Swift・iOS

Swiftを中心に学んだことを記録に残すブログです。技術に関係ない記事もたまに書いています。

【SwiftUI】StoreKitを使ってレビュー依頼をする

 

はじめに

StoreKitを使ってユーザーへアプリのレビュー依頼をする実装について、Appleの公式ドキュメント"Requesting App Store Reviews"(https://developer.apple.com/documentation/storekit/requesting_app_store_reviews)からダウンロードできるサンプルを元に、以下変更を加えて動作確認してみました。

  • UIKitで実装されたサンプルをSwiftUIに置き換え
  • レビュー依頼画面の表示条件を、「遷移後の画面を2回以上表示した場合」に変更
  • レビュー依頼の動作確認に影響しない画面を省略

  

サンプルイメージ

遷移後の画面を2回以上表示した場合、遷移前の画面でレビュー依頼画面が表示される。

f:id:hfoasi8fje3:20210627195324g:plain

 

開発環境

 

実装

SampleApp.swift

import SwiftUI

@main
struct SampleApp: App {
    var body: some Scene {
        WindowGroup {
           InitialView()
        }
    }
}

 

InitialView.swift

※"SKStoreReviewController.requestReview(in: windowScene)"でレビュー依頼画面を表示している。

import SwiftUI
import StoreKit

struct InitialView: View {
    
    var body: some View {
        NavigationView {
            VStack {
                Spacer()
                
                NavigationLink(destination: ProcessCompletedView()) {
                    Text("Start Process")
                        .font(.system(size: 30))
                }
                
                Spacer()
                
                if let writeReviewURL = URL(string: "https://apps.apple.com/app/idXXXXXXXXXX?action=write-review") {
                    Link("Write a Review", destination: writeReviewURL)
                        .font(.system(size: 18))
                        .padding()
                }
                
                Button("Reset Sample") {
                    UserDefaults.standard.set(0, forKey: UserDefaultsKeys.processCompletedCountKey)
                    print("Count have been reset")
                }
                .font(.system(size: 18))
                .padding([.bottom], 40)
            }
            .onAppear(perform: {
                let count = UserDefaults.standard.integer(forKey: UserDefaultsKeys.processCompletedCountKey)
                if count >= 2 {
                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
                        if let windowScene = UIApplication.shared.windows.first?.windowScene {
                            SKStoreReviewController.requestReview(in: windowScene)
                        }
                    }
                }
            })
        }
    }
}

struct InitialView_Previews: PreviewProvider {
    static var previews: some View {
        InitialView()
    }
}

 

ProcessCompletedView.swift

import SwiftUI

struct ProcessCompletedView: View {
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        VStack {
            Spacer()
            
            Text("Process Completed")
                .font(.system(size: 30))
                .padding()
            
            Button("Start Over") {
                presentationMode.wrappedValue.dismiss()
            }
            .font(.system(size: 18))
            
            Spacer()
        }
        .onAppear(perform: {
            var count = UserDefaults.standard.integer(forKey: UserDefaultsKeys.processCompletedCountKey)
            count += 1
            UserDefaults.standard.set(count, forKey: UserDefaultsKeys.processCompletedCountKey)
            print("Process completed \(count) time(s)")
        })
    }
}

struct ProcessCompletedView_Previews: PreviewProvider {
    static var previews: some View {
        ProcessCompletedView()
    }
}

 

UserDefaultsKeys.swift

class UserDefaultsKeys {
    class var processCompletedCountKey: String {
        return "processCompletedCount"
    }
}

 

おわりに

開発者ができるのはあくまでレビュー依頼をするところまでなので、レビュー依頼画面でのユーザーの行動(評価したのか、それともキャンセルしたのか)を知ることができないのは少し残念でした。ただ、簡潔にレビュー依頼の実装ができるのは便利だと思いました。

 

参考