fix: widgets use App Group shared UserDefaults instead of Keychain

- Widgets can't access app's Keychain (different sandbox)
- App writes data to shared UserDefaults (group.com.daniil.pulsehealth)
- Widgets read from shared UserDefaults — no API calls needed
- WidgetDataService: updates widget data + reloads timelines
- DashboardView: pushes habits/tasks data to widget after load
- HealthView: pushes health data to widget after load
- App Group capability added to both app and widget entitlements
- Widgets update every 15 minutes from cached data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 14:47:26 +03:00
parent 0c21a14cb9
commit a07696bd55
10 changed files with 165 additions and 314 deletions

View File

@@ -0,0 +1,25 @@
import Foundation
import WidgetKit
enum WidgetDataService {
static let suiteName = "group.com.daniil.pulsehealth"
static var shared: UserDefaults? {
UserDefaults(suiteName: suiteName)
}
static func updateHabits(completed: Int, total: Int, tasksCount: Int) {
shared?.set(completed, forKey: "w_habits_completed")
shared?.set(total, forKey: "w_habits_total")
shared?.set(tasksCount, forKey: "w_tasks_count")
WidgetCenter.shared.reloadTimelines(ofKind: "HabitsProgress")
}
static func updateHealth(steps: Int, sleep: Double, heartRate: Int, readiness: Int) {
shared?.set(steps, forKey: "w_steps")
shared?.set(sleep, forKey: "w_sleep")
shared?.set(heartRate, forKey: "w_heart_rate")
shared?.set(readiness, forKey: "w_readiness")
WidgetCenter.shared.reloadTimelines(ofKind: "HealthSummary")
}
}