-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHealthKitDeployment.swift
93 lines (71 loc) · 3.53 KB
/
HealthKitDeployment.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
/*
Abstract:
A collection of HealthKit properties, functions, and utilities.
*/
import Foundation
import HealthKit
class HealthData {
static let healthStore: HKHealthStore = HKHealthStore()
// MARK: - HKHealthStore
class func saveHealthData(_ data: [HKObject], completion: @escaping (_ success: Bool, _ error: Error?) -> Void) {
healthStore.save(data, withCompletion: completion)
}
// MARK: - HKStatisticsCollectionQuery
class func fetchStatistics(with identifier: HKQuantityTypeIdentifier,
predicate: NSPredicate? = nil,
options: HKStatisticsOptions,
startDate: Date,
endDate: Date = Date(),
interval: DateComponents,
completion: @escaping (HKStatisticsCollection) -> Void) {
guard let quantityType = HKObjectType.quantityType(forIdentifier: identifier) else {
fatalError("*** Unable to create a step count type ***")
}
let anchorDate = createAnchorDate()
// Create the query
let query = HKStatisticsCollectionQuery(quantityType: quantityType,
quantitySamplePredicate: predicate,
options: options,
anchorDate: anchorDate,
intervalComponents: interval)
// Set the results handler
query.initialResultsHandler = { query, results, error in
if let statsCollection = results {
completion(statsCollection)
}
}
healthStore.execute(query)
}
// MARK: - Helper Functions
class func updateAnchor(_ newAnchor: HKQueryAnchor?, from query: HKAnchoredObjectQuery) {
if let sampleType = query.objectType as? HKSampleType {
setAnchor(newAnchor, for: sampleType)
} else {
if let identifier = query.objectType?.identifier {
print("anchoredObjectQueryDidUpdate error: Did not save anchor for \(identifier) – Not an HKSampleType.")
} else {
print("anchoredObjectQueryDidUpdate error: query doesn't not have non-nil objectType.")
}
}
}
private static let userDefaults = UserDefaults.standard
private static let anchorKeyPrefix = "Anchor_"
private class func anchorKey(for type: HKSampleType) -> String {
return anchorKeyPrefix + type.identifier
}
/// Returns the saved anchor used in a long-running anchored object query for a particular sample type.
/// Returns nil if a query has never been run.
class func getAnchor(for type: HKSampleType) -> HKQueryAnchor? {
if let anchorData = userDefaults.object(forKey: anchorKey(for: type)) as? Data {
return try? NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: anchorData)
}
return nil
}
/// Update the saved anchor used in a long-running anchored object query for a particular sample type.
private class func setAnchor(_ queryAnchor: HKQueryAnchor?, for type: HKSampleType) {
if let queryAnchor = queryAnchor,
let data = try? NSKeyedArchiver.archivedData(withRootObject: queryAnchor, requiringSecureCoding: true) {
userDefaults.set(data, forKey: anchorKey(for: type))
}
}
}