@kingstinct/react-native-healthkit 9.0.5 → 9.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/CharacteristicTypeModule.swift +36 -21
- package/ios/CoreModule.swift +83 -85
- package/ios/Helpers.swift +0 -21
- package/lib/commonjs/healthkit.js +225 -0
- package/lib/commonjs/hooks/useStatisticsForQuantity.js +1 -1
- package/lib/commonjs/index.js +6 -209
- package/lib/commonjs/types/index.js +1 -0
- package/lib/module/healthkit.js +203 -0
- package/lib/module/hooks/useStatisticsForQuantity.js +1 -1
- package/lib/module/index.js +3 -203
- package/lib/module/types/index.js +1 -0
- package/lib/typescript/healthkit.d.ts +69 -0
- package/lib/typescript/{index.ios.d.ts → healthkit.ios.d.ts} +17 -17
- package/lib/typescript/hooks/useHealthkitAuthorization.d.ts +1 -1
- package/lib/typescript/index.d.ts +3 -69
- package/lib/typescript/specs/CategoryTypeModule.nitro.d.ts +1 -1
- package/lib/typescript/specs/CharacteristicTypeModule.nitro.d.ts +2 -2
- package/lib/typescript/specs/CoreModule.nitro.d.ts +3 -3
- package/lib/typescript/types/QuantityType.d.ts +2 -2
- package/lib/typescript/types/QueryOptions.d.ts +11 -3
- package/lib/typescript/types/Shared.d.ts +3 -3
- package/lib/typescript/types/index.d.ts +1 -0
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +4 -4
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +30 -39
- package/nitrogen/generated/ios/c++/HybridCharacteristicTypeModuleSpecSwift.hpp +3 -2
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__chrono__system_clock__time_point_.swift +52 -0
- package/nitrogen/generated/ios/swift/HybridCharacteristicTypeModuleSpec.swift +2 -2
- package/nitrogen/generated/ios/swift/HybridCharacteristicTypeModuleSpec_cxx.swift +23 -11
- package/nitrogen/generated/ios/swift/StatisticsQueryOptions.swift +33 -19
- package/nitrogen/generated/shared/c++/HybridCharacteristicTypeModuleSpec.hpp +3 -2
- package/nitrogen/generated/shared/c++/StatisticsQueryOptions.hpp +11 -5
- package/package.json +1 -1
- package/src/healthkit.ts +422 -0
- package/src/hooks/useHealthkitAuthorization.ts +2 -2
- package/src/hooks/useStatisticsForQuantity.ts +1 -3
- package/src/index.ts +3 -419
- package/src/specs/CategoryTypeModule.nitro.ts +1 -1
- package/src/specs/CharacteristicTypeModule.nitro.ts +2 -2
- package/src/specs/CoreModule.nitro.ts +5 -5
- package/src/test-setup.ts +0 -1
- package/src/types/QuantityType.ts +2 -2
- package/src/types/QueryOptions.ts +25 -4
- package/src/types/Shared.ts +6 -8
- package/src/types/index.ts +1 -0
- package/nitrogen/generated/ios/swift/Func_void_std__chrono__system_clock__time_point.swift +0 -46
- package/nitrogen/generated/ios/swift/Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout.swift +0 -19
- /package/lib/commonjs/{index.ios.js → healthkit.ios.js} +0 -0
- /package/lib/module/{index.ios.js → healthkit.ios.js} +0 -0
- /package/src/{index.ios.ts → healthkit.ios.ts} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import HealthKit
|
|
3
2
|
import NitroModules
|
|
4
3
|
|
|
@@ -6,23 +5,23 @@ class CharacteristicTypeModule: HybridCharacteristicTypeModuleSpec {
|
|
|
6
5
|
func getBloodTypeAsync() throws -> Promise<BloodType> {
|
|
7
6
|
return Promise.resolved(withResult: try self.getBloodType())
|
|
8
7
|
}
|
|
9
|
-
|
|
10
|
-
func getDateOfBirthAsync() throws -> Promise<Date
|
|
8
|
+
|
|
9
|
+
func getDateOfBirthAsync() throws -> Promise<Date?> {
|
|
11
10
|
return Promise.resolved(withResult: try self.getDateOfBirth())
|
|
12
11
|
}
|
|
13
|
-
|
|
12
|
+
|
|
14
13
|
func getBiologicalSexAsync() throws -> Promise<BiologicalSex> {
|
|
15
14
|
return Promise.resolved(withResult: try self.getBiologicalSex())
|
|
16
15
|
}
|
|
17
|
-
|
|
16
|
+
|
|
18
17
|
func getFitzpatrickSkinTypeAsync() throws -> Promise<FitzpatrickSkinType> {
|
|
19
18
|
return Promise.resolved(withResult: try self.getFitzpatrickSkinType())
|
|
20
19
|
}
|
|
21
|
-
|
|
20
|
+
|
|
22
21
|
func getWheelchairUseAsync() throws -> Promise<WheelchairUse> {
|
|
23
22
|
return Promise.resolved(withResult: try self.getWheelchairUse())
|
|
24
23
|
}
|
|
25
|
-
|
|
24
|
+
|
|
26
25
|
// Using the global 'store' instance defined in Auth.swift
|
|
27
26
|
|
|
28
27
|
func getBiologicalSex() throws -> BiologicalSex {
|
|
@@ -33,34 +32,50 @@ class CharacteristicTypeModule: HybridCharacteristicTypeModuleSpec {
|
|
|
33
32
|
throw RuntimeError.error(withMessage: "[react-native-healthkit] Got unknown biological sex value: \(biologicalSexObject.biologicalSex.rawValue)")
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
func getDateOfBirth() throws -> Date? {
|
|
36
|
+
do {
|
|
37
|
+
let components = try store.dateOfBirthComponents()
|
|
38
|
+
return components.date
|
|
39
|
+
} catch {
|
|
40
|
+
let nsError = error as NSError
|
|
41
|
+
|
|
42
|
+
// 1️⃣ HealthKit’s documented “no data” error
|
|
43
|
+
if nsError.domain == HKError.errorDomain,
|
|
44
|
+
nsError.code == HKError.Code.errorNoData.rawValue {
|
|
45
|
+
return nil
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 2️⃣ The undocumented generic Obj-C error some OS versions emit
|
|
49
|
+
if nsError.domain == "Foundation._GenericObjCError",
|
|
50
|
+
nsError.code == 0 {
|
|
51
|
+
return nil
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Anything else is a real failure – surface it to JS
|
|
55
|
+
throw RuntimeError.error(
|
|
56
|
+
withMessage: "[react-native-healthkit] Failed to get date of birth: \(nsError.localizedDescription)"
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
45
60
|
|
|
46
61
|
func getBloodType() throws -> BloodType {
|
|
47
62
|
let bloodTypeObject = try store.bloodType()
|
|
48
|
-
|
|
49
|
-
if let bloodType = BloodType(rawValue: Int32(bloodTypeObject.bloodType.rawValue)){
|
|
63
|
+
|
|
64
|
+
if let bloodType = BloodType(rawValue: Int32(bloodTypeObject.bloodType.rawValue)) {
|
|
50
65
|
return bloodType
|
|
51
66
|
}
|
|
52
|
-
|
|
67
|
+
|
|
53
68
|
throw RuntimeError.error(withMessage: "[react-native-healthkit] Got unknown blood type value: \(bloodTypeObject.bloodType.rawValue)")
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
func getFitzpatrickSkinType() throws -> FitzpatrickSkinType {
|
|
57
72
|
if #available(iOS 9.0, *) {
|
|
58
73
|
let skinTypeObject = try store.fitzpatrickSkinType()
|
|
59
|
-
|
|
74
|
+
|
|
60
75
|
if let skinType = FitzpatrickSkinType(rawValue: Int32(skinTypeObject.skinType.rawValue)) {
|
|
61
76
|
return skinType
|
|
62
77
|
}
|
|
63
|
-
|
|
78
|
+
|
|
64
79
|
throw RuntimeError.error(withMessage: "[react-native-healthkit] Got unknown Fitzpatrick skin type value: \(skinTypeObject.skinType.rawValue)")
|
|
65
80
|
} else {
|
|
66
81
|
throw RuntimeError.error(withMessage: "Fitzpatrick skin type is not available before iOS 9.0")
|
package/ios/CoreModule.swift
CHANGED
|
@@ -9,102 +9,99 @@ import NitroModules
|
|
|
9
9
|
|
|
10
10
|
var store = HKHealthStore.init()
|
|
11
11
|
|
|
12
|
-
var quantityTypeUnitCache =
|
|
12
|
+
var quantityTypeUnitCache = [HKQuantityType: HKUnit]()
|
|
13
13
|
|
|
14
14
|
func getUnitToUse(unitOverride: String?, quantityType: HKQuantityType) async throws -> HKUnit {
|
|
15
15
|
if let unitOverride = unitOverride {
|
|
16
16
|
let unit = HKUnit(from: unitOverride)
|
|
17
|
-
|
|
18
|
-
if
|
|
17
|
+
|
|
18
|
+
if !quantityType.is(compatibleWith: unit) {
|
|
19
19
|
throw RuntimeError.error(withMessage: "[react-native-healthkit] Unit \(unitOverride) is incompatible with \(quantityType.identifier)")
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
return unit
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
if let preferredUnit = try await getPreferredUnitsInternal(quantityTypes: [quantityType]).first?.value {
|
|
26
26
|
return preferredUnit
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
throw RuntimeError.error(withMessage: "[react-native-healthkit] Must specify a unit for \(quantityType.identifier)")
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
func getPreferredUnitsInternal(quantityTypes: [HKQuantityType], forceUpdate: Bool? = false) async throws -> [HKQuantityType: HKUnit] {
|
|
33
|
-
|
|
34
|
-
if
|
|
35
|
-
let itemsInCache = quantityTypeUnitCache.filter { (quantityType: HKQuantityType,
|
|
33
|
+
|
|
34
|
+
if forceUpdate != true {
|
|
35
|
+
let itemsInCache = quantityTypeUnitCache.filter { (quantityType: HKQuantityType, _: HKUnit) in
|
|
36
36
|
return quantityTypes.contains(where: { $0 == quantityType })
|
|
37
37
|
}
|
|
38
|
-
if
|
|
38
|
+
if itemsInCache.count == quantityTypes.count {
|
|
39
39
|
return itemsInCache
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
|
|
44
43
|
return try await withCheckedThrowingContinuation { continuation in
|
|
45
44
|
store.preferredUnits(for: Set(quantityTypes)) {
|
|
46
45
|
(typePerUnits: [HKQuantityType: HKUnit], error: Error?) in
|
|
47
46
|
if let error = error {
|
|
48
47
|
return continuation.resume(throwing: error)
|
|
49
48
|
}
|
|
50
|
-
|
|
49
|
+
|
|
51
50
|
typePerUnits.forEach { (type: HKQuantityType, unit: HKUnit) in
|
|
52
51
|
quantityTypeUnitCache.updateValue(unit, forKey: type)
|
|
53
52
|
}
|
|
54
|
-
|
|
53
|
+
|
|
55
54
|
return continuation.resume(returning: typePerUnits)
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
class CoreModule
|
|
61
|
-
func areObjectTypesAvailable(objectTypeIdentifiers: [ObjectTypeIdentifier]) ->
|
|
62
|
-
var dict =
|
|
63
|
-
|
|
59
|
+
class CoreModule: HybridCoreModuleSpec {
|
|
60
|
+
func areObjectTypesAvailable(objectTypeIdentifiers: [ObjectTypeIdentifier]) -> [String: Bool] {
|
|
61
|
+
var dict = [String: Bool]()
|
|
62
|
+
|
|
64
63
|
for objectTypeIdentifier in objectTypeIdentifiers {
|
|
65
64
|
dict[objectTypeIdentifier.stringValue] = isObjectTypeAvailable(objectTypeIdentifier: objectTypeIdentifier)
|
|
66
65
|
}
|
|
67
|
-
|
|
66
|
+
|
|
68
67
|
return dict
|
|
69
68
|
}
|
|
70
|
-
|
|
71
|
-
func areObjectTypesAvailableAsync(objectTypeIdentifiers: [ObjectTypeIdentifier]) -> Promise<
|
|
72
|
-
return Promise.resolved(withResult:
|
|
69
|
+
|
|
70
|
+
func areObjectTypesAvailableAsync(objectTypeIdentifiers: [ObjectTypeIdentifier]) -> Promise<[String: Bool]> {
|
|
71
|
+
return Promise.resolved(withResult: areObjectTypesAvailable(objectTypeIdentifiers: objectTypeIdentifiers))
|
|
73
72
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
|
|
77
74
|
func isObjectTypeAvailable(objectTypeIdentifier: ObjectTypeIdentifier) -> Bool {
|
|
78
75
|
do {
|
|
79
|
-
|
|
76
|
+
_ = try objectTypeFrom(objectTypeIdentifier: objectTypeIdentifier)
|
|
80
77
|
return true
|
|
81
78
|
} catch {
|
|
82
79
|
return false
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
|
-
|
|
82
|
+
|
|
86
83
|
func isObjectTypeAvailableAsync(objectTypeIdentifier: ObjectTypeIdentifier) -> Promise<Bool> {
|
|
87
84
|
return Promise.resolved(withResult: isObjectTypeAvailable(objectTypeIdentifier: objectTypeIdentifier))
|
|
88
85
|
}
|
|
89
|
-
|
|
86
|
+
|
|
90
87
|
func authorizationStatusFor(
|
|
91
88
|
type: ObjectTypeIdentifier
|
|
92
89
|
) throws -> AuthorizationStatus {
|
|
93
90
|
let objectType = try objectTypeFrom(objectTypeIdentifier: type)
|
|
94
|
-
|
|
91
|
+
|
|
95
92
|
let authStatus = store.authorizationStatus(for: objectType)
|
|
96
|
-
|
|
97
|
-
if let authStatus = AuthorizationStatus(rawValue: Int32(authStatus.rawValue)){
|
|
93
|
+
|
|
94
|
+
if let authStatus = AuthorizationStatus(rawValue: Int32(authStatus.rawValue)) {
|
|
98
95
|
return authStatus
|
|
99
96
|
}
|
|
100
|
-
|
|
97
|
+
|
|
101
98
|
throw RuntimeError.error(withMessage: "[react-native-healthkit] got unrecognized AuthorizationStatus with value \(authStatus.rawValue)")
|
|
102
99
|
}
|
|
103
|
-
|
|
100
|
+
|
|
104
101
|
func getRequestStatusForAuthorization(toShare: [SampleTypeIdentifierWriteable], toRead: [ObjectTypeIdentifier]) throws -> Promise<AuthorizationRequestStatus> {
|
|
105
102
|
let toShare = sampleTypesFromArray(typeIdentifiersWriteable: toShare)
|
|
106
103
|
let toRead = objectTypesFromArray(typeIdentifiers: toRead)
|
|
107
|
-
|
|
104
|
+
|
|
108
105
|
return Promise.async {
|
|
109
106
|
try await withCheckedThrowingContinuation { continuation in
|
|
110
107
|
store.getRequestStatusForAuthorization(toShare: toShare, read: toRead) { status, error in
|
|
@@ -116,17 +113,17 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
116
113
|
} else {
|
|
117
114
|
continuation.resume(throwing: RuntimeError.error(withMessage: "Unrecognized authStatus returned: \(status.rawValue)"))
|
|
118
115
|
}
|
|
119
|
-
|
|
116
|
+
|
|
120
117
|
}
|
|
121
118
|
}
|
|
122
119
|
}
|
|
123
120
|
}
|
|
124
121
|
}
|
|
125
|
-
|
|
122
|
+
|
|
126
123
|
func requestAuthorization(toShare: [SampleTypeIdentifierWriteable], toRead: [ObjectTypeIdentifier]) throws -> Promise<Bool> {
|
|
127
124
|
let share = sampleTypesFromArray(typeIdentifiersWriteable: toShare)
|
|
128
125
|
let toRead = objectTypesFromArray(typeIdentifiers: toRead)
|
|
129
|
-
|
|
126
|
+
|
|
130
127
|
return Promise.async {
|
|
131
128
|
try await withCheckedThrowingContinuation { continuation in
|
|
132
129
|
store.requestAuthorization(toShare: share, read: toRead) { status, error in
|
|
@@ -139,10 +136,10 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
139
136
|
}
|
|
140
137
|
}
|
|
141
138
|
}
|
|
142
|
-
|
|
139
|
+
|
|
143
140
|
func querySources(identifier: SampleTypeIdentifier) throws -> Promise<[HybridSourceProxySpec]> {
|
|
144
141
|
let sampleType = try sampleTypeFrom(sampleTypeIdentifier: identifier)
|
|
145
|
-
|
|
142
|
+
|
|
146
143
|
return Promise.async {
|
|
147
144
|
try await withCheckedThrowingContinuation { continuation in
|
|
148
145
|
let query = HKSourceQuery(
|
|
@@ -153,26 +150,26 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
153
150
|
continuation.resume(throwing: error)
|
|
154
151
|
return
|
|
155
152
|
}
|
|
156
|
-
|
|
153
|
+
|
|
157
154
|
guard let sources = sources else {
|
|
158
155
|
return continuation.resume(throwing: RuntimeError.error(withMessage: "Empty response for sample type \(identifier.stringValue)"))
|
|
159
156
|
}
|
|
160
|
-
|
|
157
|
+
|
|
161
158
|
let serializedSources = sources.map { source -> SourceProxy in
|
|
162
|
-
|
|
159
|
+
|
|
163
160
|
return SourceProxy(
|
|
164
161
|
source: source
|
|
165
162
|
)
|
|
166
163
|
}
|
|
167
|
-
|
|
164
|
+
|
|
168
165
|
continuation.resume(returning: serializedSources)
|
|
169
166
|
}
|
|
170
|
-
|
|
167
|
+
|
|
171
168
|
store.execute(query)
|
|
172
169
|
}
|
|
173
170
|
}
|
|
174
171
|
}
|
|
175
|
-
|
|
172
|
+
|
|
176
173
|
func enableBackgroundDelivery(typeIdentifier: ObjectTypeIdentifier, updateFrequency: UpdateFrequency) throws -> Promise<Bool> {
|
|
177
174
|
if let frequency = HKUpdateFrequency(rawValue: Int(updateFrequency.rawValue)) {
|
|
178
175
|
let type = try objectTypeFrom(objectTypeIdentifier: typeIdentifier)
|
|
@@ -193,7 +190,7 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
193
190
|
throw RuntimeError.error(withMessage: "Invalid update frequency value: \(updateFrequency)")
|
|
194
191
|
}
|
|
195
192
|
}
|
|
196
|
-
|
|
193
|
+
|
|
197
194
|
func disableBackgroundDelivery(
|
|
198
195
|
typeIdentifier: ObjectTypeIdentifier
|
|
199
196
|
) throws -> Promise<Bool> {
|
|
@@ -211,7 +208,7 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
211
208
|
}
|
|
212
209
|
}
|
|
213
210
|
}
|
|
214
|
-
|
|
211
|
+
|
|
215
212
|
func disableAllBackgroundDelivery() throws -> Promise<Bool> {
|
|
216
213
|
return Promise.async {
|
|
217
214
|
try await withCheckedThrowingContinuation { continuation in
|
|
@@ -224,64 +221,65 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
224
221
|
}
|
|
225
222
|
}
|
|
226
223
|
}
|
|
227
|
-
|
|
224
|
+
|
|
228
225
|
func unsubscribeQueryAsync(queryId: String) throws -> Promise<Bool> {
|
|
229
226
|
let result = try self.unsubscribeQuery(queryId: queryId)
|
|
230
|
-
|
|
227
|
+
|
|
231
228
|
return Promise.resolved(withResult: result)
|
|
232
229
|
}
|
|
233
|
-
|
|
230
|
+
|
|
234
231
|
func isHealthDataAvailableAsync() -> Promise<Bool> {
|
|
235
232
|
return Promise.resolved(withResult: HKHealthStore.isHealthDataAvailable())
|
|
236
233
|
}
|
|
237
|
-
|
|
234
|
+
|
|
238
235
|
func isProtectedDataAvailableAsync() -> Promise<Bool> {
|
|
239
236
|
return Promise.resolved(withResult: UIApplication.shared.isProtectedDataAvailable)
|
|
240
237
|
}
|
|
241
|
-
|
|
238
|
+
|
|
242
239
|
func isHealthDataAvailable() throws -> Bool {
|
|
243
240
|
return HKHealthStore.isHealthDataAvailable()
|
|
244
241
|
}
|
|
245
|
-
|
|
242
|
+
|
|
246
243
|
func isProtectedDataAvailable() throws -> Bool {
|
|
247
244
|
return UIApplication.shared.isProtectedDataAvailable
|
|
248
245
|
}
|
|
249
|
-
|
|
246
|
+
|
|
250
247
|
func getPreferredUnits(identifiers: [QuantityTypeIdentifier], forceUpdate: Bool?) throws -> Promise<[IdentifierWithUnit]> {
|
|
251
248
|
return Promise.async {
|
|
252
|
-
|
|
249
|
+
|
|
253
250
|
let quantityTypes = identifiers.compactMap { identifier in
|
|
254
251
|
do {
|
|
255
252
|
let quantityType = try initializeQuantityType(identifier.stringValue)
|
|
253
|
+
|
|
256
254
|
return quantityType
|
|
257
255
|
} catch {
|
|
258
256
|
print(error.localizedDescription)
|
|
259
257
|
return nil
|
|
260
258
|
}
|
|
261
259
|
}
|
|
262
|
-
|
|
260
|
+
|
|
263
261
|
let typePerUnits = try await getPreferredUnitsInternal(quantityTypes: quantityTypes, forceUpdate: forceUpdate)
|
|
264
|
-
|
|
262
|
+
|
|
265
263
|
let dic = typePerUnits.map { typePerUnit in
|
|
266
264
|
return IdentifierWithUnit(
|
|
267
265
|
typeIdentifier: typePerUnit.key.identifier,
|
|
268
266
|
unit: typePerUnit.value.unitString
|
|
269
267
|
)
|
|
270
268
|
}
|
|
271
|
-
|
|
269
|
+
|
|
272
270
|
return dic
|
|
273
271
|
}
|
|
274
272
|
}
|
|
275
|
-
|
|
273
|
+
|
|
276
274
|
var _runningQueries: [String: HKQuery] = [:]
|
|
277
|
-
|
|
275
|
+
|
|
278
276
|
func deleteObjects(objectTypeIdentifier: ObjectTypeIdentifier, filter: FilterForSamples) throws -> Promise<Double> {
|
|
279
277
|
let predicate = try createPredicateForSamples(filter: filter)
|
|
280
278
|
let of = try objectTypeFrom(objectTypeIdentifier: objectTypeIdentifier)
|
|
281
|
-
|
|
279
|
+
|
|
282
280
|
return Promise.async {
|
|
283
281
|
return try await withCheckedThrowingContinuation { continuation in
|
|
284
|
-
store.deleteObjects(of: of, predicate: predicate) { (
|
|
282
|
+
store.deleteObjects(of: of, predicate: predicate) { (_, count, error) in
|
|
285
283
|
if let error = error {
|
|
286
284
|
continuation.resume(throwing: error)
|
|
287
285
|
} else {
|
|
@@ -291,21 +289,21 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
291
289
|
}
|
|
292
290
|
}
|
|
293
291
|
}
|
|
294
|
-
|
|
292
|
+
|
|
295
293
|
func subscribeToObserverQuery(
|
|
296
294
|
typeIdentifier: SampleTypeIdentifier,
|
|
297
295
|
callback: @escaping (OnChangeCallbackArgs) -> Void
|
|
298
296
|
) throws -> String {
|
|
299
297
|
let sampleType = try sampleTypeFrom(sampleTypeIdentifier: typeIdentifier)
|
|
300
|
-
|
|
298
|
+
|
|
301
299
|
let predicate = HKQuery.predicateForSamples(
|
|
302
300
|
withStart: Date.init(),
|
|
303
301
|
end: nil,
|
|
304
302
|
options: HKQueryOptions.strictStartDate
|
|
305
303
|
)
|
|
306
|
-
|
|
304
|
+
|
|
307
305
|
let queryId = UUID().uuidString
|
|
308
|
-
|
|
306
|
+
|
|
309
307
|
func responder(
|
|
310
308
|
query: HKObserverQuery,
|
|
311
309
|
handler: @escaping HKObserverQueryCompletionHandler,
|
|
@@ -316,42 +314,42 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
316
314
|
handler()
|
|
317
315
|
}
|
|
318
316
|
}
|
|
319
|
-
|
|
317
|
+
|
|
320
318
|
let query = HKObserverQuery(
|
|
321
319
|
sampleType: sampleType,
|
|
322
320
|
predicate: predicate
|
|
323
321
|
) {
|
|
324
322
|
(query: HKObserverQuery, handler: @escaping HKObserverQueryCompletionHandler, error: Error?)
|
|
325
323
|
in
|
|
326
|
-
|
|
324
|
+
|
|
327
325
|
return responder(query: query, handler: handler, error: error)
|
|
328
|
-
|
|
326
|
+
|
|
329
327
|
}
|
|
330
|
-
|
|
328
|
+
|
|
331
329
|
store.execute(query)
|
|
332
|
-
|
|
330
|
+
|
|
333
331
|
self._runningQueries.updateValue(query, forKey: queryId)
|
|
334
|
-
|
|
335
|
-
//resolve(queryId)
|
|
336
|
-
|
|
332
|
+
|
|
333
|
+
// resolve(queryId)
|
|
334
|
+
|
|
337
335
|
return queryId
|
|
338
336
|
}
|
|
339
|
-
|
|
337
|
+
|
|
340
338
|
func unsubscribeQuery(queryId: String) throws -> Bool {
|
|
341
339
|
guard let query = self._runningQueries[queryId] else {
|
|
342
340
|
throw RuntimeError.error(withMessage: "Query with id \(queryId) not found")
|
|
343
341
|
}
|
|
344
|
-
|
|
342
|
+
|
|
345
343
|
store.stop(query)
|
|
346
|
-
|
|
344
|
+
|
|
347
345
|
self._runningQueries.removeValue(forKey: queryId)
|
|
348
|
-
|
|
346
|
+
|
|
349
347
|
return true
|
|
350
348
|
}
|
|
351
|
-
|
|
349
|
+
|
|
352
350
|
func unsubscribeQueriesAsync(queryIds: [String]) throws -> Promise<Double> {
|
|
353
351
|
let successCount = self.unsubscribeQueries(queryIds: queryIds)
|
|
354
|
-
|
|
352
|
+
|
|
355
353
|
return Promise.resolved(withResult: successCount)
|
|
356
354
|
}
|
|
357
355
|
|
|
@@ -359,17 +357,17 @@ class CoreModule : HybridCoreModuleSpec {
|
|
|
359
357
|
let successCounts = queryIds.map { queryId in
|
|
360
358
|
if let query = self._runningQueries[queryId] {
|
|
361
359
|
store.stop(query)
|
|
362
|
-
|
|
360
|
+
|
|
363
361
|
self._runningQueries.removeValue(forKey: queryId)
|
|
364
|
-
|
|
362
|
+
|
|
365
363
|
return true
|
|
366
364
|
}
|
|
367
|
-
|
|
365
|
+
|
|
368
366
|
print("Query with id \(queryId) not found, skipping unsubscribe")
|
|
369
|
-
|
|
367
|
+
|
|
370
368
|
return false
|
|
371
369
|
}
|
|
372
|
-
|
|
370
|
+
|
|
373
371
|
return Double(successCounts.filter { $0 }.count)
|
|
374
372
|
}
|
|
375
373
|
|
package/ios/Helpers.swift
CHANGED
|
@@ -136,27 +136,6 @@ func createUUIDsPredicate(uuidsWrapper: PredicateWithUUIDs) -> NSPredicate {
|
|
|
136
136
|
return HKQuery.predicateForObjects(with: Set(uuids))
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
func createPredicate(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout?) throws -> NSPredicate? {
|
|
140
|
-
if let filter = filter {
|
|
141
|
-
switch filter {
|
|
142
|
-
case .first(let uuidWrapper):
|
|
143
|
-
return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
|
|
144
|
-
case .second(let uuidsWrapper):
|
|
145
|
-
return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
|
|
146
|
-
case .third(let metadataKey):
|
|
147
|
-
return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
|
|
148
|
-
case .fourth(let dateFilter):
|
|
149
|
-
return createDatePredicate(dateFilter: dateFilter)
|
|
150
|
-
case .fifth(let w):
|
|
151
|
-
if let w = w.workout as? WorkoutProxy {
|
|
152
|
-
return w.workoutPredicate
|
|
153
|
-
}
|
|
154
|
-
throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return nil
|
|
158
|
-
}
|
|
159
|
-
|
|
160
139
|
func createPredicate(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_FilterForSamplesAnd_FilterForSamplesOr?) throws -> NSPredicate? {
|
|
161
140
|
if let filter = filter {
|
|
162
141
|
switch filter {
|