Search code examples
swiftstorekitios14

'requestReview()' was deprecated in iOS 14.0


In iOS 14, Xcode is showing a warning:

requestReview()' was deprecated in iOS 14.0

I'm using StoreKit to ask review automatically in my app.

func requestReview() {
    guard shouldRequestReview else {return}
    SKStoreReviewController.requestReview()
    lastRequest = Date()
}

enter image description here

How to get rid of that warning?


Solution

  • iOS 16+

    There is now a new RequestReviewAction that is available as an environment value:

    private struct ContentView: View {
        @Environment(\.requestReview) private var requestReview
    
        var body: some View {
            Button("Review") {
                Task { @MainActor in
                    requestReview()
                }
            }
        }
    }
    

    iOS 14+

    Quick solution

    if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
        DispatchQueue.main.async {
            SKStoreReviewController.requestReview(in: scene)
        }
    }
    

    Note: according to some comments it's more reliable with DispatchQueue.main.async

    Convenient solution

    Here's a true one-liner:

    SKStoreReviewController.requestReviewInCurrentScene()
    

    but first you need to create the following extension in SKStoreReviewController:

    extension SKStoreReviewController {
        public static func requestReviewInCurrentScene() {
            if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
                DispatchQueue.main.async {
                    requestReview(in: scene)
                }
            }
        }
    }
    

    Here is a GitHub repository with different Swift extensions including requestReviewInCurrentScene().


    Explanation

    The requestReview function was deprecated in iOS 14:

    @available(iOS, introduced: 10.3, deprecated: 14.0)
    open class func requestReview()
    

    You need to use the requestReview(in:) function instead:

    @available(iOS 14.0, *)
    open class func requestReview(in windowScene: UIWindowScene)
    

    Possible solutions

    • Custom extension

    You can create the following extension:

    extension UIApplication {
        var currentScene: UIWindowScene? {
            connectedScenes
                .first { $0.activationState == .foregroundActive } as? UIWindowScene
        }
    }
    

    and use it like this:

    if let scene = UIApplication.shared.currentScene {
        SKStoreReviewController.requestReview(in: scene)
    }
    
    • Universal one-liner:
    if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
        SKStoreReviewController.requestReview(in: scene)
    }
    
    • single scene solution (for iOS)
    if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        SKStoreReviewController.requestReview(in: scene)
    }