现在有一个新的RequestReviewAction可用作环境值:
private struct ContentView: View {
@Environment(\.requestReview) private var requestReview
var body: some View {
Button("Review") {
DispatchQueue.main.async {
requestReview()
}
}
}
}
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
DispatchQueue.main.async {
SKStoreReviewController.requestReview(in: scene)
}
}
注:根据一些评论,使用DispatchQueue.main.async
更可靠
这是一个真正的一行代码:
SKStoreReviewController.requestReviewInCurrentScene()
但首先需要在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)
}
}
}
}
这里有一个GitHub代码库,其中包括不同的Swift扩展,包括requestReviewInCurrentScene()
。
requestReview
函数已在iOS 14中弃用:
@available(iOS, introduced: 10.3, deprecated: 14.0)
open class func requestReview()
你需要使用requestReview(in:)
函数代替:
@available(iOS 14.0, *)
open class func requestReview(in windowScene: UIWindowScene)
可能的解决方案
您可以创建以下扩展:
extension UIApplication {
var currentScene: UIWindowScene? {
connectedScenes
.first { $0.activationState == .foregroundActive } as? UIWindowScene
}
}
然后像这样使用它:
if let scene = UIApplication.shared.currentScene {
SKStoreReviewController.requestReview(in: scene)
}
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
}
if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
}
iOS(13及以上)和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:不要忘记将您的苹果ID替换为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)
我写了一个小封装,用于简化对不同版本iOS的支持,并可用于macOS。这个封装基于SKStoreReviewController。
// 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)
iOS 16有了一种新的方法:https://developer.apple.com/documentation/storekit/requestreviewaction
在我的测试中,关键是要在主队列上执行。否则对话框不可靠。
private struct ContentView: View {
@Environment(\.requestReview) private var requestReview
var body: some View {
Button("Ask for Review") {
DispatchQueue.main.async {
requestReview()
}
}
}
}
由于在iOS14中,SKStoreReviewController.requestReview
已被弃用,您可以使用SKStoreReviewController.requestReview(in: scene)
以下是示例代码
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()
}
SKStoreReviewController.requestReview()
方法,没有其他逻辑,也不记录任何日期。在调用SKStoreReviewController.requestReview()
方法之前,您介意分享一下您的逻辑吗? - fs_tigre