WatchHealthWidgetRefreshCoordinator.swift
3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import Foundation
import HealthKit
/// Bridges HealthKit observer events to the three HealthKit-backed widgets.
/// This path is intentionally independent of login state and server uploads.
@MainActor
final class WatchHealthWidgetRefreshCoordinator {
static let shared = WatchHealthWidgetRefreshCoordinator()
private let healthStore = HKHealthStore()
private let defaultStepGoal = 10_000
private init() {}
func refresh(for dataType: HealthDataType) {
switch dataType {
case .heartRate:
WatchDataManager.share.refreshHeartRateWidgetData()
WatchDataManager.share.getMyLatestData()
case .steps:
WatchDataManager.share.refreshStepWidgetData()
refreshLocalActivityTarget()
case .move, .exercise, .stand:
WatchDataManager.share.refreshActivityWidgetData()
refreshLocalActivityTarget()
default:
break
}
}
func refreshAll() {
WatchDataManager.share.getMyLatestData()
WatchDataManager.share.refreshHeartRateWidgetData()
WatchDataManager.share.refreshStepWidgetData()
WatchDataManager.share.refreshActivityWidgetData()
refreshLocalActivityTarget()
}
func refreshActivityTargetData() {
refreshLocalActivityTarget()
}
private func refreshLocalActivityTarget() {
let defaultStepGoal = defaultStepGoal
let calendar = Calendar.current
var start = calendar.dateComponents([.era, .year, .month, .day], from: Date())
var end = start
start.calendar = calendar
end.calendar = calendar
let predicate = HKQuery.predicate(forActivitySummariesBetweenStart: start, end: end)
let query = HKActivitySummaryQuery(predicate: predicate) { _, summaries, error in
guard error == nil else { return }
guard let summary = summaries?.last else {
AppGroupConstants.defaults?.removeObject(
forKey: AppGroupConstants.Key.localHealthActivityTarget
)
WatchWidgetReloader.reloadActivityTarget()
return
}
let target = ActivityTarget(
id: nil,
create_time: nil,
update_time: nil,
user_id: nil,
move: Int(summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie())),
step: defaultStepGoal,
stand: Int(summary.appleStandHoursGoal.doubleValue(for: .count())),
exercise: Int(summary.appleExerciseTimeGoal.doubleValue(for: .minute())),
activity_move_mode: summary.activityMoveMode.rawValue,
active_energy_burned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()),
active_energy_burned_goal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()),
apple_move_time: summary.appleMoveTime.doubleValue(for: .minute()),
apple_move_time_goal: summary.appleMoveTimeGoal.doubleValue(for: .minute()),
apple_exercise_time: summary.appleExerciseTime.doubleValue(for: .minute()),
exercise_time_goal: summary.exerciseTimeGoal?.doubleValue(for: .minute()),
apple_stand_hours: summary.appleStandHours.doubleValue(for: .count()),
stand_hours_goal: summary.standHoursGoal?.doubleValue(for: .count())
)
guard let data = try? JSONEncoder().encode(target) else { return }
AppGroupConstants.defaults?.set(data, forKey: AppGroupConstants.Key.localHealthActivityTarget)
WatchWidgetReloader.reloadActivityTarget()
}
healthStore.execute(query)
}
}