Skip to content

Commit 4416085

Browse files
committed
EHR background delivery?
1 parent e0c18fc commit 4416085

File tree

7 files changed

+38
-48
lines changed

7 files changed

+38
-48
lines changed

CardinalKit-Example/CardinalKit/Library/HealthKit/CKHealthKitManager.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class CKHealthKitManager : NSObject {
3838
**************************************************************/
3939

4040
// handle authorization from the OS
41-
CKActivityManager.shared.getHealthAuthorizaton(forTypes: hkTypesToReadInBackground) { [weak self] (success, error) in
41+
CKActivityManager.shared.getHealthAuthorization(forTypes: hkTypesToReadInBackground) { [weak self] (success, error) in
4242
if (success) {
4343
let frequency = self?.config.read(query: "Background Read Frequency")
4444

CardinalKit-Example/CardinalKit/Library/HealthKit/CKHealthRecordsManager.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import Foundation
1010
import HealthKit
11+
import CardinalKit
1112
import CareKit
1213
import CareKitFHIR
1314
import CareKitStore
@@ -36,6 +37,18 @@ class CKHealthRecordsManager: NSObject {
3637

3738
func getAuth(_ completion: @escaping (_ success: Bool, _ error: Error?) -> Void) {
3839
healthStore.requestAuthorization(toShare: nil, read: Self.types) { (success, error) in
40+
if success {
41+
let frequency: HKUpdateFrequency
42+
switch CKConfig.shared.read(query: "Background Read Frequency") {
43+
case "daily": frequency = .daily
44+
case "weekly": frequency = .weekly
45+
case "hourly": frequency = .hourly
46+
default: frequency = .immediate
47+
}
48+
HealthKitManager.shared
49+
.startBackgroundDelivery(forTypes: Self.types, withFrequency: frequency)
50+
{ _, _ in }
51+
}
3952
completion(success, error)
4053
}
4154
}
@@ -71,5 +84,4 @@ class CKHealthRecordsManager: NSObject {
7184
healthStore.execute(query)
7285
}
7386
}
74-
7587
}

CardinalKit-Example/CardinalKit/Onboarding/Steps/CKHealthDataStepViewController.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class CKHealthDataStep: ORKInstructionStep {
4848
**************************************************************/
4949

5050
// handle authorization from the OS
51-
CKActivityManager.shared.getHealthAuthorizaton(forTypes: hkTypesToReadInBackground) { (success, error) in
51+
CKActivityManager.shared.getHealthAuthorization(forTypes: hkTypesToReadInBackground) { (success, error) in
5252
if (success) {
5353
let config = CKPropertyReader(file: "CKConfiguration")
5454
let frequency = config.read(query: "Background Read Frequency")

CardinalKit-Example/CardinalKit/Setup/AppDelegate+CardinalKit.swift

+7-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@ extension AppDelegate {
3232
CKStudyUser.shared.save()
3333

3434
// (4) then start the requested HK data collection (if any).
35-
let manager = CKHealthKitManager.shared
36-
manager.getHealthAuthorization { (success, error) in
35+
CKHealthKitManager.shared.getHealthAuthorization { (success, error) in
36+
if let error = error {
37+
print(error)
38+
}
39+
}
40+
41+
CKHealthRecordsManager.shared.getAuth { (success, error) in
3742
if let error = error {
3843
print(error)
3944
}

CardinalKit/Source/CKActivityManager.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ public class CKActivityManager : NSObject {
2323
return
2424
}
2525

26-
getHealthAuthorizaton(forTypes: self.typesToCollect) { [weak self] (success, error) in
26+
getHealthAuthorization(forTypes: self.typesToCollect) { [weak self] (success, error) in
2727
if (success) {
2828
self?.startHealthKitCollectionInBackground(withFrequency: .hourly) // TODO: get last freq
2929
}
3030
}
3131
}
3232

33-
public func getHealthAuthorizaton(forTypes typesToCollect:Set<HKQuantityType>, _ completion: @escaping (_ success: Bool, _ error: Error?) -> Void) {
33+
public func getHealthAuthorization(forTypes typesToCollect: Set<HKQuantityType>, _ completion: @escaping (_ success: Bool, _ error: Error?) -> Void) {
3434
self.typesToCollect = typesToCollect
3535
HealthKitManager.shared.getHealthKitAuth(forTypes: self.typesToCollect) { [weak self] (success, error) in
3636
self?.hasGrantedAuth = success

CardinalKit/Source/Components/HealthKit/HealthKitDataSync.swift

+8-8
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ class HealthKitDataSync {
1919

2020
static let shared = HealthKitDataSync()
2121
fileprivate let maxRetroactiveDays = 1 //day
22-
fileprivate var semaphoreDict = [String:NSLock]() //settled for lock since one max
22+
fileprivate var semaphoreDict = [String: NSLock]() //settled for lock since one max
2323

24-
func collectAndUploadData(forType type: HKQuantityType, onCompletion: (() -> Void)?) {
24+
func collectAndUploadData(forType type: HKSampleType, onCompletion: (() -> Void)?) {
2525

2626
let dispatchGroup = DispatchGroup()
2727
dispatchGroup.enter()
@@ -61,7 +61,7 @@ class HealthKitDataSync {
6161

6262
extension HealthKitDataSync {
6363

64-
fileprivate func collectData(forType type: HKQuantityType, _ sourceRevision: HKSourceRevision, onCompletion: @escaping (([HKSampleData])->Void)) {
64+
fileprivate func collectData(forType type: HKSampleType, _ sourceRevision: HKSourceRevision, onCompletion: @escaping (([HKSampleData])->Void)) {
6565

6666
let latestSync = getLastSyncDate(forType: type, forSource: sourceRevision)
6767

@@ -86,7 +86,7 @@ extension HealthKitDataSync {
8686

8787
}
8888

89-
fileprivate func getSources(forType type: HKQuantityType, onCompletion: @escaping ((Set<HKSource>)->Void)) {
89+
fileprivate func getSources(forType type: HKSampleType, onCompletion: @escaping ((Set<HKSource>)->Void)) {
9090

9191
// find all sources that contain requested data type
9292
//TODO testing datePredicate, only look through sources that have been active in the last five days... filters out devices that are no longer in use.
@@ -113,7 +113,7 @@ extension HealthKitDataSync {
113113

114114
extension HealthKitDataSync {
115115

116-
fileprivate func getLastSyncItem(forType type: HKQuantityType, _ sourceRevision: HKSourceRevision) -> Results<HealthKitDataUploads> {
116+
fileprivate func getLastSyncItem(forType type: HKSampleType, _ sourceRevision: HKSourceRevision) -> Results<HealthKitDataUploads> {
117117

118118
let realm = try! Realm()
119119
let syncMetadataQuery = NSCompoundPredicate(
@@ -145,7 +145,7 @@ extension HealthKitDataSync {
145145
}
146146

147147
// maybe throw a default date here?
148-
fileprivate func getLastSyncDate(forType type: HKQuantityType, forSource sourceRevision: HKSourceRevision) -> Date {
148+
fileprivate func getLastSyncDate(forType type: HKSampleType, forSource sourceRevision: HKSourceRevision) -> Date {
149149

150150
let lastSyncMetadata = getLastSyncItem(forType: type, sourceRevision)
151151
if let lastSyncItem = lastSyncMetadata.first {
@@ -156,7 +156,7 @@ extension HealthKitDataSync {
156156
return Date().dayByAdding(-maxRetroactiveDays)! // Q: what date should we put?
157157
}
158158

159-
fileprivate func setLastSyncDate(forType type: HKQuantityType, forSource sourceRevision: HKSourceRevision, date: Date) {
159+
fileprivate func setLastSyncDate(forType type: HKSampleType, forSource sourceRevision: HKSourceRevision, date: Date) {
160160

161161
let realm = try! Realm()
162162
let lastSyncMetadata = getLastSyncItem(forType: type, sourceRevision)
@@ -167,7 +167,7 @@ extension HealthKitDataSync {
167167
}
168168
}
169169

170-
fileprivate func queryHealthStore(forType type: HKQuantityType, forSource sourceRevision: HKSourceRevision, fromDate startDate: Date, queryHandler: @escaping (HKSampleQuery, [HKSample]?, Error?) -> Void) {
170+
fileprivate func queryHealthStore(forType type: HKSampleType, forSource sourceRevision: HKSourceRevision, fromDate startDate: Date, queryHandler: @escaping (HKSampleQuery, [HKSample]?, Error?) -> Void) {
171171

172172
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)
173173

CardinalKit/Source/Components/HealthKit/HealthKitManager.swift

+6-33
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
import HealthKit
1010

11-
class HealthKitManager: SyncDelegate {
11+
public class HealthKitManager: SyncDelegate {
1212

13-
static let shared = HealthKitManager()
13+
public static let shared = HealthKitManager()
1414

1515
lazy var healthStore: HKHealthStore = HKHealthStore()
1616

@@ -73,7 +73,7 @@ class HealthKitManager: SyncDelegate {
7373
}
7474
}
7575

76-
public func startBackgroundDelivery(forTypes types: Set<HKQuantityType>, withFrequency frequency: HKUpdateFrequency, _ completion: ((_ success: Bool, _ error: Error?) -> Void)? = nil) {
76+
public func startBackgroundDelivery(forTypes types: Set<HKSampleType>, withFrequency frequency: HKUpdateFrequency, _ completion: ((_ success: Bool, _ error: Error?) -> Void)? = nil) {
7777
self.setUpBackgroundDeliveryForDataTypes(types: types, frequency: frequency, completion)
7878
}
7979

@@ -90,7 +90,7 @@ class HealthKitManager: SyncDelegate {
9090

9191
extension HealthKitManager {
9292

93-
fileprivate func setUpBackgroundDeliveryForDataTypes(types: Set<HKQuantityType>, frequency: HKUpdateFrequency, _ completion: ((_ success: Bool, _ error: Error?) -> Void)? = nil) {
93+
fileprivate func setUpBackgroundDeliveryForDataTypes(types: Set<HKSampleType>, frequency: HKUpdateFrequency, _ completion: ((_ success: Bool, _ error: Error?) -> Void)? = nil) {
9494

9595
for type in types {
9696
let query = HKObserverQuery(sampleType: type, predicate: nil, updateHandler: { [weak self] (query, completionHandler, error) in
@@ -128,34 +128,7 @@ extension HealthKitManager {
128128
}
129129
}
130130

131-
//TODO: (delete) running the old data collection solution as a baseline to compare new values
132-
@available(*, deprecated)
133-
fileprivate func cumulativeBackgroundQuery(forType type: HKQuantityType, completionHandler: @escaping ()->Void) {
134-
135-
let supportedTypes = [HKQuantityTypeIdentifier.stepCount.rawValue, HKQuantityTypeIdentifier.flightsClimbed.rawValue, HKQuantityTypeIdentifier.distanceWalkingRunning.rawValue]
136-
if (!supportedTypes.contains(type.identifier)) {
137-
VLog("No cumulative query will run for type %@", type.identifier)
138-
completionHandler()
139-
return
140-
}
141-
142-
guard canQuery(forType: type) else {
143-
VLog("Cannot yet query for %@, please try again in a minute.", type.identifier)
144-
completionHandler()
145-
return
146-
}
147-
DispatchQueue.main.async { //run on main queue, which exists even if the app is 100% in the background.
148-
149-
VLog("[DEPRECATED] cumulative querying for type %@", type.identifier)
150-
HealthKitCollector.shared.collectAndSendSinceStartOfDay {
151-
VLog("[DEPRECATED] cumulative dollection done with type %@", type.identifier)
152-
completionHandler()
153-
}
154-
}
155-
156-
}
157-
158-
fileprivate func backgroundQuery(forType type: HKQuantityType, completionHandler: @escaping ()->Void) {
131+
fileprivate func backgroundQuery(forType type: HKSampleType, completionHandler: @escaping ()->Void) {
159132

160133
guard canQuery(forType: type) else {
161134
VLog("Cannot yet query for %{public}@, please try again in a minute.", type.identifier)
@@ -174,7 +147,7 @@ extension HealthKitManager {
174147

175148
}
176149

177-
fileprivate func canQuery(forType type: HKQuantityType) -> Bool {
150+
fileprivate func canQuery(forType type: HKSampleType) -> Bool {
178151
queryLogMutex.lock()
179152
defer { queryLogMutex.unlock() }
180153

0 commit comments

Comments
 (0)