@kingstinct/react-native-healthkit 9.0.6 → 9.0.8
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/CategoryTypeModule.swift +18 -21
- package/ios/CharacteristicTypeModule.swift +36 -21
- package/ios/CorrelationTypeModule.swift +18 -18
- package/ios/HeartbeatSeriesModule.swift +32 -32
- package/ios/QuantityTypeModule.swift +56 -57
- package/ios/Serializers.swift +12 -16
- package/ios/StateOfMindModule.swift +17 -17
- package/ios/WorkoutsModule.swift +59 -110
- package/lib/commonjs/healthkit.js +225 -0
- package/lib/commonjs/hooks/useStatisticsForQuantity.js +1 -1
- package/lib/commonjs/index.js +6 -209
- package/lib/module/healthkit.js +203 -0
- package/lib/module/hooks/useStatisticsForQuantity.js +1 -1
- package/lib/module/index.js +3 -203
- package/lib/typescript/healthkit.d.ts +69 -0
- package/lib/typescript/{index.ios.d.ts → healthkit.ios.d.ts} +11 -11
- 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/specs/WorkoutsModule.nitro.d.ts +3 -0
- package/lib/typescript/types/Shared.d.ts +3 -3
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +7 -48
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +54 -154
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +0 -14
- 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/shared/c++/HybridCharacteristicTypeModuleSpec.hpp +3 -2
- package/package.json +2 -2
- 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/specs/WorkoutsModule.nitro.ts +3 -0
- package/src/test-setup.ts +0 -1
- package/src/types/QueryOptions.ts +3 -3
- package/src/types/Shared.ts +6 -8
- package/ios/WorkoutSessionModule.swift +0 -182
- package/lib/commonjs/specs/WorkoutSessionModule.nitro.js +0 -19
- package/lib/module/specs/WorkoutSessionModule.nitro.js +0 -16
- package/lib/typescript/specs/WorkoutSessionModule.nitro.d.ts +0 -47
- package/nitrogen/generated/ios/c++/HybridWorkoutSessionModuleSpecSwift.cpp +0 -11
- package/nitrogen/generated/ios/c++/HybridWorkoutSessionModuleSpecSwift.hpp +0 -107
- package/nitrogen/generated/ios/swift/Func_void_WorkoutEventType.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_WorkoutSessionState_WorkoutSessionState_std__chrono__system_clock__time_point.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__chrono__system_clock__time_point.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__vector_RemoteSessionSharableData_.swift +0 -46
- package/nitrogen/generated/ios/swift/HybridWorkoutSessionModuleSpec.swift +0 -49
- package/nitrogen/generated/ios/swift/HybridWorkoutSessionModuleSpec_cxx.swift +0 -133
- package/nitrogen/generated/ios/swift/RemoteSessionSharableData.swift +0 -46
- package/nitrogen/generated/ios/swift/WorkoutSessionMirroringStartHandlerOptions.swift +0 -118
- package/nitrogen/generated/ios/swift/WorkoutSessionState.swift +0 -56
- package/nitrogen/generated/shared/c++/HybridWorkoutSessionModuleSpec.cpp +0 -22
- package/nitrogen/generated/shared/c++/HybridWorkoutSessionModuleSpec.hpp +0 -68
- package/nitrogen/generated/shared/c++/RemoteSessionSharableData.hpp +0 -75
- package/nitrogen/generated/shared/c++/WorkoutSessionMirroringStartHandlerOptions.hpp +0 -92
- package/nitrogen/generated/shared/c++/WorkoutSessionState.hpp +0 -68
- package/src/specs/WorkoutSessionModule.nitro.ts +0 -71
- /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,9 +1,7 @@
|
|
|
1
1
|
import HealthKit
|
|
2
2
|
import NitroModules
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
4
|
+
class CategoryTypeModule: HybridCategoryTypeModuleSpec {
|
|
7
5
|
func saveCategorySample(
|
|
8
6
|
identifier: CategoryTypeIdentifier,
|
|
9
7
|
value: Double,
|
|
@@ -12,7 +10,7 @@ class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
|
12
10
|
metadata: AnyMapHolder
|
|
13
11
|
) throws -> Promise<Bool> {
|
|
14
12
|
let type = try initializeCategoryType(identifier.stringValue)
|
|
15
|
-
|
|
13
|
+
|
|
16
14
|
let sample = HKCategorySample(
|
|
17
15
|
type: type,
|
|
18
16
|
value: Int(value),
|
|
@@ -20,7 +18,7 @@ class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
|
20
18
|
end: endDate,
|
|
21
19
|
metadata: anyMapToDictionary(metadata)
|
|
22
20
|
)
|
|
23
|
-
|
|
21
|
+
|
|
24
22
|
return Promise.async {
|
|
25
23
|
try await withCheckedThrowingContinuation { continuation in
|
|
26
24
|
store.save(sample) { (success: Bool, error: Error?) in
|
|
@@ -33,15 +31,15 @@ class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
|
-
|
|
34
|
+
|
|
37
35
|
func queryCategorySamples(
|
|
38
36
|
identifier: CategoryTypeIdentifier,
|
|
39
|
-
options: QueryOptionsWithSortOrder
|
|
37
|
+
options: QueryOptionsWithSortOrder?
|
|
40
38
|
) throws -> Promise<[CategorySample]> {
|
|
41
39
|
let sampleType = try initializeCategoryType(identifier.stringValue)
|
|
42
40
|
let predicate = try createPredicate(filter: options?.filter)
|
|
43
41
|
let queryLimit = getQueryLimit(options?.limit)
|
|
44
|
-
|
|
42
|
+
|
|
45
43
|
return Promise.async {
|
|
46
44
|
try await withCheckedThrowingContinuation { continuation in
|
|
47
45
|
let query = HKSampleQuery(
|
|
@@ -54,36 +52,35 @@ class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
|
54
52
|
continuation.resume(throwing: error)
|
|
55
53
|
return
|
|
56
54
|
}
|
|
57
|
-
|
|
55
|
+
|
|
58
56
|
guard let samples = samples else {
|
|
59
57
|
continuation.resume(returning: [])
|
|
60
58
|
return
|
|
61
59
|
}
|
|
62
|
-
|
|
60
|
+
|
|
63
61
|
let categorySamples = samples.compactMap { sample -> CategorySample? in
|
|
64
62
|
guard let categorySample = sample as? HKCategorySample else { return nil }
|
|
65
63
|
return serializeCategorySample(sample: categorySample)
|
|
66
64
|
}
|
|
67
|
-
|
|
65
|
+
|
|
68
66
|
continuation.resume(returning: categorySamples)
|
|
69
67
|
}
|
|
70
|
-
|
|
68
|
+
|
|
71
69
|
store.execute(query)
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
|
|
77
74
|
func queryCategorySamplesWithAnchor(
|
|
78
75
|
identifier: CategoryTypeIdentifier,
|
|
79
76
|
options: QueryOptionsWithAnchor
|
|
80
77
|
) throws -> Promise<CategorySamplesWithAnchorResponse> {
|
|
81
78
|
let sampleType = try initializeCategoryType(identifier.stringValue)
|
|
82
|
-
|
|
79
|
+
|
|
83
80
|
let predicate = try createPredicate(filter: options.filter)
|
|
84
81
|
let queryLimit = getQueryLimit(options.limit)
|
|
85
82
|
let queryAnchor = try deserializeHKQueryAnchor(base64String: options.anchor)
|
|
86
|
-
|
|
83
|
+
|
|
87
84
|
return Promise.async {
|
|
88
85
|
try await withCheckedThrowingContinuation { continuation in
|
|
89
86
|
let query = HKAnchoredObjectQuery(
|
|
@@ -96,7 +93,7 @@ class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
|
96
93
|
continuation.resume(throwing: error)
|
|
97
94
|
return
|
|
98
95
|
}
|
|
99
|
-
|
|
96
|
+
|
|
100
97
|
guard let samples = samples else {
|
|
101
98
|
let response = CategorySamplesWithAnchorResponse(
|
|
102
99
|
samples: [],
|
|
@@ -106,21 +103,21 @@ class CategoryTypeModule : HybridCategoryTypeModuleSpec {
|
|
|
106
103
|
continuation.resume(returning: response)
|
|
107
104
|
return
|
|
108
105
|
}
|
|
109
|
-
|
|
106
|
+
|
|
110
107
|
let categorySamples = samples.compactMap { sample -> CategorySample? in
|
|
111
108
|
guard let categorySample = sample as? HKCategorySample else { return nil }
|
|
112
109
|
return serializeCategorySample(sample: categorySample)
|
|
113
110
|
}
|
|
114
|
-
|
|
111
|
+
|
|
115
112
|
let response = CategorySamplesWithAnchorResponse(
|
|
116
113
|
samples: categorySamples,
|
|
117
114
|
deletedSamples: deletedSamples?.map { serializeDeletedSample(sample: $0) } ?? [],
|
|
118
115
|
newAnchor: serializeAnchor(anchor: newAnchor) ?? ""
|
|
119
116
|
)
|
|
120
|
-
|
|
117
|
+
|
|
121
118
|
continuation.resume(returning: response)
|
|
122
119
|
}
|
|
123
|
-
|
|
120
|
+
|
|
124
121
|
store.execute(query)
|
|
125
122
|
}
|
|
126
123
|
}
|
|
@@ -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")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import HealthKit
|
|
2
2
|
import NitroModules
|
|
3
3
|
|
|
4
|
-
class CorrelationTypeModule
|
|
4
|
+
class CorrelationTypeModule: HybridCorrelationTypeModuleSpec {
|
|
5
5
|
func saveCorrelationSample(
|
|
6
6
|
typeIdentifier: CorrelationTypeIdentifier,
|
|
7
7
|
samples: [SampleForSaving],
|
|
@@ -10,16 +10,16 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
10
10
|
metadata: AnyMapHolder
|
|
11
11
|
) throws -> Promise<Bool> {
|
|
12
12
|
let correlationType = try initializeCorrelationType(typeIdentifier.stringValue)
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
var initializedSamples = Set<HKSample>()
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
for sample in samples {
|
|
17
17
|
if let quantitySample = sample as? QuantitySampleForSaving {
|
|
18
18
|
let quantityTypeId = HKQuantityTypeIdentifier(rawValue: quantitySample.quantityType.stringValue)
|
|
19
19
|
guard let quantityType = HKSampleType.quantityType(forIdentifier: quantityTypeId) else {
|
|
20
20
|
continue
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
let unit = HKUnit(from: quantitySample.unit)
|
|
24
24
|
let quantity = HKQuantity(unit: unit, doubleValue: quantitySample.quantity)
|
|
25
25
|
let hkQuantitySample = HKQuantitySample(
|
|
@@ -30,10 +30,10 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
30
30
|
metadata: anyMapToDictionary(quantitySample.metadata)
|
|
31
31
|
)
|
|
32
32
|
initializedSamples.insert(hkQuantitySample)
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
} else if let categorySample = sample as? CategorySampleForSaving {
|
|
35
35
|
let categoryType = try initializeCategoryType(categorySample.categoryType.stringValue)
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
let hkCategorySample = HKCategorySample(
|
|
38
38
|
type: categoryType,
|
|
39
39
|
value: Int(categorySample.value),
|
|
@@ -44,7 +44,7 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
44
44
|
initializedSamples.insert(hkCategorySample)
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
let correlation = HKCorrelation(
|
|
49
49
|
type: correlationType,
|
|
50
50
|
start: start,
|
|
@@ -52,7 +52,7 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
52
52
|
objects: initializedSamples,
|
|
53
53
|
metadata: anyMapToDictionary(metadata)
|
|
54
54
|
)
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
return Promise.async {
|
|
57
57
|
try await withCheckedThrowingContinuation { continuation in
|
|
58
58
|
store.save(correlation) { (success: Bool, error: Error?) in
|
|
@@ -65,7 +65,7 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
func queryCorrelationSamples(
|
|
70
70
|
typeIdentifier: CorrelationTypeIdentifier,
|
|
71
71
|
from: Date,
|
|
@@ -82,7 +82,7 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
82
82
|
)
|
|
83
83
|
)
|
|
84
84
|
)
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
return Promise.async {
|
|
87
87
|
try await withCheckedThrowingContinuation { continuation in
|
|
88
88
|
let query = HKCorrelationQuery(
|
|
@@ -94,12 +94,12 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
94
94
|
continuation.resume(throwing: error)
|
|
95
95
|
return
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
guard let correlations = correlations else {
|
|
99
99
|
continuation.resume(returning: [])
|
|
100
100
|
return
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
|
|
103
103
|
// Collect all quantity types to get preferred units
|
|
104
104
|
var quantityTypes = Set<HKQuantityType>()
|
|
105
105
|
for correlation in correlations {
|
|
@@ -109,13 +109,13 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
store.preferredUnits(for: quantityTypes) { (unitMap: [HKQuantityType: HKUnit], error: Error?) in
|
|
114
114
|
if let error = error {
|
|
115
115
|
continuation.resume(throwing: error)
|
|
116
116
|
return
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
|
|
119
119
|
let serializedCorrelations = correlations.map { correlation -> CorrelationSample in
|
|
120
120
|
let objects = correlation.objects.compactMap { object -> CorrelationObject? in
|
|
121
121
|
if let quantitySample = object as? HKQuantitySample,
|
|
@@ -126,13 +126,13 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
126
126
|
} catch {
|
|
127
127
|
print(error.localizedDescription)
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
} else if let categorySample = object as? HKCategorySample {
|
|
131
131
|
return CorrelationObject.first(serializeCategorySample(sample: categorySample))
|
|
132
132
|
}
|
|
133
133
|
return nil
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
|
|
136
136
|
return CorrelationSample(
|
|
137
137
|
correlationType: CorrelationTypeIdentifier(fromString: correlation.correlationType.identifier)!,
|
|
138
138
|
objects: objects,
|
|
@@ -141,11 +141,11 @@ class CorrelationTypeModule : HybridCorrelationTypeModuleSpec {
|
|
|
141
141
|
endDate: correlation.endDate
|
|
142
142
|
)
|
|
143
143
|
}
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
continuation.resume(returning: serializedCorrelations)
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
store.execute(query)
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -5,7 +5,7 @@ func getHeartbeatSeriesByID(
|
|
|
5
5
|
seriesUUID: UUID
|
|
6
6
|
) async -> HKHeartbeatSeriesSample? {
|
|
7
7
|
let seriesPredicate = HKQuery.predicateForObject(with: seriesUUID)
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
let samples = try! await withCheckedThrowingContinuation {
|
|
10
10
|
(continuation: CheckedContinuation<[HKSample], Error>) in
|
|
11
11
|
let query = HKSampleQuery(
|
|
@@ -14,36 +14,36 @@ func getHeartbeatSeriesByID(
|
|
|
14
14
|
limit: 1,
|
|
15
15
|
sortDescriptors: nil
|
|
16
16
|
) { (_, results, error) in
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
if let hasError = error {
|
|
19
19
|
continuation.resume(throwing: hasError)
|
|
20
20
|
return
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
guard let samples = results else {
|
|
24
24
|
return continuation.resume(throwing: RuntimeError.error(withMessage: "Empty response"))
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
continuation.resume(returning: samples)
|
|
28
28
|
}
|
|
29
29
|
store.execute(query)
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
guard let heartbeatSeries = samples as? [HKHeartbeatSeriesSample] else {
|
|
33
33
|
return nil
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
return heartbeatSeries.first ?? nil
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
@available(iOS 13.0.0, *)
|
|
40
|
-
class HeartbeatSeriesModule
|
|
40
|
+
class HeartbeatSeriesModule: HybridHeartbeatSeriesModuleSpec {
|
|
41
41
|
func queryHeartbeatSeriesSamples(
|
|
42
42
|
options: QueryOptionsWithSortOrder?
|
|
43
43
|
) throws -> Promise<[HeartbeatSeriesSample]> {
|
|
44
44
|
let predicate = try createPredicate(filter: options?.filter)
|
|
45
45
|
let queryLimit = getQueryLimit(options?.limit)
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
return Promise.async {
|
|
48
48
|
try await withCheckedThrowingContinuation { continuation in
|
|
49
49
|
let query = HKSampleQuery(
|
|
@@ -58,42 +58,42 @@ class HeartbeatSeriesModule : HybridHeartbeatSeriesModuleSpec {
|
|
|
58
58
|
continuation.resume(throwing: error)
|
|
59
59
|
return
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
guard let samples = samples else {
|
|
63
63
|
continuation.resume(returning: [])
|
|
64
64
|
return
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
Task {
|
|
68
68
|
do {
|
|
69
69
|
var serializedSamples: [HeartbeatSeriesSample] = []
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
for sample in samples {
|
|
72
72
|
guard let heartbeatSample = sample as? HKHeartbeatSeriesSample else { continue }
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
let serialized = try await self.serializeHeartbeatSeriesSample(sample: heartbeatSample)
|
|
75
75
|
serializedSamples.append(serialized)
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
continuation.resume(returning: serializedSamples)
|
|
79
79
|
} catch {
|
|
80
80
|
continuation.resume(throwing: error)
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
store.execute(query)
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
func queryHeartbeatSeriesSamplesWithAnchor(
|
|
91
91
|
options: QueryOptionsWithAnchor
|
|
92
92
|
) throws -> Promise<HeartbeatSeriesSamplesWithAnchorResponse> {
|
|
93
93
|
let predicate = try createPredicate(filter: options.filter)
|
|
94
94
|
let queryLimit = getQueryLimit(options.limit)
|
|
95
95
|
let queryAnchor = try deserializeHKQueryAnchor(base64String: options.anchor)
|
|
96
|
-
|
|
96
|
+
|
|
97
97
|
return Promise.async {
|
|
98
98
|
try await withCheckedThrowingContinuation { continuation in
|
|
99
99
|
let query = HKAnchoredObjectQuery(
|
|
@@ -106,7 +106,7 @@ class HeartbeatSeriesModule : HybridHeartbeatSeriesModuleSpec {
|
|
|
106
106
|
continuation.resume(throwing: error)
|
|
107
107
|
return
|
|
108
108
|
}
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
guard let samples = samples else {
|
|
111
111
|
let response = HeartbeatSeriesSamplesWithAnchorResponse(
|
|
112
112
|
samples: [],
|
|
@@ -116,38 +116,38 @@ class HeartbeatSeriesModule : HybridHeartbeatSeriesModuleSpec {
|
|
|
116
116
|
continuation.resume(returning: response)
|
|
117
117
|
return
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
Task {
|
|
121
121
|
do {
|
|
122
122
|
var serializedSamples: [HeartbeatSeriesSample] = []
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
for sample in samples {
|
|
125
125
|
guard let heartbeatSample = sample as? HKHeartbeatSeriesSample else { continue }
|
|
126
126
|
let serialized = try await self.serializeHeartbeatSeriesSample(sample: heartbeatSample)
|
|
127
127
|
serializedSamples.append(serialized)
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
let response = HeartbeatSeriesSamplesWithAnchorResponse(
|
|
131
131
|
samples: serializedSamples,
|
|
132
132
|
deletedSamples: deletedSamples?.map { serializeDeletedSample(sample: $0) } ?? [],
|
|
133
133
|
newAnchor: serializeAnchor(anchor: newAnchor) ?? ""
|
|
134
134
|
)
|
|
135
|
-
|
|
135
|
+
|
|
136
136
|
continuation.resume(returning: response)
|
|
137
137
|
} catch {
|
|
138
138
|
continuation.resume(throwing: error)
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
store.execute(query)
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
|
|
147
|
+
|
|
148
148
|
private func serializeHeartbeatSeriesSample(sample: HKHeartbeatSeriesSample) async throws -> HeartbeatSeriesSample {
|
|
149
149
|
let heartbeats = try await getHeartbeatSeriesHeartbeats(sample: sample)
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
return HeartbeatSeriesSample(
|
|
152
152
|
uuid: sample.uuid.uuidString,
|
|
153
153
|
device: serializeDevice(hkDevice: sample.device),
|
|
@@ -158,31 +158,31 @@ class HeartbeatSeriesModule : HybridHeartbeatSeriesModuleSpec {
|
|
|
158
158
|
sourceRevision: serializeSourceRevision(sample.sourceRevision)
|
|
159
159
|
)
|
|
160
160
|
}
|
|
161
|
-
|
|
161
|
+
|
|
162
162
|
private func getHeartbeatSeriesHeartbeats(sample: HKHeartbeatSeriesSample) async throws -> [Heartbeat] {
|
|
163
163
|
return try await withCheckedThrowingContinuation { continuation in
|
|
164
164
|
var allBeats: [Heartbeat] = []
|
|
165
|
-
|
|
166
|
-
let query = HKHeartbeatSeriesQuery(heartbeatSeries: sample) {
|
|
165
|
+
|
|
166
|
+
let query = HKHeartbeatSeriesQuery(heartbeatSeries: sample) {
|
|
167
167
|
(_: HKHeartbeatSeriesQuery, timeSinceSeriesStart: TimeInterval, precededByGap: Bool, done: Bool, error: Error?) in
|
|
168
|
-
|
|
168
|
+
|
|
169
169
|
if let error = error {
|
|
170
170
|
continuation.resume(throwing: error)
|
|
171
171
|
return
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
let heartbeat = Heartbeat(
|
|
175
175
|
timeSinceSeriesStart: timeSinceSeriesStart,
|
|
176
176
|
precededByGap: precededByGap
|
|
177
177
|
)
|
|
178
|
-
|
|
178
|
+
|
|
179
179
|
allBeats.append(heartbeat)
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
if done {
|
|
182
182
|
continuation.resume(returning: allBeats)
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
|
|
186
186
|
store.execute(query)
|
|
187
187
|
}
|
|
188
188
|
}
|