Tune app review prompt cadence
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
import StoreKit
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class ReviewPromptService {
|
||||||
|
static let shared = ReviewPromptService()
|
||||||
|
|
||||||
|
private let lastPromptKey = "reviewPromptLastDate"
|
||||||
|
private let checkInCountKey = "reviewPromptCheckinCount"
|
||||||
|
private let minCheckInsBetweenPrompts = 3
|
||||||
|
private let minDaysBetweenPrompts = 90
|
||||||
|
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
func recordMonthlyCheckInCompleted() {
|
||||||
|
let currentCount = UserDefaults.standard.integer(forKey: checkInCountKey)
|
||||||
|
UserDefaults.standard.set(currentCount + 1, forKey: checkInCountKey)
|
||||||
|
requestReviewIfEligible()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func requestReviewIfEligible() {
|
||||||
|
let now = Date()
|
||||||
|
if let lastPrompt = UserDefaults.standard.object(forKey: lastPromptKey) as? Date {
|
||||||
|
let daysSince = now.timeIntervalSince(lastPrompt) / 86_400
|
||||||
|
if daysSince < Double(minDaysBetweenPrompts) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = UserDefaults.standard.integer(forKey: checkInCountKey)
|
||||||
|
guard count >= minCheckInsBetweenPrompts else { return }
|
||||||
|
|
||||||
|
requestReview()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func requestReview() {
|
||||||
|
guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
|
||||||
|
if #available(iOS 18.0, *) {
|
||||||
|
AppStore.requestReview(in: scene)
|
||||||
|
} else {
|
||||||
|
SKStoreReviewController.requestReview(in: scene)
|
||||||
|
}
|
||||||
|
UserDefaults.standard.set(Date(), forKey: lastPromptKey)
|
||||||
|
UserDefaults.standard.set(0, forKey: checkInCountKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,6 +167,7 @@ struct MonthlyCheckInView: View {
|
|||||||
? now
|
? now
|
||||||
: min(referenceDate.endOfMonth, now)
|
: min(referenceDate.endOfMonth, now)
|
||||||
MonthlyCheckInStore.setCompletionDate(completionDate, for: referenceDate)
|
MonthlyCheckInStore.setCompletionDate(completionDate, for: referenceDate)
|
||||||
|
ReviewPromptService.shared.recordMonthlyCheckInCompleted()
|
||||||
viewModel.refresh()
|
viewModel.refresh()
|
||||||
} label: {
|
} label: {
|
||||||
Text("Mark Check-in Complete")
|
Text("Mark Check-in Complete")
|
||||||
|
|||||||
Reference in New Issue
Block a user