Fix iCloud sync: chart and next check-in date stale on secondary device (build 32)

- completedMonthKeys: remove UserDefaults-based MonthlyCheckInStore check (not synced via iCloud)
- MonthlyCheckInCard.effectiveLastCheckInDate: use max() instead of ?? to prefer newer synced snapshot date
- MonthlyCheckInView.lastCompletionDate: use max() of local + latest CoreData snapshot via @FetchRequest
- FirebaseService.logPaywallShown: fix parameter key to paywall_trigger (matches GA4 custom dimension)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-05-24 08:42:22 +02:00
parent b48a47ce10
commit 0b01d6f563
5 changed files with 31 additions and 12 deletions
@@ -599,7 +599,10 @@ struct MonthlyCheckInCard: View {
@State private var cachedCompletionDate: Date?
private var effectiveLastCheckInDate: Date? {
cachedCompletionDate ?? lastUpdatedDate
// Use whichever is more recent: local completion record or latest snapshot date from CoreData.
// cachedCompletionDate lives in UserDefaults (device-local, not iCloud-synced), so on a
// secondary device after iCloud sync the snapshot date may be newer than the local record.
[cachedCompletionDate, lastUpdatedDate].compactMap { $0 }.max()
}
private var checkInProgress: Double {
@@ -1,9 +1,17 @@
import SwiftUI
import CoreData
struct MonthlyCheckInView: View {
@Environment(\.openURL) private var openURL
@EnvironmentObject var accountStore: AccountStore
@StateObject private var viewModel = MonthlyCheckInViewModel()
// Provides the latest snapshot date from CoreData (synced via iCloud) as fallback
// for lastCompletionDate when local MonthlyCheckInStore records are stale/missing.
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Snapshot.date, ascending: false)],
animation: .none
) private var latestSnapshots: FetchedResults<Snapshot>
@State private var referenceDate: Date
@State private var monthlyNote: String
@@ -24,7 +32,12 @@ struct MonthlyCheckInView: View {
}
private var lastCompletionDate: Date? {
MonthlyCheckInStore.latestCompletionDate()
// MonthlyCheckInStore lives in UserDefaults (device-local, not iCloud-synced).
// On a secondary device after iCloud sync the latest snapshot from CoreData may be
// newer than the local check-in record. Use whichever is more recent.
let localCompletion = MonthlyCheckInStore.latestCompletionDate()
let latestSnapshotDate = latestSnapshots.first?.date
return [localCompletion, latestSnapshotDate].compactMap { $0 }.max()
}
private var checkInProgress: Double {