LoginSignup
7
4

More than 1 year has passed since last update.

iOS16時代のStoreKit使用法 (SwiftUI)

Last updated at Posted at 2022-11-02

はじめに

SwiftUIで作成したアプリで、
ユーザーに評価やレビューを依頼するViewを表示しようと思ったのですが、
iOSのバージョンによって使い方がコロコロ変わっているのでまとめてみました。
(iPadOS, macOS, Mac Catalystでも事情は同じですが省略します)

APIの変遷

  • iOS 13.0 - (14.0でdeprecated)
SKStoreReviewController.requestReview()
  • iOS 14.0 - (deprecatedではない)
// 事前にUIWindowSceneを取得する必要がある。
SKStoreReviewController.requestReview(in: windowScene)
  • iOS 16.0 以降
@Environment(\.requestReview) var requestReview
requestReview()

UIWindowSceneを取得しなくても良くなった:clap::smiley: (面倒くさかった)

コード

EnvironmentValuesをカスタマイズする方法

iOS13 - 16まで可能な限りコードを共通化する。

iOS15_requestReviewEnvironmentValuesに追加、

  • iOS 16以降: RequestReviewActionを返す。
  • それ以外: iOS15_RequestReviewActionを返す。

iOS15_RequestReviewActioncallAsFunction()で各OS用のrequestReview()を呼ぶ。

※ iOS 15のサポートを終了したらiOS15_...を削除して、下記カスタマイズを使用しない方法のコードに変更する。

import SwiftUI
import StoreKit

struct ContentView: View {

    @Environment(\.iOS15_requestReview) var requestReview
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .onAppear {
            AppStore.perform(requestReview)
        }
    }
}

struct AppStore {
    @MainActor
    static func perform(_ action: Any) {
        if #available(iOS 16.0, *) {
            // iOS 16 -
            (action as? RequestReviewAction)?()
        } else {
            // iOS 13 - 15
            (action as? iOS15_RequestReviewAction)?()
        }
    }
}

@available(iOS, introduced: 13.0, obsoleted: 16.0, message: "Use RequestReviewAction instead")
@MainActor
struct iOS15_RequestReviewAction: EnvironmentKey, Sendable {
    static let defaultValue = Self()

    func callAsFunction() {
        if #available(iOS 14.0, *) {
            if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
                SKStoreReviewController.requestReview(in: scene)
            }
        } else {
            SKStoreReviewController.requestReview()
        }
    }
}

@available(iOS, introduced: 13.0, obsoleted: 16.0, message: "Use requestReview instead")
extension EnvironmentValues {
    @MainActor
    var iOS15_requestReview: Any {
        get {
            if #available(iOS 16.0, *) {
                return requestReview
            } else {
                return self[iOS15_RequestReviewAction.self]
            }
        }
    }
}

カスタマイズを使用しない方法

Minimum Deployments が iOS 16.0 以降

import SwiftUI
import StoreKit

struct ContentView: View {

    @Environment(\.requestReview) var requestReview

    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .onAppear {
            requestReview()
        }
    }
}

Minimum Deployments が iOS 13.0 - 15.x

import SwiftUI
import StoreKit

struct ContentView: View {

    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .onAppear {
            if #available(iOS 14.0, *) {
                if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
                    SKStoreReviewController.requestReview(in: scene)
                }
            } else {
                SKStoreReviewController.requestReview()
            }
        }
    }
}

他に良い方法があったらご教授ください。:bow:

ご注意

  • requestReviewを呼び出すタイミングは真面目に考慮していません。
  • UIWindowSceneの取得方法も真面目に考慮していません。

開発環境

  • Xcode 14.1

参考

Ratings and reviews (Human Interface Guideline)
評価、レビュー、返答
SKStoreReviewController requestReview()
SKStoreReviewController requestReview(in:)
RequestReviewAction

7
4
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
7
4