LoginSignup
0
2

More than 3 years have passed since last update.

SwiftUIでレビュー依頼ダイアログを出す

Posted at

はじめに

アプリのレビューはSKStoreReviewControllerを使うと、OSの体裁に沿ったレビュー依頼ダイアログを表示してくれます。
そもそもアプリのレビュー依頼はこの方法以外でやってはいけないようです。

実際表示されるのはこんな感じのダイアログです。

Simulator Screen Shot - iPhone 8 - 2020-10-12 at 22.58.36.png

どうやってSwiftUIで使うの?

Controllerという名前の通り、UIKitのクラスなのでUIViewControllerRepresentableでラップしてやる必要があります。
ほぼ公式サンプルの丸パクリですが、私はStoreReviewViewという名前のクラスでラップして使っています。

import Foundation
import UIKit
import SwiftUI
import StoreKit

struct StoreReviewView: UIViewControllerRepresentable {
    typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void


    func makeUIViewController(context: UIViewControllerRepresentableContext<StoreReviewView>) -> UIViewController {
        let controller = UIViewController()

        return controller
    }

    func checkAndShowReview() {
        // If the count has not yet been stored, this will return 0
        var count = UserDefaults.standard.integer(forKey: UserDefaults.processCompletedCountKey)
        count += 1
        UserDefaults.standard.set(count, forKey: UserDefaults.processCompletedCountKey)

        // Get the current bundle version for the app
        let infoDictionaryKey = kCFBundleVersionKey as String
        guard let currentVersion = Bundle.main.object(forInfoDictionaryKey: infoDictionaryKey) as? String
            else { fatalError("Expected to find a bundle version in the info dictionary") }

        let lastVersionPromptedForReview = UserDefaults.standard.string(forKey: UserDefaults.lastVersionPromptedForReviewKey)

        // Has the process been completed several times and the user has not already been prompted for this version?
        if count >= 4 && currentVersion != lastVersionPromptedForReview {
            let twoSecondsFromNow = DispatchTime.now() + 2.0
            DispatchQueue.main.asyncAfter(deadline: twoSecondsFromNow) {
                SKStoreReviewController.requestReview()
                UserDefaults.standard.set(currentVersion, forKey: UserDefaults.lastVersionPromptedForReviewKey)
            }
        }
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<StoreReviewView>) {
    }
}

extension UserDefaults {
    class var processCompletedCountKey: String {
        return "processCompletedCount"
    }

    class var lastVersionPromptedForReviewKey: String {
        return "lastVersionPromptedForReview"
    }
}

呼び出し方

ダイアログを表示したいViewのonAppearでcheckAndShowReview()を呼びます。
本当はUIKitで言うviewDidLoad()のタイミングで処理を行いたいところですが、SwiftUIなのでそれはできません。
苦肉の策ですが、onApperでPIDチェックを行うことで表示される度にカウントが増えることを防止します。

import SwiftUI

struct MainView: View {
    @State private var pid : Int32 = 0

    var body: some View {
        VStack {
            Text("Hello")
        }.onAppear() {
            if(pid != ProcessInfo.processInfo.processIdentifier) {
                StoreReviewView().checkAndShowReview()
                pid = ProcessInfo.processInfo.processIdentifier
            }
        }
    }
}

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        MainView()
    }
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2