@kingstinct/react-native-healthkit 13.0.1 → 13.1.0
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/Bridge.h +2 -0
- package/ios/CharacteristicTypeModule.swift +6 -10
- package/ios/CoreModule.swift +16 -2
- package/ios/ElectrocardiogramModule.swift +0 -1
- package/ios/ExceptionCatcher.h +1 -14
- package/ios/ExceptionCatcher.mm +17 -0
- package/ios/HeartbeatSeriesModule.swift +0 -1
- package/ios/Helpers.swift +40 -25
- package/ios/QuantityTypeModule.swift +88 -84
- package/ios/Serializers.swift +11 -28
- package/ios/WorkoutProxy.swift +5 -7
- package/ios/WorkoutsModule.swift +12 -14
- package/lib/commonjs/healthkit.ios.js +4 -2
- package/lib/commonjs/healthkit.js +3 -1
- package/lib/commonjs/types/Constants.js +12 -1
- package/lib/commonjs/types/Shared.js +0 -11
- package/lib/module/healthkit.ios.js +2 -0
- package/lib/module/healthkit.js +2 -0
- package/lib/module/types/Constants.js +11 -0
- package/lib/module/types/Shared.js +1 -10
- package/lib/typescript/healthkit.d.ts +2 -1
- package/lib/typescript/healthkit.ios.d.ts +4 -2
- package/lib/typescript/specs/CoreModule.nitro.d.ts +3 -2
- package/lib/typescript/specs/MedicationModule.nitro.d.ts +3 -0
- package/lib/typescript/types/Constants.d.ts +11 -0
- package/lib/typescript/types/Shared.d.ts +2 -11
- package/lib/typescript/types/Source.d.ts +2 -2
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +8 -0
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +43 -15
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +12 -1
- package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridCoreModuleSpec.swift +2 -1
- package/nitrogen/generated/ios/swift/HybridCoreModuleSpec_cxx.swift +20 -1
- package/nitrogen/generated/ios/swift/ObjectTypeIdentifier.swift +4 -4
- package/nitrogen/generated/ios/swift/PerObjectTypeIdentifier.swift +40 -0
- package/nitrogen/generated/ios/swift/SourceRevision.swift +16 -54
- package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.hpp +8 -1
- package/nitrogen/generated/shared/c++/ObjectTypeIdentifier.hpp +4 -4
- package/nitrogen/generated/shared/c++/PerObjectTypeIdentifier.hpp +76 -0
- package/nitrogen/generated/shared/c++/SourceRevision.hpp +10 -10
- package/package.json +1 -1
- package/src/healthkit.ios.ts +3 -0
- package/src/healthkit.ts +6 -0
- package/src/specs/CoreModule.nitro.ts +6 -1
- package/src/specs/MedicationModule.nitro.ts +3 -0
- package/src/types/Constants.ts +16 -0
- package/src/types/Shared.ts +8 -13
- package/src/types/Source.ts +2 -2
package/ios/Bridge.h
CHANGED
|
@@ -80,20 +80,16 @@ class CharacteristicTypeModule: HybridCharacteristicTypeModuleSpec {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
func getFitzpatrickSkinType() throws -> FitzpatrickSkinType {
|
|
83
|
-
|
|
84
|
-
let skinTypeObject = try store.fitzpatrickSkinType()
|
|
83
|
+
let skinTypeObject = try store.fitzpatrickSkinType()
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
throw runtimeErrorWithPrefix(
|
|
91
|
-
"Got unknown Fitzpatrick skin type value: \(skinTypeObject.skinType.rawValue)")
|
|
85
|
+
if let skinType = FitzpatrickSkinType(rawValue: Int32(skinTypeObject.skinType.rawValue)) {
|
|
86
|
+
return skinType
|
|
92
87
|
}
|
|
93
|
-
|
|
88
|
+
|
|
89
|
+
throw runtimeErrorWithPrefix(
|
|
90
|
+
"Got unknown Fitzpatrick skin type value: \(skinTypeObject.skinType.rawValue)")
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
@available(iOS 10.0, *)
|
|
97
93
|
func getWheelchairUse() throws -> WheelchairUse {
|
|
98
94
|
let wheelchairUseObject = try store.wheelchairUse()
|
|
99
95
|
if let wheelChairUse = WheelchairUse(
|
package/ios/CoreModule.swift
CHANGED
|
@@ -76,6 +76,20 @@ async throws -> [HKQuantityType: HKUnit] {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
class CoreModule: HybridCoreModuleSpec {
|
|
79
|
+
func requestPerObjectReadAuthorization(typeIdentifier: PerObjectTypeIdentifier) -> Promise<Void> {
|
|
80
|
+
return Promise.async {
|
|
81
|
+
let objectType = try perObjectTypeFrom(objectTypeIdentifier: typeIdentifier)
|
|
82
|
+
if #available(iOS 16.0, *) {
|
|
83
|
+
try await store.requestPerObjectReadAuthorization(
|
|
84
|
+
for: objectType,
|
|
85
|
+
predicate: nil
|
|
86
|
+
)
|
|
87
|
+
} else {
|
|
88
|
+
warnWithPrefix("Per-object read authorization is only available on iOS 16.0 and above")
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
79
93
|
func currentAppSource() -> any HybridSourceProxySpec {
|
|
80
94
|
return SourceProxy(source: HKSource.default())
|
|
81
95
|
}
|
|
@@ -323,12 +337,12 @@ class CoreModule: HybridCoreModuleSpec {
|
|
|
323
337
|
|
|
324
338
|
var _runningQueries: [String: HKQuery] = [:]
|
|
325
339
|
|
|
326
|
-
func deleteObjects(objectTypeIdentifier:
|
|
340
|
+
func deleteObjects(objectTypeIdentifier: SampleTypeIdentifierWriteable, filter: FilterForSamples)
|
|
327
341
|
-> Promise<Double> {
|
|
328
342
|
return Promise.async {
|
|
329
343
|
if let predicate = createPredicateForSamples(filter) {
|
|
330
344
|
|
|
331
|
-
let of = try
|
|
345
|
+
let of = try sampleTypeFrom(sampleTypeIdentifierWriteable: objectTypeIdentifier)
|
|
332
346
|
return try await withCheckedThrowingContinuation { continuation in
|
|
333
347
|
store.deleteObjects(of: of, predicate: predicate) { (_, count, error) in
|
|
334
348
|
if let error = error {
|
package/ios/ExceptionCatcher.h
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
#import <Foundation/Foundation.h>
|
|
2
2
|
#import <HealthKit/HealthKit.h>
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
if (outError) { *outError = nil; }
|
|
6
|
-
@try {
|
|
7
|
-
HKUnit *unit = [HKUnit unitFromString:unitString];
|
|
8
|
-
return unit;
|
|
9
|
-
}
|
|
10
|
-
@catch (NSException *exception) {
|
|
11
|
-
if (outError) {
|
|
12
|
-
NSDictionary *userInfo = exception.userInfo ?: @{};
|
|
13
|
-
*outError = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
|
14
|
-
}
|
|
15
|
-
return nil;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
4
|
+
HKUnit * _Nullable HKUnitFromStringCatchingExceptions(NSString * _Nonnull unitString, NSError * _Nullable * _Nullable outError);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#import "ExceptionCatcher.h"
|
|
2
|
+
|
|
3
|
+
HKUnit * _Nullable HKUnitFromStringCatchingExceptions(NSString * _Nonnull unitString, NSError * _Nullable * _Nullable outError) {
|
|
4
|
+
if (outError) { *outError = nil; }
|
|
5
|
+
@try {
|
|
6
|
+
HKUnit *unit = [HKUnit unitFromString:unitString];
|
|
7
|
+
return unit;
|
|
8
|
+
}
|
|
9
|
+
@catch (NSException *exception) {
|
|
10
|
+
if (outError) {
|
|
11
|
+
NSDictionary *userInfo = exception.userInfo ?: @{};
|
|
12
|
+
|
|
13
|
+
*outError = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
|
|
14
|
+
}
|
|
15
|
+
return nil;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -81,7 +81,6 @@ func getHeartbeatSeriesHeartbeats(sample: HKHeartbeatSeriesSample) async throws
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
@available(iOS 13.0.0, *)
|
|
85
84
|
class HeartbeatSeriesModule: HybridHeartbeatSeriesModuleSpec {
|
|
86
85
|
func queryHeartbeatSeriesSamples(
|
|
87
86
|
options: QueryOptionsWithSortOrder
|
package/ios/Helpers.swift
CHANGED
|
@@ -258,30 +258,24 @@ private func sampleTypeFromStringNullable(typeIdentifier: String) throws -> HKSa
|
|
|
258
258
|
return HKSampleType.workoutType()
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
if
|
|
262
|
-
|
|
263
|
-
return try initializeSeriesType(typeIdentifier)
|
|
264
|
-
}
|
|
261
|
+
if typeIdentifier == HKWorkoutRouteTypeIdentifier {
|
|
262
|
+
return try initializeSeriesType(typeIdentifier)
|
|
265
263
|
}
|
|
266
264
|
|
|
267
|
-
if
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
265
|
+
if typeIdentifier == HKAudiogramTypeIdentifier {
|
|
266
|
+
return HKObjectType.audiogramSampleType()
|
|
267
|
+
}
|
|
271
268
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
269
|
+
if typeIdentifier == HKDataTypeIdentifierHeartbeatSeries {
|
|
270
|
+
return try initializeSeriesType(typeIdentifier)
|
|
271
|
+
}
|
|
275
272
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
273
|
+
if typeIdentifier == HKAudiogramTypeIdentifier {
|
|
274
|
+
return HKSampleType.audiogramSampleType()
|
|
279
275
|
}
|
|
280
276
|
|
|
281
|
-
if
|
|
282
|
-
|
|
283
|
-
return HKSampleType.electrocardiogramType()
|
|
284
|
-
}
|
|
277
|
+
if typeIdentifier == HKElectrocardiogramType {
|
|
278
|
+
return HKSampleType.electrocardiogramType()
|
|
285
279
|
}
|
|
286
280
|
|
|
287
281
|
#if compiler(>=6)
|
|
@@ -366,6 +360,28 @@ func objectTypeFrom(objectTypeIdentifier: ObjectTypeIdentifier) throws -> HKObje
|
|
|
366
360
|
"Failed initializing unrecognized objectType identifier " + typeIdentifier)
|
|
367
361
|
}
|
|
368
362
|
|
|
363
|
+
// objectType is wider than sampleType, so it uses it under the hood
|
|
364
|
+
func perObjectTypeFrom(objectTypeIdentifier: PerObjectTypeIdentifier) throws -> HKObjectType {
|
|
365
|
+
let typeIdentifier = objectTypeIdentifier.stringValue
|
|
366
|
+
|
|
367
|
+
if #available(iOS 16.0, *) {
|
|
368
|
+
if typeIdentifier == HKVisionPrescriptionTypeIdentifier {
|
|
369
|
+
return HKObjectType.visionPrescriptionType()
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
#if compiler(>=6.2)
|
|
374
|
+
if #available(iOS 26.0, *) {
|
|
375
|
+
if typeIdentifier == "UserAnnotatedMedicationType" {
|
|
376
|
+
return HKObjectType.userAnnotatedMedicationType()
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
#endif
|
|
380
|
+
|
|
381
|
+
throw runtimeErrorWithPrefix(
|
|
382
|
+
"Failed initializing unrecognized objectType identifier " + typeIdentifier)
|
|
383
|
+
}
|
|
384
|
+
|
|
369
385
|
func componentsFromInterval(_ interval: NSDictionary) -> DateComponents {
|
|
370
386
|
let componentKeys: [String: WritableKeyPath<DateComponents, Int?>] = [
|
|
371
387
|
"minute": \.minute,
|
|
@@ -454,13 +470,12 @@ func buildStatisticsOptions(statistics: [StatisticsOptions], quantityType: HKQua
|
|
|
454
470
|
warnWithPrefix("buildStatisticsOptions: discretemin statistic requested for cumulative quantity type \(quantityType.identifier)")
|
|
455
471
|
}
|
|
456
472
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
473
|
+
|
|
474
|
+
if statistic == .duration {
|
|
475
|
+
opts.insert(HKStatisticsOptions.duration)
|
|
476
|
+
}
|
|
477
|
+
if statistic == .mostrecent {
|
|
478
|
+
opts.insert(HKStatisticsOptions.mostRecent)
|
|
464
479
|
}
|
|
465
480
|
}
|
|
466
481
|
return opts
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import HealthKit
|
|
2
2
|
import NitroModules
|
|
3
3
|
|
|
4
|
-
func emptyStatisticsResponse(from: Date
|
|
4
|
+
func emptyStatisticsResponse(from: Date?, to: Date?) -> QueryStatisticsResponse {
|
|
5
5
|
var response = QueryStatisticsResponse()
|
|
6
6
|
|
|
7
7
|
response.startDate = from
|
|
8
8
|
response.endDate = to
|
|
9
|
+
response.sources = []
|
|
9
10
|
|
|
10
11
|
return response
|
|
11
12
|
}
|
|
@@ -14,7 +15,7 @@ func queryStatisticsForQuantityInternal(
|
|
|
14
15
|
quantityType: HKQuantityType,
|
|
15
16
|
statistics: [StatisticsOptions],
|
|
16
17
|
options: StatisticsQueryOptions?
|
|
17
|
-
) async throws -> HKStatistics {
|
|
18
|
+
) async throws -> HKStatistics? {
|
|
18
19
|
let predicate = createPredicateForSamples(options?.filter)
|
|
19
20
|
|
|
20
21
|
return try await withCheckedThrowingContinuation { continuation in
|
|
@@ -25,7 +26,9 @@ func queryStatisticsForQuantityInternal(
|
|
|
25
26
|
) { (_, stats: HKStatistics?, error: Error?) in
|
|
26
27
|
DispatchQueue.main.async {
|
|
27
28
|
if let error = error {
|
|
28
|
-
return
|
|
29
|
+
return handleHKNoDataOrThrow(error: error, continuation: continuation, noDataFallback: {
|
|
30
|
+
return nil
|
|
31
|
+
})
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
if let stats = stats {
|
|
@@ -78,30 +81,26 @@ func serializeStatistics(gottenStats: HKStatistics, unit: HKUnit) -> QueryStatis
|
|
|
78
81
|
)
|
|
79
82
|
}
|
|
80
83
|
|
|
81
|
-
if
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
84
|
+
if let mostRecent = gottenStats.mostRecentQuantity() {
|
|
85
|
+
response.mostRecentQuantity = Quantity(
|
|
86
|
+
unit: unit.unitString,
|
|
87
|
+
quantity: mostRecent.doubleValue(for: unit)
|
|
88
|
+
)
|
|
89
|
+
}
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
91
|
+
if let mostRecentDateInterval = gottenStats.mostRecentQuantityDateInterval() {
|
|
92
|
+
response.mostRecentQuantityDateInterval = QuantityDateInterval(
|
|
93
|
+
from: mostRecentDateInterval.start,
|
|
94
|
+
to: mostRecentDateInterval.end
|
|
95
|
+
)
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
if
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
104
|
-
}
|
|
98
|
+
if let duration = gottenStats.duration() {
|
|
99
|
+
let durationUnit = HKUnit.second()
|
|
100
|
+
response.duration = Quantity(
|
|
101
|
+
unit: durationUnit.unitString,
|
|
102
|
+
quantity: duration.doubleValue(for: durationUnit)
|
|
103
|
+
)
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
return response
|
|
@@ -113,7 +112,7 @@ func queryStatisticsCollectionForQuantityInternal(
|
|
|
113
112
|
anchorDate: Date,
|
|
114
113
|
intervalComponents: IntervalComponents,
|
|
115
114
|
options: StatisticsQueryOptions?
|
|
116
|
-
) async throws -> HKStatisticsCollection {
|
|
115
|
+
) async throws -> HKStatisticsCollection? {
|
|
117
116
|
let predicate = createPredicateForSamples(options?.filter)
|
|
118
117
|
|
|
119
118
|
// Create date components from interval
|
|
@@ -148,7 +147,9 @@ func queryStatisticsCollectionForQuantityInternal(
|
|
|
148
147
|
|
|
149
148
|
query.initialResultsHandler = { (_, results: HKStatisticsCollection?, error: Error?) in
|
|
150
149
|
if let error = error {
|
|
151
|
-
return
|
|
150
|
+
return handleHKNoDataOrThrow(error: error, continuation: continuation, noDataFallback: {
|
|
151
|
+
return nil
|
|
152
|
+
})
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
guard let statistics = results else {
|
|
@@ -196,31 +197,28 @@ func serializeStatisticsPerSource(gottenStats: HKStatistics, unit: HKUnit)
|
|
|
196
197
|
)
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
if
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
200
|
+
if let mostRecent = gottenStats.mostRecentQuantity(for: source) {
|
|
201
|
+
response.mostRecentQuantity = Quantity(
|
|
202
|
+
unit: unit.unitString,
|
|
203
|
+
quantity: mostRecent.doubleValue(for: unit)
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
207
|
+
if let mostRecentDateInterval = gottenStats.mostRecentQuantityDateInterval(for: source) {
|
|
208
|
+
response.mostRecentQuantityDateInterval = QuantityDateInterval(
|
|
209
|
+
from: mostRecentDateInterval.start,
|
|
210
|
+
to: mostRecentDateInterval.end
|
|
211
|
+
)
|
|
213
212
|
}
|
|
214
213
|
|
|
215
|
-
if
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
)
|
|
222
|
-
}
|
|
214
|
+
if let duration = gottenStats.duration(for: source) {
|
|
215
|
+
let durationUnit = HKUnit.second()
|
|
216
|
+
response.duration = Quantity(
|
|
217
|
+
unit: durationUnit.unitString,
|
|
218
|
+
quantity: duration.doubleValue(for: durationUnit)
|
|
219
|
+
)
|
|
223
220
|
}
|
|
221
|
+
|
|
224
222
|
return response
|
|
225
223
|
}
|
|
226
224
|
}
|
|
@@ -280,20 +278,19 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
280
278
|
return Promise.async {
|
|
281
279
|
let quantityType = try initializeQuantityType(identifier.stringValue)
|
|
282
280
|
|
|
283
|
-
let gottenStats = try await queryStatisticsForQuantityInternal(
|
|
281
|
+
if let gottenStats = try await queryStatisticsForQuantityInternal(
|
|
284
282
|
quantityType: quantityType,
|
|
285
283
|
statistics: statistics,
|
|
286
284
|
options: options
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return response
|
|
285
|
+
) {
|
|
286
|
+
let unit = try await getUnitToUse(
|
|
287
|
+
unitOverride: options?.unit,
|
|
288
|
+
quantityType: quantityType
|
|
289
|
+
)
|
|
290
|
+
return serializeStatisticsPerSource(gottenStats: gottenStats, unit: unit)
|
|
291
|
+
} else {
|
|
292
|
+
return []
|
|
293
|
+
}
|
|
297
294
|
}
|
|
298
295
|
}
|
|
299
296
|
|
|
@@ -304,22 +301,24 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
304
301
|
return Promise.async {
|
|
305
302
|
let quantityType = try initializeQuantityType(identifier.stringValue)
|
|
306
303
|
|
|
307
|
-
let statistics = try await queryStatisticsCollectionForQuantityInternal(
|
|
304
|
+
if let statistics = try await queryStatisticsCollectionForQuantityInternal(
|
|
308
305
|
quantityType: quantityType,
|
|
309
306
|
statistics: statistics,
|
|
310
307
|
anchorDate: anchorDate,
|
|
311
308
|
intervalComponents: intervalComponents,
|
|
312
309
|
options: options
|
|
313
|
-
)
|
|
310
|
+
) {
|
|
314
311
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
312
|
+
let unit = try await getUnitToUse(
|
|
313
|
+
unitOverride: options?.unit,
|
|
314
|
+
quantityType: quantityType
|
|
315
|
+
)
|
|
319
316
|
|
|
320
|
-
|
|
321
|
-
|
|
317
|
+
return statistics.statistics().flatMap { statistics in
|
|
318
|
+
return serializeStatisticsPerSource(gottenStats: statistics, unit: unit)
|
|
319
|
+
}
|
|
322
320
|
}
|
|
321
|
+
return []
|
|
323
322
|
}
|
|
324
323
|
}
|
|
325
324
|
|
|
@@ -351,20 +350,23 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
351
350
|
return Promise.async {
|
|
352
351
|
let quantityType = try initializeQuantityType(identifier.stringValue)
|
|
353
352
|
|
|
354
|
-
let gottenStats = try await queryStatisticsForQuantityInternal(
|
|
353
|
+
if let gottenStats = try await queryStatisticsForQuantityInternal(
|
|
355
354
|
quantityType: quantityType,
|
|
356
355
|
statistics: statistics,
|
|
357
356
|
options: options
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
)
|
|
357
|
+
) {
|
|
358
|
+
let unit = try await getUnitToUse(
|
|
359
|
+
unitOverride: options?.unit,
|
|
360
|
+
quantityType: quantityType
|
|
361
|
+
)
|
|
364
362
|
|
|
365
|
-
|
|
363
|
+
return serializeStatistics(gottenStats: gottenStats, unit: unit)
|
|
364
|
+
}
|
|
366
365
|
|
|
367
|
-
return
|
|
366
|
+
return emptyStatisticsResponse(
|
|
367
|
+
from: options?.filter?.date?.startDate,
|
|
368
|
+
to: options?.filter?.date?.endDate
|
|
369
|
+
)
|
|
368
370
|
}
|
|
369
371
|
}
|
|
370
372
|
|
|
@@ -375,22 +377,24 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
375
377
|
return Promise.async {
|
|
376
378
|
let quantityType = try initializeQuantityType(identifier.stringValue)
|
|
377
379
|
|
|
378
|
-
let statistics = try await queryStatisticsCollectionForQuantityInternal(
|
|
380
|
+
if let statistics = try await queryStatisticsCollectionForQuantityInternal(
|
|
379
381
|
quantityType: quantityType,
|
|
380
382
|
statistics: statistics,
|
|
381
383
|
anchorDate: anchorDate,
|
|
382
384
|
intervalComponents: intervalComponents,
|
|
383
385
|
options: options
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
)
|
|
386
|
+
) {
|
|
387
|
+
let unit = try await getUnitToUse(
|
|
388
|
+
unitOverride: options?.unit,
|
|
389
|
+
quantityType: quantityType
|
|
390
|
+
)
|
|
390
391
|
|
|
391
|
-
|
|
392
|
-
|
|
392
|
+
return statistics.statistics().map { statistics in
|
|
393
|
+
return serializeStatistics(gottenStats: statistics, unit: unit)
|
|
394
|
+
}
|
|
393
395
|
}
|
|
396
|
+
|
|
397
|
+
return []
|
|
394
398
|
}
|
|
395
399
|
}
|
|
396
400
|
|
package/ios/Serializers.swift
CHANGED
|
@@ -218,19 +218,15 @@ func serializeUnknownQuantityTyped(quantity: HKQuantity?) -> Quantity? {
|
|
|
218
218
|
return serializeQuantityTyped(unit: METUnit, quantity: quantity)
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
if
|
|
222
|
-
|
|
223
|
-
return serializeQuantityTyped(unit: HKUnit.internationalUnit(), quantity: quantity)
|
|
224
|
-
}
|
|
221
|
+
if quantity.is(compatibleWith: HKUnit.internationalUnit()) {
|
|
222
|
+
return serializeQuantityTyped(unit: HKUnit.internationalUnit(), quantity: quantity)
|
|
225
223
|
}
|
|
226
224
|
|
|
227
|
-
if
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return serializeQuantityTyped(unit: HKUnit.decibelHearingLevel(), quantity: quantity)
|
|
233
|
-
}
|
|
225
|
+
if quantity.is(compatibleWith: HKUnit.hertz()) {
|
|
226
|
+
return serializeQuantityTyped(unit: HKUnit.hertz(), quantity: quantity)
|
|
227
|
+
}
|
|
228
|
+
if quantity.is(compatibleWith: HKUnit.decibelHearingLevel()) {
|
|
229
|
+
return serializeQuantityTyped(unit: HKUnit.decibelHearingLevel(), quantity: quantity)
|
|
234
230
|
}
|
|
235
231
|
|
|
236
232
|
if #available(iOS 16.0, *) {
|
|
@@ -318,32 +314,19 @@ func serializeDevice(hkDevice: HKDevice?) -> Device? {
|
|
|
318
314
|
)
|
|
319
315
|
}
|
|
320
316
|
|
|
321
|
-
func serializeOperatingSystemVersion(_ version: OperatingSystemVersion
|
|
322
|
-
guard let version = version else {
|
|
323
|
-
return nil
|
|
324
|
-
}
|
|
325
|
-
|
|
317
|
+
func serializeOperatingSystemVersion(_ version: OperatingSystemVersion) -> String {
|
|
326
318
|
let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
|
|
327
319
|
|
|
328
320
|
return versionString
|
|
329
321
|
}
|
|
330
322
|
|
|
331
323
|
func serializeSourceRevision(_ hkSourceRevision: HKSourceRevision) -> SourceRevision {
|
|
332
|
-
if #available(iOS 11, *) {
|
|
333
|
-
return SourceRevision(
|
|
334
|
-
source: serializeSource(hkSourceRevision.source),
|
|
335
|
-
version: hkSourceRevision.version,
|
|
336
|
-
operatingSystemVersion: serializeOperatingSystemVersion(
|
|
337
|
-
hkSourceRevision.operatingSystemVersion),
|
|
338
|
-
productType: hkSourceRevision.productType
|
|
339
|
-
)
|
|
340
|
-
}
|
|
341
|
-
|
|
342
324
|
return SourceRevision(
|
|
343
325
|
source: serializeSource(hkSourceRevision.source),
|
|
344
326
|
version: hkSourceRevision.version,
|
|
345
|
-
operatingSystemVersion:
|
|
346
|
-
|
|
327
|
+
operatingSystemVersion: serializeOperatingSystemVersion(
|
|
328
|
+
hkSourceRevision.operatingSystemVersion),
|
|
329
|
+
productType: hkSourceRevision.productType
|
|
347
330
|
)
|
|
348
331
|
}
|
|
349
332
|
|
package/ios/WorkoutProxy.swift
CHANGED
|
@@ -329,13 +329,11 @@ class WorkoutProxy: HybridWorkoutProxySpec {
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
var totalFlightsClimbed: Quantity? {
|
|
332
|
-
if
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
)
|
|
338
|
-
}
|
|
332
|
+
if let hkTotalFlightsClimbed = workout.totalFlightsClimbed {
|
|
333
|
+
return Quantity(
|
|
334
|
+
unit: "count",
|
|
335
|
+
quantity: hkTotalFlightsClimbed.doubleValue(for: HKUnit.count())
|
|
336
|
+
)
|
|
339
337
|
}
|
|
340
338
|
return nil
|
|
341
339
|
}
|
package/ios/WorkoutsModule.swift
CHANGED
|
@@ -159,20 +159,18 @@ class WorkoutsModule: HybridWorkoutsModuleSpec {
|
|
|
159
159
|
metadata: metadataDeserialized
|
|
160
160
|
)
|
|
161
161
|
} else {
|
|
162
|
-
if
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
)
|
|
175
|
-
}
|
|
162
|
+
if let totalFlightsClimbed = totalFlightsClimbed {
|
|
163
|
+
workout = HKWorkout.init(
|
|
164
|
+
activityType: type,
|
|
165
|
+
start: startDate,
|
|
166
|
+
end: endDate,
|
|
167
|
+
workoutEvents: nil,
|
|
168
|
+
totalEnergyBurned: totalEnergyBurned,
|
|
169
|
+
totalDistance: totalDistance,
|
|
170
|
+
totalFlightsClimbed: totalFlightsClimbed,
|
|
171
|
+
device: nil,
|
|
172
|
+
metadata: metadataDeserialized
|
|
173
|
+
)
|
|
176
174
|
}
|
|
177
175
|
}
|
|
178
176
|
|
|
@@ -17,8 +17,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.
|
|
21
|
-
exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.currentAppSource = exports.queryMedicationEventsWithAnchor = exports.queryMedicationEvents = exports.queryMedications = exports.requestMedicationsAuthorization = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isQuantityCompatibleWithUnit = exports.saveStateOfMindSample = exports.queryStateOfMindSamplesWithAnchor = exports.queryStateOfMindSamples = exports.isProtectedDataAvailable = exports.startWatchApp = exports.saveWorkoutSample = exports.saveQuantitySample = exports.saveCorrelationSample = void 0;
|
|
20
|
+
exports.deleteObjects = exports.requestAuthorization = exports.querySources = exports.queryWorkoutSamplesWithAnchor = exports.queryWorkoutSamples = exports.queryStatisticsCollectionForQuantitySeparateBySource = exports.queryStatisticsForQuantitySeparateBySource = exports.queryStatisticsCollectionForQuantity = exports.queryStatisticsForQuantity = exports.queryQuantitySamplesWithAnchor = exports.queryQuantitySamples = exports.queryElectrocardiogramSamplesWithAnchor = exports.queryElectrocardiogramSamples = exports.queryHeartbeatSeriesSamplesWithAnchor = exports.queryHeartbeatSeriesSamples = exports.queryCorrelationSamplesWithAnchor = exports.queryCorrelationSamples = exports.queryCategorySamplesWithAnchor = exports.queryCategorySamples = exports.isHealthDataAvailableAsync = exports.isHealthDataAvailable = exports.getWheelchairUse = exports.getRequestStatusForAuthorization = exports.getPreferredUnits = exports.getFitzpatrickSkinType = exports.getDateOfBirth = exports.getBloodType = exports.getBiologicalSex = exports.enableBackgroundDelivery = exports.disableBackgroundDelivery = exports.disableAllBackgroundDelivery = exports.requestPerObjectReadAuthorization = exports.authorizationStatusFor = exports.useSubscribeToQuantitySamples = exports.useSubscribeToChanges = exports.useSubscribeToCategorySamples = exports.useStatisticsForQuantity = exports.useSources = exports.useMostRecentWorkout = exports.useMostRecentQuantitySample = exports.useMostRecentCategorySample = exports.useIsHealthDataAvailable = exports.useHealthkitAuthorization = exports.subscribeToQuantitySamples = exports.subscribeToChanges = exports.subscribeToCategorySamples = exports.getPreferredUnit = exports.getMostRecentWorkout = exports.getMostRecentQuantitySample = exports.getMostRecentCategorySample = void 0;
|
|
21
|
+
exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.currentAppSource = exports.queryMedicationEventsWithAnchor = exports.queryMedicationEvents = exports.queryMedications = exports.requestMedicationsAuthorization = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isQuantityCompatibleWithUnit = exports.saveStateOfMindSample = exports.queryStateOfMindSamplesWithAnchor = exports.queryStateOfMindSamples = exports.isProtectedDataAvailable = exports.startWatchApp = exports.saveWorkoutSample = exports.saveQuantitySample = exports.saveCorrelationSample = exports.saveCategorySample = void 0;
|
|
22
22
|
const react_native_1 = require("react-native");
|
|
23
23
|
const useHealthkitAuthorization_1 = __importDefault(require("./hooks/useHealthkitAuthorization"));
|
|
24
24
|
exports.useHealthkitAuthorization = useHealthkitAuthorization_1.default;
|
|
@@ -59,6 +59,7 @@ __exportStar(require("./types"), exports);
|
|
|
59
59
|
const currentMajorVersionIOS = react_native_1.Platform.OS === 'ios' ? Number.parseInt(react_native_1.Platform.Version, 10) : 0;
|
|
60
60
|
// Named exports - all functions bound to their respective modules
|
|
61
61
|
exports.authorizationStatusFor = modules_1.Core.authorizationStatusFor.bind(modules_1.Core);
|
|
62
|
+
exports.requestPerObjectReadAuthorization = modules_1.Core.requestPerObjectReadAuthorization.bind(modules_1.Core);
|
|
62
63
|
exports.disableAllBackgroundDelivery = modules_1.Core.disableAllBackgroundDelivery.bind(modules_1.Core);
|
|
63
64
|
exports.disableBackgroundDelivery = modules_1.Core.disableBackgroundDelivery.bind(modules_1.Core);
|
|
64
65
|
exports.enableBackgroundDelivery = modules_1.Core.enableBackgroundDelivery.bind(modules_1.Core);
|
|
@@ -160,6 +161,7 @@ exports.default = {
|
|
|
160
161
|
queryWorkoutSamplesWithAnchor: exports.queryWorkoutSamplesWithAnchor,
|
|
161
162
|
querySources: exports.querySources,
|
|
162
163
|
requestAuthorization: exports.requestAuthorization,
|
|
164
|
+
requestPerObjectReadAuthorization: exports.requestPerObjectReadAuthorization,
|
|
163
165
|
deleteObjects: exports.deleteObjects,
|
|
164
166
|
saveCategorySample: exports.saveCategorySample,
|
|
165
167
|
saveCorrelationSample: exports.saveCorrelationSample,
|