I have the following code to show a ratings prompt when the user comes back to the app a second time and hasn't seen the prompt. It asks the user to rate my app in the app store. I'm on the latest version of iOS.
When I call RatingPrompt.trackVisitAndShowPromptIfNeeded()
, even though the conditions are met (the user hasn't seen the prompt and it's been more than 1 day since they first visited the app), the prompt doesn't show.
What am I doing wrong?
import StoreKit
import UIKit
struct RatingPrompt {
private static let firstVisitKey = "firstVisitDate"
private static let hasShownPromptKey = "hasShownRatingPrompt"
private static let hasShownAfterFirstSummaryKey = "hasShownAfterFirstSummary"
/// Call when user opens the app / visits a main screen
static func trackVisitAndShowPromptIfNeeded() {
let defaults = UserDefaults.standard
let now = Date()
// Save first visit date
if defaults.object(forKey: firstVisitKey) == nil {
defaults.set(now, forKey: firstVisitKey)
return
}
// If already shown via visit or summary, do nothing
if defaults.bool(forKey: hasShownPromptKey) {
return
}
// Check if at least 1 day passed
if let firstVisit = defaults.object(forKey: firstVisitKey) as? Date {
let oneDay: TimeInterval = 60 * 60 * 24
if now.timeIntervalSince(firstVisit) >= oneDay {
requestReview()
defaults.set(true, forKey: hasShownPromptKey)
}
}
}
/// Call when user reads their first book summary
static func trackFirstSummaryRead() {
let defaults = UserDefaults.standard
// If already shown, do nothing
if defaults.bool(forKey: hasShownPromptKey) || defaults.bool(forKey: hasShownAfterFirstSummaryKey) {
return
}
// Show immediately on first summary read
requestReview()
defaults.set(true, forKey: hasShownAfterFirstSummaryKey)
defaults.set(true, forKey: hasShownPromptKey) // ensure it won't show again
}
/// Internal helper to request review
private static func requestReview() {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first {
SKStoreReviewController.requestReview(in: window.windowScene!)
}
}
}
To review the app manually you should use your app’s URL. The built in controllers are subject to Apple deciding if it’s ok
// Replace the YOURAPPSTOREID value below with the App Store ID for your app.
// You can find the App Store ID in your app's product URL.
let url = "https://apps.apple.com/app/idYOURAPPSTOREID?action=write-review"
guard let writeReviewURL = URL(string: url) else {
fatalError("Expected a valid URL")
}
openURL(writeReviewURL)