在 iOS 14.0中,“ requestReview()”已被弃用

在 iOS14中,Xcode 显示了一个警告:

在 iOS14.0中不推荐使用 requestReview ()’

我正在使用 StoreKit 在我的应用程序中自动询问评论。

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

enter image description here

如何摆脱这种警告?

14987 次浏览

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") {
DispatchQueue.main.async {
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, although it should work without it as well.

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)
}

Simple solution for iOS(13 & above) and macOS

iOS (Swift 5+):

    if #available(iOS 14.0, *) {
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
}
} else if #available(iOS 10.3, *) {
SKStoreReviewController.requestReview()
}

macOS: Don't forget to replace your Apple ID with in URL "id123456789"

guard let writeReviewURL = URL(string: "https://itunes.apple.com/app/id123456789?action=write-review") else {
print("Invalid URL")
return
}
NSWorkspace.shared.open(writeReviewURL)

As SKStoreReviewController.requestReview is deprecated in ios14 You can use SKStoreReviewController.requestReview(in: scene) from ios14
Sample code is below

if #available(iOS 14.0, *) {
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
}
} else if #available(iOS 10.3, *) {
SKStoreReviewController.requestReview()
}

iOS 16 has a new way to do it: https://developer.apple.com/documentation/storekit/requestreviewaction

In my tests it is crucial to do it on the main queue. Otherwise the dialogue is unreliable.

private struct ContentView: View {


@Environment(\.requestReview) private var requestReview


var body: some View {
Button("Ask for Review") {
DispatchQueue.main.async {
requestReview()
}
}
}
}

I made a small wrapper over SKStoreReviewController that saves the headache of supporting different versions of ios. Also it works for macOS.

// Review after 3 launches
AppReview.requestIf(launches: 3)


// Review after 5 days
AppReview.requestIf(days: 5)


// Review after 3 launches and 5 days
AppReview.requestIf(launches: 3, days: 5)

https://github.com/mezhevikin/AppReview