【SwiftUI】@AppStorage変数に起動回数を保存して、しきい値を満たしていればアプリのレビューを促す

2022.03.17

SwiftUIでユーザーにアプリのレビューを促す為のrequestReview(in:)を使用するに伴って調べてみました。その際にiOS 14から使用できる@AppStorageというプロパティラッパーがあったので合わせて使用してみました。

環境

  • Xcode 13.2.1

requestReview(in:)とは

簡単にいうと、アプリの評価をユーザーに行っていただく為のリクエストを表示させることが出来ます。

以前、requestReviewについての記事は書いたので詳細は割愛させていただきます。ご興味のある方は下記を見ていただければと思います。

【Swift】requestReview()がiOS14.0から非推奨だったので対応した

使い方

まずはStoreKitをインポートします。

import StoreKit

あとは、onAppear等のレビューリクエストを行いたい場所でSKStoreReviewController.requestReview(in:)を呼ぶだけです。

.onAppear {
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        SKStoreReviewController.requestReview(in: scene)
    }
}

しかし、このままだとonAppearされる度にレビューリクエストは発生してしまいます。

この状態だと、Human Interface Guidelines - Ratings and Reviewsで考慮すべき点として挙げてある以下の点が考慮出来ないと思います。

  • ユーザーがアプリへのエンゲージメントを示した後でのみ、評価を求めてください。
  • 最初の立ち上げ時またはオンボーディング中に評価を求めないでください。意見を述べるのに十分な時間をとってください。
  • 迷惑な存在にならないでください。繰り返しの評価プロンプトはイライラする可能性があり、アプリに対するユーザーの意見に悪影響を与える可能性さえあります。
  • 評価リクエストの間に少なくとも1〜2週間かかり、ユーザーがアプリとの追加のエンゲージメントを示した後にのみ再度プロンプトを表示します。

こちらを考慮するために、@AppStorageプロパティに起動回数を保存しつつ、しきい値と比較してレビューリクエストを行うかどうかを判定したいと思います。

@AppStorage

UserDefaultsの値の変更を@StateのようにViewに反映することの出来るプロパティラッパーです。 iOS 14から使用できるプロパティラッパーですが、UserDefaultsへの値の保存が簡単にできるようになりました。

@AppStorage("launchedCount") var launchedCount = 0
  • @AppStorage("launchedCount")では、UserDefaultskeyの値を設定しています。
  • var launchedCount = 0ではUserDefaultsの初期値を設定しています。

こちらのデータの保存先はUserDefaultsになるので、UserDefaultsで同じkeyを使用することでも取得出来ます。

UserDefaults.standard.integer(forKey: "launchedCount")

起動回数としきい値を比較しながらレビューリクエストを行うか判定する

今回は1日1度は必ず開くアプリという仮定で進めていきます。

こちらは起動すると褒めてくれるアプリです

ContentView

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("あなたは、えらい")
            .fontWeight(.black)
            .padding()
    }
}

レビューリクエスト用のクラスを作成する

import SwiftUI
import StoreKit

class AppStoreReview {

    /// 起動回数のUserDefaults
    @AppStorage("launchedCount") static var launchedCount = 0

    /// しきい値
    static let threshold = 14

    /// 条件を満たしていれば、レビューリクエストを行う
    static func requestIfNeeded() {

        launchedCount += 1

        if launchedCount % threshold == 0 {
            if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
                SKStoreReviewController.requestReview(in: scene)
            }
        }
    }
}
  • launchedCount
    • 何回起動したかを保持している@AppStorageプロパティ
  • threshold
    • しきい値、1日1回使用すると仮定して、14回(2週間)に設定
  • requestIfNeeded()
    • 起動回数をしきい値で割り切れるならレビューリクエストを出す

使用例

onAppear時にレビューリクエスト対象ならレビューを促しています。

ContentView()
    .onAppear {
        AppStoreReview.requestIfNeeded()
    }

おわりに

レビューリクエストを出す時のガイドラインを改めて学びました。今回は例として14回というしきい値を設けましたが、プロジェクトによっては各バージョンで1回までと指定したり、それぞれに適した値を設けると良さそうです。

また、今回は考慮していませんが、HIGに記載されていたその他の考慮ポイント

  • 最初の立ち上げ時またはオンボーディング中に評価を求めないでください
  • ユーザーの邪魔をしないでください
  • 評価リクエストが最も理にかなっている論理的な一時停止または停止ポイントを見つけてください

こちらも考慮する必要がありそうなのでより良いポイントを見極めていきたいと思います。

そして、レビューリクエストは365日以内に3回までという制限があるので、大事にしていきたいですね。

参考