@kingstinct/react-native-healthkit 11.0.0 → 11.1.1
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/README.md +2 -2
- package/ios/ElectrocardiogramModule.swift +212 -0
- package/ios/QuantityTypeModule.swift +52 -15
- package/lib/commonjs/healthkit.ios.js +6 -2
- package/lib/commonjs/healthkit.js +10 -2
- package/lib/commonjs/modules.js +2 -1
- package/lib/commonjs/specs/ElectrocardiogramModule.nitro.js +2 -0
- package/lib/commonjs/types/ElectrocardiogramSample.js +2 -0
- package/lib/module/healthkit.ios.js +5 -1
- package/lib/module/healthkit.js +8 -0
- package/lib/module/modules.js +1 -0
- package/lib/module/specs/ElectrocardiogramModule.nitro.js +1 -0
- package/lib/module/types/ElectrocardiogramSample.js +1 -0
- package/lib/typescript/healthkit.d.ts +2 -0
- package/lib/typescript/healthkit.ios.d.ts +4 -0
- package/lib/typescript/modules.d.ts +2 -0
- package/lib/typescript/specs/ElectrocardiogramModule.nitro.d.ts +8 -0
- package/lib/typescript/types/ElectrocardiogramSample.d.ts +39 -0
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +83 -50
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +257 -74
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +29 -0
- package/nitrogen/generated/ios/ReactNativeHealthkitAutolinking.mm +8 -0
- package/nitrogen/generated/ios/ReactNativeHealthkitAutolinking.swift +15 -0
- package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +1 -1
- package/nitrogen/generated/ios/c++/HybridElectrocardiogramModuleSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridElectrocardiogramModuleSpecSwift.hpp +152 -0
- package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +1 -1
- package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +2 -2
- package/nitrogen/generated/ios/c++/HybridWorkoutProxySpecSwift.hpp +1 -2
- package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +4 -4
- package/nitrogen/generated/ios/swift/CategorySample.swift +2 -16
- package/nitrogen/generated/ios/swift/CategorySampleForSaving.swift +1 -8
- package/nitrogen/generated/ios/swift/ECGQueryOptionsWithAnchor.swift +179 -0
- package/nitrogen/generated/ios/swift/ECGQueryOptionsWithSortOrder.swift +184 -0
- package/nitrogen/generated/ios/swift/ElectrocardiogramClassification.swift +60 -0
- package/nitrogen/generated/ios/swift/ElectrocardiogramLead.swift +40 -0
- package/nitrogen/generated/ios/swift/ElectrocardiogramSample.swift +284 -0
- package/nitrogen/generated/ios/swift/ElectrocardiogramSamplesWithAnchorResponse.swift +81 -0
- package/nitrogen/generated/ios/swift/ElectrocardiogramSymptomsStatus.swift +44 -0
- package/nitrogen/generated/ios/swift/ElectrocardiogramVoltage.swift +57 -0
- package/nitrogen/generated/ios/swift/Func_void_ElectrocardiogramSamplesWithAnchorResponse.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_QueryStatisticsResponse_.swift +1 -8
- package/nitrogen/generated/ios/swift/Func_void_std__optional_WorkoutPlan_.swift +1 -8
- package/nitrogen/generated/ios/swift/Func_void_std__vector_ElectrocardiogramSample_.swift +47 -0
- package/nitrogen/generated/ios/swift/HeartbeatSeriesSample.swift +2 -16
- package/nitrogen/generated/ios/swift/HybridCategoryTypeModuleSpec_cxx.swift +1 -8
- package/nitrogen/generated/ios/swift/HybridCoreModuleSpec_cxx.swift +33 -5
- package/nitrogen/generated/ios/swift/HybridElectrocardiogramModuleSpec.swift +50 -0
- package/nitrogen/generated/ios/swift/HybridElectrocardiogramModuleSpec_cxx.swift +155 -0
- package/nitrogen/generated/ios/swift/HybridHeartbeatSeriesModuleSpec_cxx.swift +1 -8
- package/nitrogen/generated/ios/swift/HybridQuantityTypeModuleSpec_cxx.swift +11 -24
- package/nitrogen/generated/ios/swift/HybridStateOfMindModuleSpec_cxx.swift +10 -9
- package/nitrogen/generated/ios/swift/QuantitySample.swift +2 -16
- package/nitrogen/generated/ios/swift/QuantitySampleForSaving.swift +1 -8
- package/nitrogen/generated/ios/swift/QueryStatisticsResponse.swift +7 -56
- package/nitrogen/generated/ios/swift/StateOfMindSample.swift +23 -45
- package/nitrogen/generated/ios/swift/WorkoutSample.swift +2 -16
- package/nitrogen/generated/shared/c++/CategorySample.hpp +8 -0
- package/nitrogen/generated/shared/c++/CategorySampleForSaving.hpp +8 -0
- package/nitrogen/generated/shared/c++/CategorySamplesWithAnchorResponse.hpp +8 -0
- package/nitrogen/generated/shared/c++/CorrelationSample.hpp +8 -0
- package/nitrogen/generated/shared/c++/DeletedSample.hpp +8 -0
- package/nitrogen/generated/shared/c++/Device.hpp +8 -0
- package/nitrogen/generated/shared/c++/ECGQueryOptionsWithAnchor.hpp +109 -0
- package/nitrogen/generated/shared/c++/ECGQueryOptionsWithSortOrder.hpp +108 -0
- package/nitrogen/generated/shared/c++/ElectrocardiogramClassification.hpp +96 -0
- package/nitrogen/generated/shared/c++/ElectrocardiogramLead.hpp +76 -0
- package/nitrogen/generated/shared/c++/ElectrocardiogramSample.hpp +143 -0
- package/nitrogen/generated/shared/c++/ElectrocardiogramSamplesWithAnchorResponse.hpp +89 -0
- package/nitrogen/generated/shared/c++/ElectrocardiogramSymptomsStatus.hpp +80 -0
- package/nitrogen/generated/shared/c++/ElectrocardiogramVoltage.hpp +84 -0
- package/nitrogen/generated/shared/c++/FilterForSamplesAnd.hpp +8 -0
- package/nitrogen/generated/shared/c++/FilterForSamplesOr.hpp +8 -0
- package/nitrogen/generated/shared/c++/Heartbeat.hpp +8 -0
- package/nitrogen/generated/shared/c++/HeartbeatSeriesSample.hpp +8 -0
- package/nitrogen/generated/shared/c++/HeartbeatSeriesSamplesWithAnchorResponse.hpp +8 -0
- package/nitrogen/generated/shared/c++/HybridElectrocardiogramModuleSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridElectrocardiogramModuleSpec.hpp +76 -0
- package/nitrogen/generated/shared/c++/IdentifierWithUnit.hpp +8 -0
- package/nitrogen/generated/shared/c++/IntervalComponents.hpp +8 -0
- package/nitrogen/generated/shared/c++/LocationForSaving.hpp +8 -0
- package/nitrogen/generated/shared/c++/OnChangeCallbackArgs.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateForWorkoutsAnd.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateForWorkoutsOr.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateFromWorkout.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateWithMetadataKey.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateWithStartAndEnd.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateWithUUID.hpp +8 -0
- package/nitrogen/generated/shared/c++/PredicateWithUUIDs.hpp +8 -0
- package/nitrogen/generated/shared/c++/Quantity.hpp +8 -0
- package/nitrogen/generated/shared/c++/QuantityDateInterval.hpp +8 -0
- package/nitrogen/generated/shared/c++/QuantitySample.hpp +8 -0
- package/nitrogen/generated/shared/c++/QuantitySampleForSaving.hpp +8 -0
- package/nitrogen/generated/shared/c++/QuantitySamplesWithAnchorResponse.hpp +8 -0
- package/nitrogen/generated/shared/c++/QueryOptionsWithAnchor.hpp +8 -0
- package/nitrogen/generated/shared/c++/QueryOptionsWithAnchorAndUnit.hpp +8 -0
- package/nitrogen/generated/shared/c++/QueryOptionsWithSortOrder.hpp +8 -0
- package/nitrogen/generated/shared/c++/QueryOptionsWithSortOrderAndUnit.hpp +8 -0
- package/nitrogen/generated/shared/c++/QueryStatisticsResponse.hpp +8 -0
- package/nitrogen/generated/shared/c++/QueryWorkoutSamplesWithAnchorResponse.hpp +8 -0
- package/nitrogen/generated/shared/c++/Source.hpp +8 -0
- package/nitrogen/generated/shared/c++/SourceRevision.hpp +8 -0
- package/nitrogen/generated/shared/c++/StateOfMindSample.hpp +8 -0
- package/nitrogen/generated/shared/c++/StatisticsQueryOptions.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutActivity.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutActivityTypePredicate.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutConfiguration.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutDurationPredicate.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutEvent.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutPlan.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutQueryOptions.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutQueryOptionsWithAnchor.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutRoute.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutRouteLocation.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutSample.hpp +8 -0
- package/nitrogen/generated/shared/c++/WorkoutTotals.hpp +8 -0
- package/package.json +5 -5
- package/src/healthkit.ios.ts +9 -0
- package/src/healthkit.ts +16 -0
- package/src/modules.ts +6 -0
- package/src/specs/ElectrocardiogramModule.nitro.ts +18 -0
- package/src/types/ElectrocardiogramSample.ts +60 -0
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ Some imperative examples:
|
|
|
104
104
|
|
|
105
105
|
useEffect(() => {
|
|
106
106
|
if (hasRequestedAuthorization) {
|
|
107
|
-
const unsubscribe = subscribeToChanges(
|
|
107
|
+
const unsubscribe = subscribeToChanges('HKQuantityTypeIdentifierHeartRate', () => {
|
|
108
108
|
// refetch data as needed
|
|
109
109
|
});
|
|
110
110
|
|
|
@@ -113,7 +113,7 @@ Some imperative examples:
|
|
|
113
113
|
}, [hasRequestedAuthorization]);
|
|
114
114
|
|
|
115
115
|
/* write data */
|
|
116
|
-
await requestAuthorization([], [
|
|
116
|
+
await requestAuthorization([], ['HKQuantityTypeIdentifierInsulinDelivery']); // request write permission for insulin delivery
|
|
117
117
|
|
|
118
118
|
saveQuantitySample(
|
|
119
119
|
'HKQuantityTypeIdentifierInsulinDelivery',
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import HealthKit
|
|
2
|
+
import NitroModules
|
|
3
|
+
|
|
4
|
+
// MARK: - Helpers
|
|
5
|
+
|
|
6
|
+
func getElectrocardiogramByID(
|
|
7
|
+
seriesUUID: UUID
|
|
8
|
+
) async -> HKElectrocardiogram? {
|
|
9
|
+
let predicate = HKQuery.predicateForObject(with: seriesUUID)
|
|
10
|
+
|
|
11
|
+
let samples = try? await withCheckedThrowingContinuation { (continuation: CheckedContinuation<[HKSample], Error>) in
|
|
12
|
+
let query = HKSampleQuery(
|
|
13
|
+
sampleType: HKObjectType.electrocardiogramType(),
|
|
14
|
+
predicate: predicate,
|
|
15
|
+
limit: 1,
|
|
16
|
+
sortDescriptors: nil
|
|
17
|
+
) { _, results, error in
|
|
18
|
+
if let error { continuation.resume(throwing: error); return }
|
|
19
|
+
guard let results else {
|
|
20
|
+
continuation.resume(throwing: RuntimeError.error(withMessage: "Empty response"))
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
continuation.resume(returning: results)
|
|
24
|
+
}
|
|
25
|
+
store.execute(query)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (samples as? [HKElectrocardiogram])?.first
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@available(iOS 14.0, *)
|
|
32
|
+
class ElectrocardiogramModule: HybridElectrocardiogramModuleSpec {
|
|
33
|
+
|
|
34
|
+
// Query (simple)
|
|
35
|
+
func queryElectrocardiogramSamples(
|
|
36
|
+
options: ECGQueryOptionsWithSortOrder?
|
|
37
|
+
) throws -> Promise<[ElectrocardiogramSample]> {
|
|
38
|
+
let predicate = try createPredicate(filter: options?.filter)
|
|
39
|
+
let queryLimit = getQueryLimit(options?.limit)
|
|
40
|
+
let ascending = options?.ascending ?? false
|
|
41
|
+
let includeVoltages = options?.includeVoltages ?? false
|
|
42
|
+
|
|
43
|
+
return Promise.async {
|
|
44
|
+
try await withCheckedThrowingContinuation { continuation in
|
|
45
|
+
let query = HKSampleQuery(
|
|
46
|
+
sampleType: HKObjectType.electrocardiogramType(),
|
|
47
|
+
predicate: predicate,
|
|
48
|
+
limit: queryLimit,
|
|
49
|
+
sortDescriptors: [
|
|
50
|
+
NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: ascending)
|
|
51
|
+
]
|
|
52
|
+
) { _, samples, error in
|
|
53
|
+
if let error { continuation.resume(throwing: error); return }
|
|
54
|
+
guard let samples = samples as? [HKElectrocardiogram], !samples.isEmpty else {
|
|
55
|
+
continuation.resume(returning: [])
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Task {
|
|
60
|
+
do {
|
|
61
|
+
var out: [ElectrocardiogramSample] = []
|
|
62
|
+
out.reserveCapacity(samples.count)
|
|
63
|
+
for s in samples {
|
|
64
|
+
let serialized = try await self.serializeECGSample(sample: s, includeVoltages: includeVoltages)
|
|
65
|
+
out.append(serialized)
|
|
66
|
+
}
|
|
67
|
+
continuation.resume(returning: out)
|
|
68
|
+
} catch {
|
|
69
|
+
continuation.resume(throwing: error)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
store.execute(query)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Query (anchored)
|
|
79
|
+
func queryElectrocardiogramSamplesWithAnchor(
|
|
80
|
+
options: ECGQueryOptionsWithAnchor
|
|
81
|
+
) throws -> Promise<ElectrocardiogramSamplesWithAnchorResponse> {
|
|
82
|
+
let predicate = try createPredicate(filter: options.filter)
|
|
83
|
+
let queryLimit = getQueryLimit(options.limit)
|
|
84
|
+
let queryAnchor = try deserializeHKQueryAnchor(base64String: options.anchor)
|
|
85
|
+
let includeVoltages = options.includeVoltages
|
|
86
|
+
|
|
87
|
+
return Promise.async {
|
|
88
|
+
try await withCheckedThrowingContinuation { continuation in
|
|
89
|
+
let query = HKAnchoredObjectQuery(
|
|
90
|
+
type: HKObjectType.electrocardiogramType(),
|
|
91
|
+
predicate: predicate,
|
|
92
|
+
anchor: queryAnchor,
|
|
93
|
+
limit: queryLimit
|
|
94
|
+
) { _, samples, deleted, newAnchor, error in
|
|
95
|
+
if let error { continuation.resume(throwing: error); return }
|
|
96
|
+
|
|
97
|
+
Task {
|
|
98
|
+
do {
|
|
99
|
+
let typed = (samples as? [HKElectrocardiogram]) ?? []
|
|
100
|
+
var out: [ElectrocardiogramSample] = []
|
|
101
|
+
out.reserveCapacity(typed.count)
|
|
102
|
+
for s in typed {
|
|
103
|
+
let serialized = try await self.serializeECGSample(sample: s, includeVoltages: includeVoltages)
|
|
104
|
+
out.append(serialized)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let response = ElectrocardiogramSamplesWithAnchorResponse(
|
|
108
|
+
samples: out,
|
|
109
|
+
deletedSamples: (deleted ?? []).map { serializeDeletedSample(sample: $0) },
|
|
110
|
+
newAnchor: serializeAnchor(anchor: newAnchor) ?? ""
|
|
111
|
+
)
|
|
112
|
+
continuation.resume(returning: response)
|
|
113
|
+
} catch {
|
|
114
|
+
continuation.resume(throwing: error)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
store.execute(query)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// MARK: - Serialization
|
|
124
|
+
|
|
125
|
+
private func serializeECGSample(sample: HKElectrocardiogram, includeVoltages: Bool) async throws -> ElectrocardiogramSample {
|
|
126
|
+
// Convert quantities
|
|
127
|
+
let bpmUnit = HKUnit.count().unitDivided(by: .minute())
|
|
128
|
+
let hzUnit = HKUnit.hertz()
|
|
129
|
+
let avgHR = sample.averageHeartRate?.doubleValue(for: bpmUnit)
|
|
130
|
+
let freqHz = sample.samplingFrequency?.doubleValue(for: hzUnit)
|
|
131
|
+
|
|
132
|
+
// Optional: waveform
|
|
133
|
+
let voltages: [ElectrocardiogramVoltage]? = includeVoltages
|
|
134
|
+
? try await getECGVoltages(sample: sample)
|
|
135
|
+
: nil
|
|
136
|
+
|
|
137
|
+
// Algorithm version is stored in metadata under HKAppleECGAlgorithmVersion
|
|
138
|
+
let algorithmVersion = sample.metadata?[HKMetadataKeyAlgorithmVersion] as? String
|
|
139
|
+
|
|
140
|
+
return ElectrocardiogramSample(
|
|
141
|
+
uuid: sample.uuid.uuidString,
|
|
142
|
+
device: serializeDevice(hkDevice: sample.device),
|
|
143
|
+
startDate: sample.startDate,
|
|
144
|
+
endDate: sample.endDate,
|
|
145
|
+
classification: serializeClassification(sample.classification),
|
|
146
|
+
symptomsStatus: serializeSymptomsStatus(sample.symptomsStatus),
|
|
147
|
+
averageHeartRateBpm: avgHR,
|
|
148
|
+
samplingFrequencyHz: freqHz,
|
|
149
|
+
numberOfVoltageMeasurements: Double(sample.numberOfVoltageMeasurements),
|
|
150
|
+
algorithmVersion: algorithmVersion,
|
|
151
|
+
voltages: voltages,
|
|
152
|
+
metadata: serializeMetadata(sample.metadata),
|
|
153
|
+
sourceRevision: serializeSourceRevision(sample.sourceRevision)
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private func getECGVoltages(sample: HKElectrocardiogram) async throws -> [ElectrocardiogramVoltage] {
|
|
158
|
+
try await withCheckedThrowingContinuation { continuation in
|
|
159
|
+
var all: [ElectrocardiogramVoltage] = []
|
|
160
|
+
all.reserveCapacity(sample.numberOfVoltageMeasurements)
|
|
161
|
+
|
|
162
|
+
// Stream measurements
|
|
163
|
+
let q = HKElectrocardiogramQuery(sample) { _, result in
|
|
164
|
+
switch result {
|
|
165
|
+
case .error(let error):
|
|
166
|
+
continuation.resume(throwing: error)
|
|
167
|
+
|
|
168
|
+
case .measurement(let m):
|
|
169
|
+
// Lead I-like from Apple Watch
|
|
170
|
+
if let v = m.quantity(for: .appleWatchSimilarToLeadI)?.doubleValue(for: .volt()) {
|
|
171
|
+
let item = ElectrocardiogramVoltage(
|
|
172
|
+
timeSinceSampleStart: m.timeSinceSampleStart,
|
|
173
|
+
voltage: v,
|
|
174
|
+
lead: ElectrocardiogramLead(fromString: "appleWatchSimilarToLeadI")!
|
|
175
|
+
)
|
|
176
|
+
all.append(item)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
case .done:
|
|
180
|
+
continuation.resume(returning: all)
|
|
181
|
+
@unknown default:
|
|
182
|
+
continuation.resume(throwing: RuntimeError.error(withMessage: "HKElectrocardiogramQuery received unknown result type"))
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
store.execute(q)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// MARK: - Enum mappers
|
|
190
|
+
|
|
191
|
+
private func serializeClassification(_ classification: HKElectrocardiogram.Classification) -> ElectrocardiogramClassification {
|
|
192
|
+
switch classification {
|
|
193
|
+
case .notSet: return ElectrocardiogramClassification(fromString: "notSet")!
|
|
194
|
+
case .sinusRhythm: return ElectrocardiogramClassification(fromString: "sinusRhythm")!
|
|
195
|
+
case .atrialFibrillation: return ElectrocardiogramClassification(fromString: "atrialFibrillation")!
|
|
196
|
+
case .inconclusiveLowHeartRate: return ElectrocardiogramClassification(fromString: "inconclusiveLowHeartRate")!
|
|
197
|
+
case .inconclusiveHighHeartRate: return ElectrocardiogramClassification(fromString: "inconclusiveHighHeartRate")!
|
|
198
|
+
case .inconclusivePoorReading: return ElectrocardiogramClassification(fromString: "inconclusivePoorReading")!
|
|
199
|
+
case .inconclusiveOther: return ElectrocardiogramClassification(fromString: "inconclusiveOther")!
|
|
200
|
+
@unknown default: return ElectrocardiogramClassification(fromString: "inconclusiveOther")!
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private func serializeSymptomsStatus(_ symptoms: HKElectrocardiogram.SymptomsStatus) -> ElectrocardiogramSymptomsStatus {
|
|
205
|
+
switch symptoms {
|
|
206
|
+
case .notSet: return ElectrocardiogramSymptomsStatus(fromString: "notSet")!
|
|
207
|
+
case .none: return ElectrocardiogramSymptomsStatus(fromString: "none")!
|
|
208
|
+
case .present: return ElectrocardiogramSymptomsStatus(fromString: "present")!
|
|
209
|
+
@unknown default: return ElectrocardiogramSymptomsStatus(fromString: "notSet")!
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -49,6 +49,15 @@ func queryQuantitySamplesInternal(
|
|
|
49
49
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
func emptyStatisticsResponse(from: Date, to: Date) -> QueryStatisticsResponse {
|
|
53
|
+
var response = QueryStatisticsResponse()
|
|
54
|
+
|
|
55
|
+
response.startDate = from
|
|
56
|
+
response.endDate = to
|
|
57
|
+
|
|
58
|
+
return response
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
func serializeStatistics(gottenStats: HKStatistics, unit: HKUnit) -> QueryStatisticsResponse {
|
|
53
62
|
var response = QueryStatisticsResponse()
|
|
54
63
|
|
|
@@ -200,6 +209,26 @@ func buildStatisticsOptions(statistics: [StatisticsOptions]) -> HKStatisticsOpti
|
|
|
200
209
|
return opts
|
|
201
210
|
}
|
|
202
211
|
|
|
212
|
+
/// Handles HealthKit's `errorNoData` by resuming the continuation with a fallback value if provided,
|
|
213
|
+
/// otherwise resumes with `nil` for Optional result types. For other errors, resumes by throwing.
|
|
214
|
+
/// - Parameters:
|
|
215
|
+
/// - error: The error returned by HealthKit.
|
|
216
|
+
/// - continuation: The continuation to resume.
|
|
217
|
+
/// - noDataFallback: Optional closure producing a fallback value to use when the error is `errorNoData`.
|
|
218
|
+
func handleHKNoDataOrThrow<T>(
|
|
219
|
+
error: Error,
|
|
220
|
+
continuation: CheckedContinuation<T, Error>,
|
|
221
|
+
noDataFallback: (() -> T)
|
|
222
|
+
) {
|
|
223
|
+
let nsError = error as NSError
|
|
224
|
+
if nsError.domain == HKError.errorDomain,
|
|
225
|
+
nsError.code == HKError.Code.errorNoData.rawValue {
|
|
226
|
+
continuation.resume(returning: noDataFallback())
|
|
227
|
+
} else {
|
|
228
|
+
continuation.resume(throwing: error)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
203
232
|
class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
204
233
|
func deleteQuantitySamples(identifier: QuantityTypeIdentifier, filter: FilterForSamples) throws -> Promise<Bool> {
|
|
205
234
|
let sampleType = try initializeQuantityType(identifier.stringValue)
|
|
@@ -240,17 +269,17 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
240
269
|
) { (_, stats: HKStatistics?, error: Error?) in
|
|
241
270
|
DispatchQueue.main.async {
|
|
242
271
|
if let error = error {
|
|
243
|
-
|
|
244
|
-
|
|
272
|
+
return handleHKNoDataOrThrow(error: error, continuation: continuation) {
|
|
273
|
+
QueryStatisticsResponse()
|
|
274
|
+
}
|
|
245
275
|
}
|
|
246
276
|
|
|
247
277
|
guard let gottenStats = stats else {
|
|
248
278
|
let emptyResponse = QueryStatisticsResponse()
|
|
249
|
-
continuation.resume(returning: emptyResponse)
|
|
250
|
-
return
|
|
279
|
+
return continuation.resume(returning: emptyResponse)
|
|
251
280
|
}
|
|
252
281
|
|
|
253
|
-
|
|
282
|
+
let response = serializeStatistics(gottenStats: gottenStats, unit: unit)
|
|
254
283
|
|
|
255
284
|
continuation.resume(returning: response)
|
|
256
285
|
}
|
|
@@ -306,8 +335,9 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
306
335
|
|
|
307
336
|
query.initialResultsHandler = { (_, results: HKStatisticsCollection?, error: Error?) in
|
|
308
337
|
if let error = error {
|
|
309
|
-
|
|
310
|
-
|
|
338
|
+
return handleHKNoDataOrThrow(error: error, continuation: continuation) {
|
|
339
|
+
[]
|
|
340
|
+
}
|
|
311
341
|
}
|
|
312
342
|
|
|
313
343
|
guard let statistics = results else {
|
|
@@ -371,18 +401,25 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
371
401
|
error: Error?
|
|
372
402
|
) in
|
|
373
403
|
if let error = error {
|
|
374
|
-
|
|
375
|
-
|
|
404
|
+
return handleHKNoDataOrThrow(error: error, continuation: continuation) {
|
|
405
|
+
QuantitySamplesWithAnchorResponse(
|
|
406
|
+
samples: [],
|
|
407
|
+
deletedSamples: [],
|
|
408
|
+
newAnchor: ""
|
|
409
|
+
)
|
|
410
|
+
}
|
|
376
411
|
}
|
|
377
412
|
|
|
413
|
+
let deletedSamples = deletedSamples?.map { serializeDeletedSample(sample: $0) } ?? []
|
|
414
|
+
let newAnchor = serializeAnchor(anchor: newAnchor) ?? ""
|
|
415
|
+
|
|
378
416
|
guard let samples = samples else {
|
|
379
417
|
let response = QuantitySamplesWithAnchorResponse(
|
|
380
418
|
samples: [],
|
|
381
|
-
deletedSamples: deletedSamples
|
|
382
|
-
newAnchor:
|
|
419
|
+
deletedSamples: deletedSamples,
|
|
420
|
+
newAnchor: newAnchor
|
|
383
421
|
)
|
|
384
|
-
continuation.resume(returning: response)
|
|
385
|
-
return
|
|
422
|
+
return continuation.resume(returning: response)
|
|
386
423
|
}
|
|
387
424
|
|
|
388
425
|
let quantitySamples = samples.compactMap { sample in
|
|
@@ -401,8 +438,8 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
|
|
|
401
438
|
|
|
402
439
|
let response = QuantitySamplesWithAnchorResponse(
|
|
403
440
|
samples: quantitySamples,
|
|
404
|
-
deletedSamples: deletedSamples
|
|
405
|
-
newAnchor:
|
|
441
|
+
deletedSamples: deletedSamples,
|
|
442
|
+
newAnchor: newAnchor,
|
|
406
443
|
)
|
|
407
444
|
|
|
408
445
|
continuation.resume(returning: response)
|
|
@@ -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.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = void 0;
|
|
20
|
+
exports.saveStateOfMindSample = exports.queryStateOfMindSamples = exports.isProtectedDataAvailable = exports.startWatchApp = exports.subscribeToChanges = exports.saveWorkoutSample = exports.saveQuantitySample = exports.saveCorrelationSample = exports.saveCategorySample = exports.deleteObjects = exports.requestAuthorization = exports.querySources = exports.queryWorkoutSamplesWithAnchor = exports.queryWorkoutSamples = exports.queryStatisticsCollectionForQuantity = exports.queryStatisticsForQuantity = exports.queryQuantitySamplesWithAnchor = exports.queryQuantitySamples = exports.queryElectrocardiogramSamplesWithAnchor = exports.queryElectrocardiogramSamples = exports.queryHeartbeatSeriesSamplesWithAnchor = exports.queryHeartbeatSeriesSamples = 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.authorizationStatusFor = exports.useStatisticsForQuantity = exports.useSources = exports.useIsHealthDataAvailable = exports.useHealthkitAuthorization = exports.useSubscribeToChanges = exports.useMostRecentWorkout = exports.useMostRecentQuantitySample = exports.useMostRecentCategorySample = exports.getPreferredUnit = exports.getMostRecentWorkout = exports.getMostRecentQuantitySample = exports.getMostRecentCategorySample = void 0;
|
|
21
|
+
exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.unsubscribeQueries = exports.isQuantityCompatibleWithUnit = 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;
|
|
@@ -66,6 +66,8 @@ exports.queryCategorySamplesWithAnchor = modules_1.CategoryTypes.queryCategorySa
|
|
|
66
66
|
exports.queryCorrelationSamples = modules_1.CorrelationTypes.queryCorrelationSamples.bind(modules_1.CorrelationTypes);
|
|
67
67
|
exports.queryHeartbeatSeriesSamples = modules_1.HeartbeatSeries.queryHeartbeatSeriesSamples.bind(modules_1.HeartbeatSeries);
|
|
68
68
|
exports.queryHeartbeatSeriesSamplesWithAnchor = modules_1.HeartbeatSeries.queryHeartbeatSeriesSamplesWithAnchor.bind(modules_1.HeartbeatSeries);
|
|
69
|
+
exports.queryElectrocardiogramSamples = modules_1.Electrocardiograms.queryElectrocardiogramSamples.bind(modules_1.Electrocardiograms);
|
|
70
|
+
exports.queryElectrocardiogramSamplesWithAnchor = modules_1.Electrocardiograms.queryElectrocardiogramSamplesWithAnchor.bind(modules_1.Electrocardiograms);
|
|
69
71
|
exports.queryQuantitySamples = modules_1.QuantityTypes.queryQuantitySamples.bind(modules_1.QuantityTypes);
|
|
70
72
|
exports.queryQuantitySamplesWithAnchor = modules_1.QuantityTypes.queryQuantitySamplesWithAnchor.bind(modules_1.QuantityTypes);
|
|
71
73
|
exports.queryStatisticsForQuantity = modules_1.QuantityTypes.queryStatisticsForQuantity.bind(modules_1.QuantityTypes);
|
|
@@ -128,6 +130,8 @@ exports.default = {
|
|
|
128
130
|
queryCorrelationSamples: exports.queryCorrelationSamples,
|
|
129
131
|
queryHeartbeatSeriesSamples: exports.queryHeartbeatSeriesSamples,
|
|
130
132
|
queryHeartbeatSeriesSamplesWithAnchor: exports.queryHeartbeatSeriesSamplesWithAnchor,
|
|
133
|
+
queryElectrocardiogramSamples: exports.queryElectrocardiogramSamples,
|
|
134
|
+
queryElectrocardiogramSamplesWithAnchor: exports.queryElectrocardiogramSamplesWithAnchor,
|
|
131
135
|
queryQuantitySamples: exports.queryQuantitySamples,
|
|
132
136
|
queryQuantitySamplesWithAnchor: exports.queryQuantitySamplesWithAnchor,
|
|
133
137
|
queryStatisticsForQuantity: exports.queryStatisticsForQuantity,
|
|
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
exports.unsubscribeQueries = exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = void 0;
|
|
17
|
+
exports.useSources = exports.useIsHealthDataAvailable = exports.useHealthkitAuthorization = exports.useSubscribeToChanges = exports.useMostRecentWorkout = exports.useMostRecentQuantitySample = exports.getPreferredUnit = exports.getMostRecentWorkout = exports.getMostRecentQuantitySample = exports.saveStateOfMindSample = exports.queryStateOfMindSamples = exports.startWatchApp = exports.saveWorkoutSample = exports.queryWorkoutSamplesWithAnchor = exports.queryWorkoutSamples = exports.queryElectrocardiogramSamplesWithAnchor = exports.queryElectrocardiogramSamples = exports.queryHeartbeatSeriesSamplesWithAnchor = exports.queryHeartbeatSeriesSamples = exports.saveCorrelationSample = exports.queryCorrelationSamples = exports.saveCategorySample = exports.isQuantityCompatibleWithUnit = exports.saveQuantitySample = exports.queryStatisticsCollectionForQuantity = exports.queryStatisticsForQuantity = exports.queryQuantitySamplesWithAnchor = exports.queryQuantitySamples = exports.getWheelchairUse = exports.getFitzpatrickSkinType = exports.getDateOfBirth = exports.getBloodType = exports.getBiologicalSex = exports.areObjectTypesAvailableAsync = exports.areObjectTypesAvailable = exports.isObjectTypeAvailableAsync = exports.isObjectTypeAvailable = exports.isProtectedDataAvailable = exports.subscribeToChanges = exports.deleteObjects = exports.requestAuthorization = exports.querySources = exports.isHealthDataAvailableAsync = exports.isHealthDataAvailable = exports.getRequestStatusForAuthorization = exports.getPreferredUnits = exports.enableBackgroundDelivery = exports.disableBackgroundDelivery = exports.disableAllBackgroundDelivery = exports.authorizationStatusFor = void 0;
|
|
18
|
+
exports.unsubscribeQueries = exports.getWheelchairUseAsync = exports.getFitzpatrickSkinTypeAsync = exports.getDateOfBirthAsync = exports.getBloodTypeAsync = exports.getBiologicalSexAsync = exports.useStatisticsForQuantity = void 0;
|
|
19
19
|
exports.queryCategorySamples = queryCategorySamples;
|
|
20
20
|
exports.queryCategorySamplesWithAnchor = queryCategorySamplesWithAnchor;
|
|
21
21
|
exports.getMostRecentCategorySample = getMostRecentCategorySample;
|
|
@@ -103,6 +103,12 @@ exports.queryHeartbeatSeriesSamplesWithAnchor = UnavailableFnFromModule('queryHe
|
|
|
103
103
|
deletedSamples: [],
|
|
104
104
|
newAnchor: '',
|
|
105
105
|
}));
|
|
106
|
+
exports.queryElectrocardiogramSamples = UnavailableFnFromModule('queryElectrocardiogramSamples', Promise.resolve([]));
|
|
107
|
+
exports.queryElectrocardiogramSamplesWithAnchor = UnavailableFnFromModule('queryElectrocardiogramSamplesWithAnchor', Promise.resolve({
|
|
108
|
+
samples: [],
|
|
109
|
+
deletedSamples: [],
|
|
110
|
+
newAnchor: '',
|
|
111
|
+
}));
|
|
106
112
|
// WorkoutsModule functions
|
|
107
113
|
exports.queryWorkoutSamples = UnavailableFnFromModule('queryWorkoutSamples', Promise.resolve([]));
|
|
108
114
|
exports.queryWorkoutSamplesWithAnchor = UnavailableFnFromModule('queryWorkoutSamplesWithAnchor', Promise.resolve({
|
|
@@ -188,6 +194,8 @@ const HealthkitModule = {
|
|
|
188
194
|
queryCorrelationSamples: exports.queryCorrelationSamples,
|
|
189
195
|
queryHeartbeatSeriesSamples: exports.queryHeartbeatSeriesSamples,
|
|
190
196
|
queryHeartbeatSeriesSamplesWithAnchor: exports.queryHeartbeatSeriesSamplesWithAnchor,
|
|
197
|
+
queryElectrocardiogramSamples: exports.queryElectrocardiogramSamples,
|
|
198
|
+
queryElectrocardiogramSamplesWithAnchor: exports.queryElectrocardiogramSamplesWithAnchor,
|
|
191
199
|
queryQuantitySamples: exports.queryQuantitySamples,
|
|
192
200
|
queryQuantitySamplesWithAnchor: exports.queryQuantitySamplesWithAnchor,
|
|
193
201
|
queryStatisticsForQuantity: exports.queryStatisticsForQuantity,
|
package/lib/commonjs/modules.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StateOfMind = exports.HeartbeatSeries = exports.CorrelationTypes = exports.CategoryTypes = exports.QuantityTypes = exports.Characteristics = exports.Workouts = exports.Core = void 0;
|
|
3
|
+
exports.StateOfMind = exports.HeartbeatSeries = exports.Electrocardiograms = exports.CorrelationTypes = exports.CategoryTypes = exports.QuantityTypes = exports.Characteristics = exports.Workouts = exports.Core = void 0;
|
|
4
4
|
const react_native_nitro_modules_1 = require("react-native-nitro-modules");
|
|
5
5
|
exports.Core = react_native_nitro_modules_1.NitroModules.createHybridObject('CoreModule');
|
|
6
6
|
exports.Workouts = react_native_nitro_modules_1.NitroModules.createHybridObject('WorkoutsModule');
|
|
@@ -8,5 +8,6 @@ exports.Characteristics = react_native_nitro_modules_1.NitroModules.createHybrid
|
|
|
8
8
|
exports.QuantityTypes = react_native_nitro_modules_1.NitroModules.createHybridObject('QuantityTypeModule');
|
|
9
9
|
exports.CategoryTypes = react_native_nitro_modules_1.NitroModules.createHybridObject('CategoryTypeModule');
|
|
10
10
|
exports.CorrelationTypes = react_native_nitro_modules_1.NitroModules.createHybridObject('CorrelationTypeModule');
|
|
11
|
+
exports.Electrocardiograms = react_native_nitro_modules_1.NitroModules.createHybridObject('ElectrocardiogramModule');
|
|
11
12
|
exports.HeartbeatSeries = react_native_nitro_modules_1.NitroModules.createHybridObject('HeartbeatSeriesModule');
|
|
12
13
|
exports.StateOfMind = react_native_nitro_modules_1.NitroModules.createHybridObject('StateOfMindModule');
|
|
@@ -7,7 +7,7 @@ import useMostRecentWorkout from './hooks/useMostRecentWorkout';
|
|
|
7
7
|
import useSources from './hooks/useSources';
|
|
8
8
|
import useStatisticsForQuantity from './hooks/useStatisticsForQuantity';
|
|
9
9
|
import useSubscribeToChanges from './hooks/useSubscribeToChanges';
|
|
10
|
-
import { CategoryTypes, Characteristics, Core, CorrelationTypes, HeartbeatSeries, QuantityTypes, StateOfMind, Workouts, } from './modules';
|
|
10
|
+
import { CategoryTypes, Characteristics, Core, CorrelationTypes, Electrocardiograms, HeartbeatSeries, QuantityTypes, StateOfMind, Workouts, } from './modules';
|
|
11
11
|
import getMostRecentCategorySample from './utils/getMostRecentCategorySample';
|
|
12
12
|
import getMostRecentQuantitySample from './utils/getMostRecentQuantitySample';
|
|
13
13
|
import getMostRecentWorkout from './utils/getMostRecentWorkout';
|
|
@@ -34,6 +34,8 @@ export const queryCategorySamplesWithAnchor = CategoryTypes.queryCategorySamples
|
|
|
34
34
|
export const queryCorrelationSamples = CorrelationTypes.queryCorrelationSamples.bind(CorrelationTypes);
|
|
35
35
|
export const queryHeartbeatSeriesSamples = HeartbeatSeries.queryHeartbeatSeriesSamples.bind(HeartbeatSeries);
|
|
36
36
|
export const queryHeartbeatSeriesSamplesWithAnchor = HeartbeatSeries.queryHeartbeatSeriesSamplesWithAnchor.bind(HeartbeatSeries);
|
|
37
|
+
export const queryElectrocardiogramSamples = Electrocardiograms.queryElectrocardiogramSamples.bind(Electrocardiograms);
|
|
38
|
+
export const queryElectrocardiogramSamplesWithAnchor = Electrocardiograms.queryElectrocardiogramSamplesWithAnchor.bind(Electrocardiograms);
|
|
37
39
|
export const queryQuantitySamples = QuantityTypes.queryQuantitySamples.bind(QuantityTypes);
|
|
38
40
|
export const queryQuantitySamplesWithAnchor = QuantityTypes.queryQuantitySamplesWithAnchor.bind(QuantityTypes);
|
|
39
41
|
export const queryStatisticsForQuantity = QuantityTypes.queryStatisticsForQuantity.bind(QuantityTypes);
|
|
@@ -96,6 +98,8 @@ export default {
|
|
|
96
98
|
queryCorrelationSamples,
|
|
97
99
|
queryHeartbeatSeriesSamples,
|
|
98
100
|
queryHeartbeatSeriesSamplesWithAnchor,
|
|
101
|
+
queryElectrocardiogramSamples,
|
|
102
|
+
queryElectrocardiogramSamplesWithAnchor,
|
|
99
103
|
queryQuantitySamples,
|
|
100
104
|
queryQuantitySamplesWithAnchor,
|
|
101
105
|
queryStatisticsForQuantity,
|
package/lib/module/healthkit.js
CHANGED
|
@@ -81,6 +81,12 @@ export const queryHeartbeatSeriesSamplesWithAnchor = UnavailableFnFromModule('qu
|
|
|
81
81
|
deletedSamples: [],
|
|
82
82
|
newAnchor: '',
|
|
83
83
|
}));
|
|
84
|
+
export const queryElectrocardiogramSamples = UnavailableFnFromModule('queryElectrocardiogramSamples', Promise.resolve([]));
|
|
85
|
+
export const queryElectrocardiogramSamplesWithAnchor = UnavailableFnFromModule('queryElectrocardiogramSamplesWithAnchor', Promise.resolve({
|
|
86
|
+
samples: [],
|
|
87
|
+
deletedSamples: [],
|
|
88
|
+
newAnchor: '',
|
|
89
|
+
}));
|
|
84
90
|
// WorkoutsModule functions
|
|
85
91
|
export const queryWorkoutSamples = UnavailableFnFromModule('queryWorkoutSamples', Promise.resolve([]));
|
|
86
92
|
export const queryWorkoutSamplesWithAnchor = UnavailableFnFromModule('queryWorkoutSamplesWithAnchor', Promise.resolve({
|
|
@@ -166,6 +172,8 @@ const HealthkitModule = {
|
|
|
166
172
|
queryCorrelationSamples,
|
|
167
173
|
queryHeartbeatSeriesSamples,
|
|
168
174
|
queryHeartbeatSeriesSamplesWithAnchor,
|
|
175
|
+
queryElectrocardiogramSamples,
|
|
176
|
+
queryElectrocardiogramSamplesWithAnchor,
|
|
169
177
|
queryQuantitySamples,
|
|
170
178
|
queryQuantitySamplesWithAnchor,
|
|
171
179
|
queryStatisticsForQuantity,
|
package/lib/module/modules.js
CHANGED
|
@@ -5,5 +5,6 @@ export const Characteristics = NitroModules.createHybridObject('CharacteristicTy
|
|
|
5
5
|
export const QuantityTypes = NitroModules.createHybridObject('QuantityTypeModule');
|
|
6
6
|
export const CategoryTypes = NitroModules.createHybridObject('CategoryTypeModule');
|
|
7
7
|
export const CorrelationTypes = NitroModules.createHybridObject('CorrelationTypeModule');
|
|
8
|
+
export const Electrocardiograms = NitroModules.createHybridObject('ElectrocardiogramModule');
|
|
8
9
|
export const HeartbeatSeries = NitroModules.createHybridObject('HeartbeatSeriesModule');
|
|
9
10
|
export const StateOfMind = NitroModules.createHybridObject('StateOfMindModule');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -42,6 +42,8 @@ export declare const queryCorrelationSamples: (typeIdentifier: import("./types")
|
|
|
42
42
|
export declare const saveCorrelationSample: (typeIdentifier: import("./types").CorrelationTypeIdentifier, samples: import("./types").SampleForSaving[], start: Date, end: Date, metadata: import("react-native-nitro-modules").AnyMap) => Promise<boolean>;
|
|
43
43
|
export declare const queryHeartbeatSeriesSamples: (options?: QueryOptionsWithSortOrder) => Promise<readonly import("./types").HeartbeatSeriesSample[]>;
|
|
44
44
|
export declare const queryHeartbeatSeriesSamplesWithAnchor: (options: QueryOptionsWithAnchor) => Promise<import("./types").HeartbeatSeriesSamplesWithAnchorResponse>;
|
|
45
|
+
export declare const queryElectrocardiogramSamples: (options?: import("./types/ElectrocardiogramSample").ECGQueryOptionsWithSortOrder) => Promise<readonly import("./types/ElectrocardiogramSample").ElectrocardiogramSample[]>;
|
|
46
|
+
export declare const queryElectrocardiogramSamplesWithAnchor: (options: import("./types/ElectrocardiogramSample").ECGQueryOptionsWithAnchor) => Promise<import("./types/ElectrocardiogramSample").ElectrocardiogramSamplesWithAnchorResponse>;
|
|
45
47
|
export declare const queryWorkoutSamples: (options: import("./types").WorkoutQueryOptions) => Promise<WorkoutProxy[]>;
|
|
46
48
|
export declare const queryWorkoutSamplesWithAnchor: (options: import("./types").WorkoutQueryOptionsWithAnchor) => Promise<import("./types").QueryWorkoutSamplesWithAnchorResponse>;
|
|
47
49
|
export declare const saveWorkoutSample: (workoutActivityType: import("./types").WorkoutActivityType, quantities: readonly import("./types").QuantitySampleForSaving[], startDate: Date, endDate: Date, totals: import("./types").WorkoutTotals, metadata: import("react-native-nitro-modules").AnyMap) => Promise<WorkoutProxy>;
|
|
@@ -50,6 +50,8 @@ export declare const queryCategorySamplesWithAnchor: <T extends import("./types"
|
|
|
50
50
|
export declare const queryCorrelationSamples: (typeIdentifier: import("./types").CorrelationTypeIdentifier, from: Date, to: Date) => Promise<readonly import("./types").CorrelationSample[]>;
|
|
51
51
|
export declare const queryHeartbeatSeriesSamples: (options?: import("./types").QueryOptionsWithSortOrder) => Promise<readonly import("./types").HeartbeatSeriesSample[]>;
|
|
52
52
|
export declare const queryHeartbeatSeriesSamplesWithAnchor: (options: import("./types").QueryOptionsWithAnchor) => Promise<import("./types").HeartbeatSeriesSamplesWithAnchorResponse>;
|
|
53
|
+
export declare const queryElectrocardiogramSamples: (options?: import("./types/ElectrocardiogramSample").ECGQueryOptionsWithSortOrder) => Promise<readonly import("./types/ElectrocardiogramSample").ElectrocardiogramSample[]>;
|
|
54
|
+
export declare const queryElectrocardiogramSamplesWithAnchor: (options: import("./types/ElectrocardiogramSample").ECGQueryOptionsWithAnchor) => Promise<import("./types/ElectrocardiogramSample").ElectrocardiogramSamplesWithAnchorResponse>;
|
|
53
55
|
export declare const queryQuantitySamples: (identifier: QuantityTypeIdentifier, options?: import("./types").QueryOptionsWithSortOrderAndUnit) => Promise<readonly import("./types").QuantitySample[]>;
|
|
54
56
|
export declare const queryQuantitySamplesWithAnchor: (identifier: QuantityTypeIdentifier, options: import("./types").QueryOptionsWithAnchorAndUnit) => Promise<import("./types").QuantitySamplesWithAnchorResponse>;
|
|
55
57
|
export declare const queryStatisticsForQuantity: (identifier: QuantityTypeIdentifier, statistics: readonly import("./types").StatisticsOptions[], options?: import("./types").StatisticsQueryOptions) => Promise<import("./types").QueryStatisticsResponse>;
|
|
@@ -112,6 +114,8 @@ declare const _default: {
|
|
|
112
114
|
queryCorrelationSamples: (typeIdentifier: import("./types").CorrelationTypeIdentifier, from: Date, to: Date) => Promise<readonly import("./types").CorrelationSample[]>;
|
|
113
115
|
queryHeartbeatSeriesSamples: (options?: import("./types").QueryOptionsWithSortOrder) => Promise<readonly import("./types").HeartbeatSeriesSample[]>;
|
|
114
116
|
queryHeartbeatSeriesSamplesWithAnchor: (options: import("./types").QueryOptionsWithAnchor) => Promise<import("./types").HeartbeatSeriesSamplesWithAnchorResponse>;
|
|
117
|
+
queryElectrocardiogramSamples: (options?: import("./types/ElectrocardiogramSample").ECGQueryOptionsWithSortOrder) => Promise<readonly import("./types/ElectrocardiogramSample").ElectrocardiogramSample[]>;
|
|
118
|
+
queryElectrocardiogramSamplesWithAnchor: (options: import("./types/ElectrocardiogramSample").ECGQueryOptionsWithAnchor) => Promise<import("./types/ElectrocardiogramSample").ElectrocardiogramSamplesWithAnchorResponse>;
|
|
115
119
|
queryQuantitySamples: (identifier: QuantityTypeIdentifier, options?: import("./types").QueryOptionsWithSortOrderAndUnit) => Promise<readonly import("./types").QuantitySample[]>;
|
|
116
120
|
queryQuantitySamplesWithAnchor: (identifier: QuantityTypeIdentifier, options: import("./types").QueryOptionsWithAnchorAndUnit) => Promise<import("./types").QuantitySamplesWithAnchorResponse>;
|
|
117
121
|
queryStatisticsForQuantity: (identifier: QuantityTypeIdentifier, statistics: readonly import("./types").StatisticsOptions[], options?: import("./types").StatisticsQueryOptions) => Promise<import("./types").QueryStatisticsResponse>;
|
|
@@ -2,6 +2,7 @@ import type { CategoryTypeModuleTyped } from './specs/CategoryTypeModule.nitro';
|
|
|
2
2
|
import type { CharacteristicTypeModule } from './specs/CharacteristicTypeModule.nitro';
|
|
3
3
|
import type { CoreModule } from './specs/CoreModule.nitro';
|
|
4
4
|
import type { CorrelationTypeModule } from './specs/CorrelationTypeModule.nitro';
|
|
5
|
+
import type { ElectrocardiogramModule } from './specs/ElectrocardiogramModule.nitro';
|
|
5
6
|
import type { HeartbeatSeriesModule } from './specs/HeartbeatSeriesModule.nitro';
|
|
6
7
|
import type { QuantityTypeModule } from './specs/QuantityTypeModule.nitro';
|
|
7
8
|
import type { StateOfMindModule } from './specs/StateOfMindModule.nitro';
|
|
@@ -12,5 +13,6 @@ export declare const Characteristics: CharacteristicTypeModule;
|
|
|
12
13
|
export declare const QuantityTypes: QuantityTypeModule;
|
|
13
14
|
export declare const CategoryTypes: CategoryTypeModuleTyped;
|
|
14
15
|
export declare const CorrelationTypes: CorrelationTypeModule;
|
|
16
|
+
export declare const Electrocardiograms: ElectrocardiogramModule;
|
|
15
17
|
export declare const HeartbeatSeries: HeartbeatSeriesModule;
|
|
16
18
|
export declare const StateOfMind: StateOfMindModule;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
import type { ECGQueryOptionsWithAnchor, ECGQueryOptionsWithSortOrder, ElectrocardiogramSample, ElectrocardiogramSamplesWithAnchorResponse } from '../types/ElectrocardiogramSample';
|
|
3
|
+
export interface ElectrocardiogramModule extends HybridObject<{
|
|
4
|
+
ios: 'swift';
|
|
5
|
+
}> {
|
|
6
|
+
queryElectrocardiogramSamples(options?: ECGQueryOptionsWithSortOrder): Promise<readonly ElectrocardiogramSample[]>;
|
|
7
|
+
queryElectrocardiogramSamplesWithAnchor(options: ECGQueryOptionsWithAnchor): Promise<ElectrocardiogramSamplesWithAnchorResponse>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AnyMap } from 'react-native-nitro-modules';
|
|
2
|
+
import type { QueryOptionsWithAnchor, QueryOptionsWithSortOrder } from '../types/QueryOptions';
|
|
3
|
+
import type { Device } from './Device';
|
|
4
|
+
import type { DeletedSample } from './Shared';
|
|
5
|
+
import type { SourceRevision } from './Source';
|
|
6
|
+
export type ElectrocardiogramClassification = 'notSet' | 'sinusRhythm' | 'atrialFibrillation' | 'inconclusiveLowHeartRate' | 'inconclusiveHighHeartRate' | 'inconclusivePoorReading' | 'inconclusiveOther';
|
|
7
|
+
export type ElectrocardiogramSymptomsStatus = 'notSet' | 'none' | 'present';
|
|
8
|
+
export type ElectrocardiogramLead = 'appleWatchSimilarToLeadI' | 'unknown';
|
|
9
|
+
export interface ElectrocardiogramVoltage {
|
|
10
|
+
readonly timeSinceSampleStart: number;
|
|
11
|
+
readonly voltage: number;
|
|
12
|
+
readonly lead: ElectrocardiogramLead;
|
|
13
|
+
}
|
|
14
|
+
export interface ElectrocardiogramSample {
|
|
15
|
+
readonly uuid: string;
|
|
16
|
+
readonly device?: Device;
|
|
17
|
+
readonly startDate: Date;
|
|
18
|
+
readonly endDate: Date;
|
|
19
|
+
readonly classification: ElectrocardiogramClassification;
|
|
20
|
+
readonly symptomsStatus: ElectrocardiogramSymptomsStatus;
|
|
21
|
+
readonly averageHeartRateBpm?: number;
|
|
22
|
+
readonly samplingFrequencyHz?: number;
|
|
23
|
+
readonly numberOfVoltageMeasurements: number;
|
|
24
|
+
readonly algorithmVersion?: string;
|
|
25
|
+
readonly voltages?: readonly ElectrocardiogramVoltage[];
|
|
26
|
+
readonly metadata?: AnyMap;
|
|
27
|
+
readonly sourceRevision?: SourceRevision;
|
|
28
|
+
}
|
|
29
|
+
export interface ElectrocardiogramSamplesWithAnchorResponse {
|
|
30
|
+
readonly samples: readonly ElectrocardiogramSample[];
|
|
31
|
+
readonly deletedSamples: readonly DeletedSample[];
|
|
32
|
+
readonly newAnchor: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ECGQueryOptionsWithSortOrder extends QueryOptionsWithSortOrder {
|
|
35
|
+
readonly includeVoltages?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface ECGQueryOptionsWithAnchor extends QueryOptionsWithAnchor {
|
|
38
|
+
readonly includeVoltages: boolean;
|
|
39
|
+
}
|