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

91
在iOS 14中,Xcode显示一个警告:

requestReview() 在iOS 14.0中已经弃用

我在我的应用程序中使用StoreKit自动请求评论。
func requestReview() {
    guard shouldRequestReview else {return}
    SKStoreReviewController.requestReview()
    lastRequest = Date()
}

在此输入图片描述

如何消除此警告?


@ Dc7 - 在您的代码中,看起来您正在记录上次显示请求审查的日期,您介意分享一下您的逻辑吗?我在AppStore上有一个应用程序,一些用户报告说他们不断收到RateApp请求,我想知道我是否做错了什么。在10次启动后,我要求用户对应用进行评分,但我只调用SKStoreReviewController.requestReview()方法,没有其他逻辑,也不记录任何日期。在调用SKStoreReviewController.requestReview()方法之前,您介意分享一下您的逻辑吗? - fs_tigre
5个回答

190

iOS 16+

现在有一个新的RequestReviewAction可用作环境值:

private struct ContentView: View {
    @Environment(\.requestReview) private var requestReview

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

iOS 14+

快速解决方案

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)
}
  • 通用 one-liner:
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
    SKStoreReviewController.requestReview(in: scene)
}
  • iOS的{{单场景}}解决方案
if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
    SKStoreReviewController.requestReview(in: scene)
}

1
在我的看法中,这不是iPad上的理想解决方案。当您打开多个WindowScenes时,即使窗口在后台,审核弹出窗口也会显示在“first”connectedScene中。 - toshi0383
4
@toshi0383,是的,你说得对。在回答时我只考虑了iOS。请查看更新后适用于多个场景的答案。 - pawello2222
@pawello2222,你知道这个问题的答案吗?https://stackoverflow.com/questions/69272521/requestreview-doesnt-work-if-i-open-my-app-manually - RRN
macOS的等效解决方案是什么?旧函数的好处在于它不受操作系统限制。 - TheNeil
1
我会在 requestReviewInCurrentScene() 的主体中添加 DispatchQueue.main.async { }。 - Jean Raymond Daher

60

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)

macOS的等效解决方案是什么?旧函数的好处在于它不受操作系统限制。 - TheNeil

3

我写了一个小封装,用于简化对不同版本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)

https://github.com/mezhevikin/AppReview


0

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

-8

由于在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()
}

2
这个答案与上一个相同(格式也一样糟糕)。 - inexcitus
inexcitus 请纠正格式。 - Jagveer Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接