1.1.0 feature work: Monthly Check-in, Charts, Goals, Share, Reviews
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,8 @@ final class ReviewPromptService {
|
||||
|
||||
private let lastPromptKey = "reviewPromptLastDate"
|
||||
private let checkInCountKey = "reviewPromptCheckinCount"
|
||||
private let hasCompletedStoreReviewKey = "reviewPromptHasCompletedStoreReview"
|
||||
private let promptedAchievementKeysKey = "reviewPromptedAchievementKeys"
|
||||
private let minCheckInsBetweenPrompts = 3
|
||||
private let minDaysBetweenPrompts = 90
|
||||
private let userDefaults: UserDefaults
|
||||
@@ -34,7 +36,40 @@ final class ReviewPromptService {
|
||||
requestReviewIfEligible()
|
||||
}
|
||||
|
||||
func shouldAskForAchievementSatisfaction(newlyUnlockedAchievementKeys: Set<String>) -> Bool {
|
||||
guard !newlyUnlockedAchievementKeys.isEmpty else { return false }
|
||||
guard !hasCompletedStoreReview else { return false }
|
||||
|
||||
let promptedKeys = Set(userDefaults.stringArray(forKey: promptedAchievementKeysKey) ?? [])
|
||||
let unpromptedKeys = newlyUnlockedAchievementKeys.subtracting(promptedKeys)
|
||||
guard !unpromptedKeys.isEmpty else { return false }
|
||||
|
||||
let mergedKeys = promptedKeys.union(unpromptedKeys).sorted()
|
||||
userDefaults.set(mergedKeys, forKey: promptedAchievementKeysKey)
|
||||
return true
|
||||
}
|
||||
|
||||
var hasCompletedStoreReview: Bool {
|
||||
userDefaults.bool(forKey: hasCompletedStoreReviewKey)
|
||||
}
|
||||
|
||||
func markStoreReviewCompleted() {
|
||||
userDefaults.set(true, forKey: hasCompletedStoreReviewKey)
|
||||
}
|
||||
|
||||
static func appStoreWriteReviewURL() -> URL {
|
||||
guard var components = URLComponents(url: GoalShareService.appStoreURL, resolvingAgainstBaseURL: false) else {
|
||||
return GoalShareService.appStoreURL
|
||||
}
|
||||
var queryItems = components.queryItems ?? []
|
||||
queryItems.removeAll { $0.name == "action" }
|
||||
queryItems.append(URLQueryItem(name: "action", value: "write-review"))
|
||||
components.queryItems = queryItems
|
||||
return components.url ?? GoalShareService.appStoreURL
|
||||
}
|
||||
|
||||
private func requestReviewIfEligible() {
|
||||
guard !hasCompletedStoreReview else { return }
|
||||
let now = dateProvider()
|
||||
if let lastPrompt = userDefaults.object(forKey: lastPromptKey) as? Date {
|
||||
let daysSince = now.timeIntervalSince(lastPrompt) / 86_400
|
||||
|
||||
Reference in New Issue
Block a user