You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用requestReview()请求应用评分

App Store Review Request Questions & Code Feedback

Hey there! Let's tackle your two key questions about App Store review prompts first, then dive into some tweaks for your code.

Question 1: Can I re-request a review if the user declined initially?

Absolutely! Here's the thing: Apple's SKStoreReviewController.requestReview() handles the heavy lifting of deciding when to actually show the prompt to the user. If a user taps "Later" or "No, Thanks", the system will automatically suppress any future prompts from your app for a period of time (usually weeks, depending on Apple's current rules).

You can keep triggering your own logic (like counting 3 more completed action sequences) and calling requestReview() when your conditions are met—just let Apple's system handle whether the prompt actually appears. You won't accidentally spam the user, since the system blocks repeated prompts after a decline.

Question 2: Can I call the review request from multiple app nodes, letting Apple control frequency?

This is not just allowed—it's actually a recommended practice! Since you can't guarantee users will hit your single pre-planned trigger point, adding the request call at multiple natural, positive interaction moments (like finishing a task, unlocking a feature, or completing a successful session) increases the chance that a user who's having a good experience will see the prompt.

Apple's system enforces a strict limit of 3 review prompts per user per 12-month period across all versions of your app. No matter how many times you call requestReview(), the system will only show the prompt if it's within that limit and the user hasn't declined recently. So feel free to add the call wherever it makes sense in your user flow—Apple will filter out any excess requests automatically.


Feedback on Your AppReviewRequest Code

First off, using @AppStorage to persist your run count and last version is a smart, clean approach. That said, there are a few small bugs and improvements to make:

Original Code

enum AppReviewRequest {
    @AppStorage("runCountSinceLastRequest") static var runCountSinceLastRequest = 0
    @AppStorage("lastVersion") static var lastVersion = ""
    static let threshold = 4
    static let currentVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
    static func countUpRequestReview() {
        if currentVersion != lastVersion {
            if runCountSinceLastRequest < threshold - 1 {
                runCountSinceLastRequest += 1
                print(runCountSinceLastRequest)
            }
        }
    }
    static func requestReviewIfNeeded() {
        if currentVersion != lastVersion {
            if runCountSinceLastRequest == threshold {
                if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
                    SKStoreReviewController.requestReview(in: scene)
                    lastVersion = currentVersion
                    runCountSinceLastRequest = 0
                }
            }
        }
    }
}

Key Fixes & Improvements

  1. Fix the Counting Logic Bug
    Right now, your countUpRequestReview() stops incrementing when runCountSinceLastRequest hits threshold - 1 (3, when threshold is 4). But requestReviewIfNeeded() only triggers when the count equals threshold (4)—so the prompt will never show up! Adjust the counting logic to increment until the threshold is reached:

    static func countUpRequestReview() {
        if currentVersion != lastVersion {
            runCountSinceLastRequest += 1
            print(runCountSinceLastRequest)
        }
    }
    

    Then update the trigger condition in requestReviewIfNeeded() to check if the count meets or exceeds the threshold:

    if runCountSinceLastRequest >= threshold {
        // Trigger review request
    }
    
  2. Avoid Force Unwrapping
    The line Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String uses force unwrapping, which could crash if the key is missing (unlikely, but better safe than sorry). Replace it with a safe optional binding:

    static let currentVersion: String = {
        guard let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String else {
            return "unknown"
        }
        return version
    }()
    
  3. Tweak Version Reset Logic
    Your current logic resets the count and version only when the prompt is shown. That's fine, but if you want to ensure you don't count interactions from a previous version, you could reset the count immediately when a new version is detected (in countUpRequestReview()), but that's optional depending on your desired behavior.

  4. Trigger on Valuable Actions
    Instead of calling countUpRequestReview() on app launch, consider calling it only when the user completes your target action sequence. This ensures you're asking for a review after the user has a positive, intentional experience—boosting the chance they'll leave a rating.


内容的提问来源于stack exchange,提问作者Tom_Swift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:42:46