-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathDataManager.swift
129 lines (107 loc) · 4.25 KB
/
DataManager.swift
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//
// DataManager.swift
// Learn
//
// Copyright © 2019 LoopKit Authors. All rights reserved.
//
import Foundation
import HealthKit
import LoopKit
import LoopCore
final class DataManager {
let carbStore: CarbStore
let doseStore: DoseStore
let glucoseStore: GlucoseStore
let settings: LoopSettings
init(
basalRateSchedule: BasalRateSchedule? = UserDefaults.appGroup?.legacyBasalRateSchedule,
carbRatioSchedule: CarbRatioSchedule? = UserDefaults.appGroup?.legacyCarbRatioSchedule,
defaultRapidActingModel: ExponentialInsulinModelPreset? = UserDefaults.appGroup?.legacyDefaultRapidActingModel,
insulinSensitivitySchedule: InsulinSensitivitySchedule? = UserDefaults.appGroup?.legacyInsulinSensitivitySchedule,
settings: LoopSettings = UserDefaults.appGroup?.legacyLoopSettings ?? LoopSettings()
) {
self.settings = settings
let healthStore = HKHealthStore()
let cacheStore = PersistenceController.controllerInAppGroupDirectory(isReadOnly: true)
carbStore = CarbStore(
healthStore: healthStore,
cacheStore: cacheStore,
cacheLength: .hours(24),
defaultAbsorptionTimes: (fast: .minutes(30), medium: .hours(3), slow: .hours(5)),
observationInterval: 0,
carbRatioSchedule: carbRatioSchedule,
insulinSensitivitySchedule: insulinSensitivitySchedule,
provenanceIdentifier: HKSource.default().bundleIdentifier
)
doseStore = DoseStore(
healthStore: healthStore,
cacheStore: cacheStore,
observationEnabled: false,
longestEffectDuration: ExponentialInsulinModelPreset.rapidActingAdult.effectDuration,
basalProfile: basalRateSchedule,
insulinSensitivitySchedule: insulinSensitivitySchedule,
provenanceIdentifier: HKSource.default().bundleIdentifier
)
glucoseStore = GlucoseStore(
healthStore: healthStore,
cacheStore: cacheStore,
observationEnabled: false,
provenanceIdentifier: HKSource.default().bundleIdentifier
)
}
}
// MARK: - Thread-safe Preferences
extension DataManager {
/// The daily schedule of basal insulin rates
var basalRateSchedule: BasalRateSchedule? {
return doseStore.basalProfile
}
/// The daily schedule of carbs-to-insulin ratios
/// This is measured in grams/Unit
var carbRatioSchedule: CarbRatioSchedule? {
return carbStore.carbRatioSchedule
}
/// The daily schedule of insulin sensitivity (also known as ISF)
/// This is measured in <blood glucose>/Unit
var insulinSensitivitySchedule: InsulinSensitivitySchedule? {
return carbStore.insulinSensitivitySchedule
}
}
// MARK: - HealthKit Setup
extension DataManager {
var healthStore: HKHealthStore {
return carbStore.healthStore
}
/// All the HealthKit types to be read and shared by stores
private var sampleTypes: Set<HKSampleType> {
return Set([
glucoseStore.sampleType,
carbStore.sampleType,
doseStore.sampleType,
].compactMap { $0 })
}
/// True if any stores require HealthKit authorization
var authorizationRequired: Bool {
return glucoseStore.authorizationRequired ||
carbStore.authorizationRequired ||
doseStore.authorizationRequired
}
/// True if the user has explicitly denied access to any stores' HealthKit types
private var sharingDenied: Bool {
return glucoseStore.sharingDenied ||
carbStore.sharingDenied ||
doseStore.sharingDenied
}
func authorize(_ completion: @escaping () -> Void) {
// Authorize all types at once for simplicity
carbStore.healthStore.requestAuthorization(toShare: [], read: sampleTypes) { (success, error) in
if success {
// Call the individual authorization methods to trigger query creation
self.carbStore.authorize(toShare: false, { _ in })
self.doseStore.insulinDeliveryStore.authorize(toShare: false, { _ in })
self.glucoseStore.authorize(toShare: false, { _ in })
}
completion()
}
}
}