@kingstinct/react-native-healthkit 13.3.1 → 14.0.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.
Files changed (191) hide show
  1. package/ReactNativeHealthkit.podspec +1 -0
  2. package/app.plugin.ts +40 -2
  3. package/ios/BackgroundDeliveryManager.swift +196 -0
  4. package/ios/CategoryTypeModule.swift +1 -1
  5. package/ios/CoreModule.swift +24 -0
  6. package/ios/CorrelationTypeModule.swift +2 -35
  7. package/ios/ElectrocardiogramModule.swift +2 -34
  8. package/ios/HeartbeatSeriesModule.swift +2 -34
  9. package/ios/MedicationModule.swift +3 -35
  10. package/ios/PredicateHelpers.swift +2 -2
  11. package/ios/QuantityTypeModule.swift +11 -11
  12. package/ios/Serializers.swift +58 -90
  13. package/ios/StateOfMindModule.swift +2 -34
  14. package/ios/WorkoutProxy.swift +4 -149
  15. package/ios/generated/HealthkitGenerated.swift +52 -0
  16. package/lib/commonjs/generated/healthkit.generated.js +745 -0
  17. package/lib/commonjs/healthkit.ios.js +51 -17
  18. package/lib/commonjs/healthkit.js +120 -34
  19. package/lib/commonjs/specs/QuantityTypeModule.nitro.js +1 -0
  20. package/lib/commonjs/type-tests/generated-typing.js +2 -0
  21. package/lib/commonjs/types/CategoryType.js +19 -99
  22. package/lib/commonjs/types/Medication.js +2 -0
  23. package/lib/commonjs/types/MetadataEnums.js +17 -0
  24. package/lib/commonjs/types/QuantityType.js +4 -15
  25. package/lib/commonjs/types/WeatherCondition.js +2 -32
  26. package/lib/commonjs/types/Workouts.js +3 -98
  27. package/lib/commonjs/types/index.js +2 -0
  28. package/lib/module/generated/healthkit.generated.js +742 -0
  29. package/lib/module/healthkit.ios.js +49 -15
  30. package/lib/module/healthkit.js +94 -20
  31. package/lib/module/specs/QuantityTypeModule.nitro.js +1 -0
  32. package/lib/module/type-tests/generated-typing.js +1 -0
  33. package/lib/module/types/CategoryType.js +2 -98
  34. package/lib/module/types/Medication.js +1 -0
  35. package/lib/module/types/MetadataEnums.js +1 -0
  36. package/lib/module/types/QuantityType.js +2 -14
  37. package/lib/module/types/WeatherCondition.js +1 -32
  38. package/lib/module/types/Workouts.js +2 -98
  39. package/lib/module/types/index.js +2 -0
  40. package/lib/typescript/generated/healthkit.generated.d.ts +1006 -0
  41. package/lib/typescript/healthkit.d.ts +39 -36
  42. package/lib/typescript/healthkit.ios.d.ts +64 -53
  43. package/lib/typescript/hooks/useMostRecentQuantitySample.d.ts +3 -2
  44. package/lib/typescript/hooks/useMostRecentWorkout.d.ts +2 -2
  45. package/lib/typescript/hooks/useQuantitySampleById.d.ts +5 -4
  46. package/lib/typescript/hooks/useStatisticsForQuantity.d.ts +2 -2
  47. package/lib/typescript/hooks/useSubscribeToQuantitySamples.d.ts +1 -1
  48. package/lib/typescript/modules.d.ts +2 -2
  49. package/lib/typescript/specs/CategoryTypeModule.nitro.d.ts +3 -3
  50. package/lib/typescript/specs/CoreModule.nitro.d.ts +15 -0
  51. package/lib/typescript/specs/QuantityTypeModule.nitro.d.ts +20 -9
  52. package/lib/typescript/type-tests/generated-typing.d.ts +1 -0
  53. package/lib/typescript/types/CategoryType.d.ts +10 -104
  54. package/lib/typescript/types/CategoryTypeIdentifier.d.ts +1 -61
  55. package/lib/typescript/types/CorrelationType.d.ts +8 -2
  56. package/lib/typescript/types/ElectrocardiogramSample.d.ts +8 -1
  57. package/lib/typescript/types/HeartbeatSeries.d.ts +8 -1
  58. package/lib/typescript/types/InterfaceVerification.d.ts +14 -1
  59. package/lib/typescript/types/Medication.d.ts +10 -0
  60. package/lib/typescript/types/MetadataEnums.d.ts +1 -0
  61. package/lib/typescript/types/QuantitySample.d.ts +9 -1
  62. package/lib/typescript/types/QuantityType.d.ts +14 -18
  63. package/lib/typescript/types/QuantityTypeIdentifier.d.ts +1 -671
  64. package/lib/typescript/types/QueryOptions.d.ts +8 -4
  65. package/lib/typescript/types/Shared.d.ts +12 -41
  66. package/lib/typescript/types/StateOfMind.d.ts +8 -1
  67. package/lib/typescript/types/Subscriptions.d.ts +11 -11
  68. package/lib/typescript/types/WeatherCondition.d.ts +1 -30
  69. package/lib/typescript/types/Workouts.d.ts +20 -104
  70. package/lib/typescript/types/index.d.ts +2 -0
  71. package/lib/typescript/utils/getMostRecentQuantitySample.d.ts +2 -1
  72. package/lib/typescript/utils/getMostRecentWorkout.d.ts +2 -1
  73. package/lib/typescript/utils/getPreferredUnit.d.ts +2 -1
  74. package/lib/typescript/utils/getQuantitySampleById.d.ts +2 -1
  75. package/lib/typescript/utils/subscribeToQuantitySamples.d.ts +1 -1
  76. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +55 -109
  77. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +12 -18
  78. package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +5 -14
  79. package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +18 -2
  80. package/nitrogen/generated/ios/c++/HybridCorrelationTypeModuleSpecSwift.hpp +1 -13
  81. package/nitrogen/generated/ios/c++/HybridElectrocardiogramModuleSpecSwift.hpp +1 -13
  82. package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +2 -14
  83. package/nitrogen/generated/ios/c++/HybridMedicationModuleSpecSwift.hpp +1 -13
  84. package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +19 -28
  85. package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +2 -14
  86. package/nitrogen/generated/ios/c++/HybridWorkoutProxySpecSwift.hpp +3 -116
  87. package/nitrogen/generated/ios/swift/CategorySample.swift +4 -329
  88. package/nitrogen/generated/ios/swift/CategoryTypeIdentifier.swift +112 -108
  89. package/nitrogen/generated/ios/swift/CategoryTypeIdentifierWriteable.swift +292 -0
  90. package/nitrogen/generated/ios/swift/CorrelationSample.swift +4 -347
  91. package/nitrogen/generated/ios/swift/ElectrocardiogramSample.swift +4 -329
  92. package/nitrogen/generated/ios/swift/FilterForWorkouts.swift +30 -30
  93. package/nitrogen/generated/ios/swift/FilterForWorkoutsBase.swift +30 -30
  94. package/nitrogen/generated/ios/swift/GeneralForm.swift +4 -4
  95. package/nitrogen/generated/ios/swift/HeartbeatSeriesSample.swift +4 -329
  96. package/nitrogen/generated/ios/swift/HybridCategoryTypeModuleSpec.swift +1 -1
  97. package/nitrogen/generated/ios/swift/HybridCategoryTypeModuleSpec_cxx.swift +1 -1
  98. package/nitrogen/generated/ios/swift/HybridCoreModuleSpec.swift +2 -0
  99. package/nitrogen/generated/ios/swift/HybridCoreModuleSpec_cxx.swift +38 -0
  100. package/nitrogen/generated/ios/swift/HybridQuantityTypeModuleSpec.swift +6 -6
  101. package/nitrogen/generated/ios/swift/HybridQuantityTypeModuleSpec_cxx.swift +6 -6
  102. package/nitrogen/generated/ios/swift/HybridWorkoutProxySpec.swift +1 -27
  103. package/nitrogen/generated/ios/swift/HybridWorkoutProxySpec_cxx.swift +2 -340
  104. package/nitrogen/generated/ios/swift/MedicationDoseEvent.swift +4 -329
  105. package/nitrogen/generated/ios/swift/ObjectTypeIdentifier.swift +492 -492
  106. package/nitrogen/generated/ios/swift/QuantitySample.swift +4 -329
  107. package/nitrogen/generated/ios/swift/QuantityTypeIdentifier.swift +380 -384
  108. package/nitrogen/generated/ios/swift/QuantityTypeIdentifierWriteable.swift +372 -376
  109. package/nitrogen/generated/ios/swift/{QueryOptionsWithAnchorAndUnit.swift → QueryOptionsWithAnchorAndStringUnit.swift} +5 -5
  110. package/nitrogen/generated/ios/swift/{QueryOptionsWithSortOrderAndUnit.swift → QueryOptionsWithSortOrderAndStringUnit.swift} +5 -5
  111. package/nitrogen/generated/ios/swift/QueryStatisticsResponseFromSingleSource.swift +37 -37
  112. package/nitrogen/generated/ios/swift/SampleTypeIdentifier.swift +492 -492
  113. package/nitrogen/generated/ios/swift/SampleTypeIdentifierWriteable.swift +482 -486
  114. package/nitrogen/generated/ios/swift/StateOfMindSample.swift +4 -329
  115. package/nitrogen/generated/ios/swift/{StatisticsQueryOptions.swift → StatisticsQueryOptionsWithStringUnit.swift} +5 -5
  116. package/nitrogen/generated/ios/swift/WorkoutEvent.swift +20 -2
  117. package/nitrogen/generated/ios/swift/WorkoutSample.swift +4 -402
  118. package/nitrogen/generated/shared/c++/CategorySample.hpp +8 -100
  119. package/nitrogen/generated/shared/c++/CategoryTypeIdentifier.hpp +153 -149
  120. package/nitrogen/generated/shared/c++/CategoryTypeIdentifierWriteable.hpp +328 -0
  121. package/nitrogen/generated/shared/c++/CorrelationSample.hpp +9 -105
  122. package/nitrogen/generated/shared/c++/ElectrocardiogramSample.hpp +7 -99
  123. package/nitrogen/generated/shared/c++/FilterForWorkouts.hpp +13 -13
  124. package/nitrogen/generated/shared/c++/FilterForWorkoutsBase.hpp +13 -13
  125. package/nitrogen/generated/shared/c++/GeneralForm.hpp +7 -7
  126. package/nitrogen/generated/shared/c++/HeartbeatSeriesSample.hpp +8 -100
  127. package/nitrogen/generated/shared/c++/HybridCategoryTypeModuleSpec.hpp +5 -2
  128. package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.cpp +2 -0
  129. package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.hpp +4 -2
  130. package/nitrogen/generated/shared/c++/HybridQuantityTypeModuleSpec.hpp +15 -15
  131. package/nitrogen/generated/shared/c++/HybridWorkoutProxySpec.cpp +1 -27
  132. package/nitrogen/generated/shared/c++/HybridWorkoutProxySpec.hpp +2 -37
  133. package/nitrogen/generated/shared/c++/MedicationDoseEvent.hpp +7 -99
  134. package/nitrogen/generated/shared/c++/ObjectTypeIdentifier.hpp +565 -565
  135. package/nitrogen/generated/shared/c++/QuantitySample.hpp +8 -100
  136. package/nitrogen/generated/shared/c++/QuantityTypeIdentifier.hpp +407 -411
  137. package/nitrogen/generated/shared/c++/QuantityTypeIdentifierWriteable.hpp +398 -402
  138. package/nitrogen/generated/shared/c++/{QueryOptionsWithAnchorAndUnit.hpp → QueryOptionsWithAnchorAndStringUnit.hpp} +11 -11
  139. package/nitrogen/generated/shared/c++/{QueryOptionsWithSortOrderAndUnit.hpp → QueryOptionsWithSortOrderAndStringUnit.hpp} +11 -11
  140. package/nitrogen/generated/shared/c++/QueryStatisticsResponseFromSingleSource.hpp +12 -12
  141. package/nitrogen/generated/shared/c++/SampleTypeIdentifier.hpp +559 -559
  142. package/nitrogen/generated/shared/c++/SampleTypeIdentifierWriteable.hpp +541 -545
  143. package/nitrogen/generated/shared/c++/StateOfMindSample.hpp +8 -100
  144. package/nitrogen/generated/shared/c++/{StatisticsQueryOptions.hpp → StatisticsQueryOptionsWithStringUnit.hpp} +11 -11
  145. package/nitrogen/generated/shared/c++/WorkoutEvent.hpp +8 -2
  146. package/nitrogen/generated/shared/c++/WorkoutSample.hpp +7 -120
  147. package/package.json +5 -2
  148. package/src/generated/healthkit-schema.json +3680 -0
  149. package/src/generated/healthkit.generated.ts +1307 -0
  150. package/src/healthkit.ios.ts +225 -19
  151. package/src/healthkit.ts +181 -55
  152. package/src/hooks/useMostRecentQuantitySample.ts +6 -5
  153. package/src/hooks/useMostRecentWorkout.ts +2 -2
  154. package/src/hooks/useQuantitySampleById.ts +6 -5
  155. package/src/hooks/useStatisticsForQuantity.ts +2 -1
  156. package/src/hooks/useSubscribeToQuantitySamples.ts +1 -1
  157. package/src/modules.ts +7 -2
  158. package/src/specs/CategoryTypeModule.nitro.ts +8 -5
  159. package/src/specs/CoreModule.nitro.ts +20 -0
  160. package/src/specs/QuantityTypeModule.nitro.ts +81 -7
  161. package/src/test-setup.ts +2 -0
  162. package/src/type-tests/generated-typing.ts +133 -0
  163. package/src/types/CategoryType.ts +52 -148
  164. package/src/types/CategoryTypeIdentifier.ts +5 -134
  165. package/src/types/CorrelationType.ts +13 -3
  166. package/src/types/ElectrocardiogramSample.ts +13 -1
  167. package/src/types/HeartbeatSeries.ts +13 -1
  168. package/src/types/InterfaceVerification.ts +38 -1
  169. package/src/types/Medication.ts +19 -0
  170. package/src/types/MetadataEnums.ts +15 -0
  171. package/src/types/QuantitySample.ts +14 -2
  172. package/src/types/QuantityType.ts +22 -122
  173. package/src/types/QuantityTypeIdentifier.ts +5 -772
  174. package/src/types/QueryOptions.ts +11 -4
  175. package/src/types/Shared.ts +22 -49
  176. package/src/types/StateOfMind.ts +13 -1
  177. package/src/types/Subscriptions.ts +19 -13
  178. package/src/types/WeatherCondition.ts +1 -31
  179. package/src/types/Workouts.ts +46 -108
  180. package/src/types/index.ts +2 -0
  181. package/src/utils/getMostRecentQuantitySample.ts +4 -3
  182. package/src/utils/getMostRecentWorkout.ts +5 -2
  183. package/src/utils/getPreferredUnit.ts +5 -4
  184. package/src/utils/getQuantitySampleById.ts +4 -3
  185. package/src/utils/subscribeToQuantitySamples.ts +5 -3
  186. package/nitrogen/generated/ios/swift/HeartRateMotionContext.swift +0 -44
  187. package/nitrogen/generated/ios/swift/InsulinDeliveryReason.swift +0 -40
  188. package/nitrogen/generated/ios/swift/WeatherCondition.swift +0 -144
  189. package/nitrogen/generated/shared/c++/HeartRateMotionContext.hpp +0 -67
  190. package/nitrogen/generated/shared/c++/InsulinDeliveryReason.hpp +0 -62
  191. package/nitrogen/generated/shared/c++/WeatherCondition.hpp +0 -88
@@ -35,6 +35,7 @@ Pod::Spec.new do |s|
35
35
  load 'nitrogen/generated/ios/ReactNativeHealthkit+autolinking.rb'
36
36
  add_nitrogen_files(s)
37
37
 
38
+
38
39
  # Workaround for Swift 6.2 (Xcode 26): shared_ptr lost automatic CxxConvertibleToBool conformance,
39
40
  # causing nitrogen-generated Bool(fromCxx:) calls to fail. Replace with use_count() > 0.
40
41
  # This can be removed once nitrogen fixes the codegen template upstream.
package/app.plugin.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  type ConfigPlugin,
3
3
  createRunOncePlugin,
4
+ withAppDelegate,
4
5
  withEntitlementsPlist,
5
6
  withInfoPlist,
6
7
  withPlugins,
@@ -8,8 +9,6 @@ import {
8
9
 
9
10
  import pkg from './package.json'
10
11
 
11
- // please note that the BackgroundConfig currently doesn't actually enable background delivery for any types, but you
12
- // can set it to false if you don't want the entitlement
13
12
  type BackgroundConfig = boolean
14
13
 
15
14
  type InfoPlistConfig = {
@@ -57,10 +56,49 @@ const withInfoPlistPlugin: ConfigPlugin<InfoPlistConfig> = (config, props) => {
57
56
  })
58
57
  }
59
58
 
59
+ const withAppDelegatePlugin: ConfigPlugin<{
60
+ background?: BackgroundConfig
61
+ }> = (config, props) => {
62
+ if (props?.background === false) {
63
+ return config
64
+ }
65
+
66
+ return withAppDelegate(config, (configDelegate) => {
67
+ const contents = configDelegate.modResults.contents
68
+
69
+ // Add import for HealthKit if not already present
70
+ if (!contents.includes('import HealthKit')) {
71
+ configDelegate.modResults.contents =
72
+ configDelegate.modResults.contents.replace(
73
+ /^(import .+\n)/m,
74
+ '$1import HealthKit\n',
75
+ )
76
+ }
77
+
78
+ // Insert BackgroundDeliveryManager setup into didFinishLaunchingWithOptions
79
+ const setupCall =
80
+ ' BackgroundDeliveryManager.shared.setupBackgroundObservers()\n'
81
+
82
+ if (
83
+ !configDelegate.modResults.contents.includes('BackgroundDeliveryManager')
84
+ ) {
85
+ // Match the opening of didFinishLaunchingWithOptions and insert after the opening brace
86
+ configDelegate.modResults.contents =
87
+ configDelegate.modResults.contents.replace(
88
+ /(func application\(.+didFinishLaunchingWithOptions.+\{)\n/,
89
+ `$1\n${setupCall}`,
90
+ )
91
+ }
92
+
93
+ return configDelegate
94
+ })
95
+ }
96
+
60
97
  const healthkitAppPlugin: ConfigPlugin<AppPluginConfig> = (config, props) => {
61
98
  return withPlugins(config, [
62
99
  [withEntitlementsPlugin, props],
63
100
  [withInfoPlistPlugin, props],
101
+ [withAppDelegatePlugin, props],
64
102
  ])
65
103
  }
66
104
 
@@ -0,0 +1,196 @@
1
+ import Foundation
2
+ import HealthKit
3
+
4
+ /// Manages HealthKit background delivery by registering observer queries at app launch,
5
+ /// before the JS bridge is available. This is required by Apple — observer queries must
6
+ /// be set up in `application(_:didFinishLaunchingWithOptions:)` to receive background
7
+ /// delivery callbacks after the app has been terminated.
8
+ ///
9
+ /// Usage from AppDelegate.swift:
10
+ /// BackgroundDeliveryManager.shared.setupBackgroundObservers()
11
+ ///
12
+ /// The types to observe are persisted in UserDefaults by `configureBackgroundTypes()`
13
+ /// called from JS. On subsequent cold launches, the manager reads these and registers
14
+ /// observers immediately, queuing any events until JS subscribes via `drainPendingEvents()`.
15
+ @objc public class BackgroundDeliveryManager: NSObject {
16
+ @objc public static let shared = BackgroundDeliveryManager()
17
+
18
+ private let healthStore = HKHealthStore()
19
+ private let queue = DispatchQueue(label: "com.kingstinct.healthkit.background", attributes: .concurrent)
20
+ private var observerQueries: [String: HKObserverQuery] = [:]
21
+ private var pendingEvents: [(typeIdentifier: String, errorMessage: String?)] = []
22
+ private var jsCallback: ((String, String?) -> Void)?
23
+ private var isSetUp = false
24
+
25
+ static let typesKey = "com.kingstinct.healthkit.backgroundTypes"
26
+ static let frequencyKey = "com.kingstinct.healthkit.backgroundFrequency"
27
+
28
+ private override init() {
29
+ super.init()
30
+ }
31
+
32
+ /// Call this from AppDelegate.didFinishLaunchingWithOptions to register observer queries
33
+ /// for any previously configured background delivery types.
34
+ @objc public func setupBackgroundObservers() {
35
+ guard HKHealthStore.isHealthDataAvailable() else { return }
36
+
37
+ guard let typeIdentifiers = UserDefaults.standard.stringArray(forKey: BackgroundDeliveryManager.typesKey) else {
38
+ return
39
+ }
40
+
41
+ let frequencyRaw = UserDefaults.standard.integer(forKey: BackgroundDeliveryManager.frequencyKey)
42
+ let frequency = HKUpdateFrequency(rawValue: frequencyRaw) ?? .immediate
43
+
44
+ registerObservers(typeIdentifiers: typeIdentifiers, frequency: frequency)
45
+ }
46
+
47
+ /// Persist types and frequency, then register observers for the current session.
48
+ /// Called from JS via CoreModule.configureBackgroundTypes().
49
+ func configure(typeIdentifiers: [String], frequency: HKUpdateFrequency) {
50
+ UserDefaults.standard.set(typeIdentifiers, forKey: BackgroundDeliveryManager.typesKey)
51
+ UserDefaults.standard.set(frequency.rawValue, forKey: BackgroundDeliveryManager.frequencyKey)
52
+
53
+ // Tear down existing observers before re-registering
54
+ tearDown()
55
+ registerObservers(typeIdentifiers: typeIdentifiers, frequency: frequency)
56
+ }
57
+
58
+ /// Subscribe a JS callback. Any events that arrived before JS was ready are flushed immediately.
59
+ func setCallback(_ callback: @escaping (String, String?) -> Void) {
60
+ queue.sync(flags: .barrier) {
61
+ self.jsCallback = callback
62
+ let events = self.pendingEvents
63
+ self.pendingEvents = []
64
+
65
+ for event in events {
66
+ callback(event.typeIdentifier, event.errorMessage)
67
+ }
68
+ }
69
+ }
70
+
71
+ /// Remove the JS callback (e.g., on teardown).
72
+ func removeCallback() {
73
+ queue.sync(flags: .barrier) {
74
+ self.jsCallback = nil
75
+ }
76
+ }
77
+
78
+ /// Returns any pending events and clears the queue. Used by CoreModule.subscribeToObserverQuery
79
+ /// to flush events that arrived before JS subscribed.
80
+ func drainPendingEvents() -> [(typeIdentifier: String, errorMessage: String?)] {
81
+ return queue.sync(flags: .barrier) {
82
+ let events = self.pendingEvents
83
+ self.pendingEvents = []
84
+ return events
85
+ }
86
+ }
87
+
88
+ /// Stop all observer queries and clear state.
89
+ func tearDown() {
90
+ queue.sync(flags: .barrier) {
91
+ for (_, query) in self.observerQueries {
92
+ self.healthStore.stop(query)
93
+ }
94
+ self.observerQueries = [:]
95
+ self.isSetUp = false
96
+ }
97
+ }
98
+
99
+ /// Clear persisted configuration (disables background delivery on next launch).
100
+ func clearConfiguration() {
101
+ UserDefaults.standard.removeObject(forKey: BackgroundDeliveryManager.typesKey)
102
+ UserDefaults.standard.removeObject(forKey: BackgroundDeliveryManager.frequencyKey)
103
+ tearDown()
104
+ }
105
+
106
+ private func registerObservers(typeIdentifiers: [String], frequency: HKUpdateFrequency) {
107
+ queue.sync(flags: .barrier) {
108
+ guard !self.isSetUp else { return }
109
+ self.isSetUp = true
110
+ }
111
+
112
+ for typeIdentifier in typeIdentifiers {
113
+ guard let sampleType = sampleTypeFromString(typeIdentifier) else {
114
+ print("[react-native-healthkit] BackgroundDeliveryManager: skipping unrecognized type \(typeIdentifier)")
115
+ continue
116
+ }
117
+
118
+ // Use nil predicate to catch all samples, including those written while the app was terminated.
119
+ // The current subscribeToObserverQuery uses Date.init() which misses data from when the app was dead.
120
+ let query = HKObserverQuery(
121
+ sampleType: sampleType,
122
+ predicate: nil
123
+ ) { [weak self] (_: HKObserverQuery, completionHandler: @escaping HKObserverQueryCompletionHandler, error: Error?) in
124
+ self?.handleObserverCallback(
125
+ typeIdentifier: typeIdentifier,
126
+ error: error
127
+ )
128
+ // Must call the completion handler promptly so iOS knows we processed the update.
129
+ completionHandler()
130
+ }
131
+
132
+ healthStore.execute(query)
133
+
134
+ healthStore.enableBackgroundDelivery(for: sampleType, frequency: frequency) { success, error in
135
+ if let error = error {
136
+ print("[react-native-healthkit] BackgroundDeliveryManager: enableBackgroundDelivery failed for \(typeIdentifier): \(error.localizedDescription)")
137
+ } else if !success {
138
+ print("[react-native-healthkit] BackgroundDeliveryManager: enableBackgroundDelivery returned false for \(typeIdentifier)")
139
+ }
140
+ }
141
+
142
+ queue.sync(flags: .barrier) {
143
+ self.observerQueries[typeIdentifier] = query
144
+ }
145
+ }
146
+ }
147
+
148
+ private func handleObserverCallback(typeIdentifier: String, error: Error?) {
149
+ let errorMessage = error?.localizedDescription
150
+
151
+ queue.sync(flags: .barrier) {
152
+ if let callback = self.jsCallback {
153
+ // JS is connected — dispatch to main thread for JSI safety
154
+ DispatchQueue.main.async {
155
+ callback(typeIdentifier, errorMessage)
156
+ }
157
+ } else {
158
+ // JS not ready yet — queue the event for later
159
+ self.pendingEvents.append((typeIdentifier: typeIdentifier, errorMessage: errorMessage))
160
+ }
161
+ }
162
+ }
163
+
164
+ // Local type resolution that doesn't depend on NitroModules (which isn't available at AppDelegate time).
165
+ // Uses the older factory APIs (quantityType(forIdentifier:) etc.) for iOS 13+ compatibility.
166
+ private func sampleTypeFromString(_ identifier: String) -> HKSampleType? {
167
+ if identifier.starts(with: "HKQuantityTypeIdentifier") {
168
+ let typeId = HKQuantityTypeIdentifier(rawValue: identifier)
169
+ return HKSampleType.quantityType(forIdentifier: typeId)
170
+ }
171
+ if identifier.starts(with: "HKCategoryTypeIdentifier") {
172
+ let typeId = HKCategoryTypeIdentifier(rawValue: identifier)
173
+ return HKSampleType.categoryType(forIdentifier: typeId)
174
+ }
175
+ if identifier == "HKWorkoutTypeIdentifier" {
176
+ return HKSampleType.workoutType()
177
+ }
178
+ if identifier.starts(with: "HKCorrelationTypeIdentifier") {
179
+ let typeId = HKCorrelationTypeIdentifier(rawValue: identifier)
180
+ return HKSampleType.correlationType(forIdentifier: typeId)
181
+ }
182
+ if identifier == "HKAudiogramSampleType" {
183
+ return HKObjectType.audiogramSampleType()
184
+ }
185
+ if identifier == "HKDataTypeIdentifierHeartbeatSeries" || identifier == "HKWorkoutRouteTypeIdentifier" {
186
+ return HKObjectType.seriesType(forIdentifier: identifier)
187
+ }
188
+ if identifier == "HKElectrocardiogramType" {
189
+ if #available(iOS 14.0, *) {
190
+ return HKSampleType.electrocardiogramType()
191
+ }
192
+ return nil
193
+ }
194
+ return nil
195
+ }
196
+ }
@@ -3,7 +3,7 @@ import NitroModules
3
3
 
4
4
  class CategoryTypeModule: HybridCategoryTypeModuleSpec {
5
5
  func saveCategorySample(
6
- identifier: CategoryTypeIdentifier,
6
+ identifier: CategoryTypeIdentifierWriteable,
7
7
  value: Double,
8
8
  startDate: Date,
9
9
  endDate: Date,
@@ -430,6 +430,30 @@ class CoreModule: HybridCoreModuleSpec {
430
430
  }
431
431
  }
432
432
 
433
+ func configureBackgroundTypes(
434
+ typeIdentifiers: [String], updateFrequency: UpdateFrequency
435
+ ) -> Promise<Bool> {
436
+ return Promise.async {
437
+ guard let frequency = HKUpdateFrequency(rawValue: Int(updateFrequency.rawValue)) else {
438
+ throw runtimeErrorWithPrefix("Invalid update frequency rawValue: \(updateFrequency)")
439
+ }
440
+
441
+ BackgroundDeliveryManager.shared.configure(
442
+ typeIdentifiers: typeIdentifiers,
443
+ frequency: frequency
444
+ )
445
+
446
+ return true
447
+ }
448
+ }
449
+
450
+ func clearBackgroundTypes() -> Promise<Bool> {
451
+ return Promise.async {
452
+ BackgroundDeliveryManager.shared.clearConfiguration()
453
+ return true
454
+ }
455
+ }
456
+
433
457
  func unsubscribeQueries(queryIds: [String]) -> Double {
434
458
  let successCounts = queryIds.map { queryId in
435
459
  if let query = self._runningQueries[queryId] {
@@ -24,47 +24,14 @@ func serializeCorrelationSample(correlation: HKCorrelation, unitMap: [HKQuantity
24
24
  return CorrelationSample(
25
25
  correlationType: CorrelationTypeIdentifier(fromString: correlation.correlationType.identifier)!,
26
26
  objects: objects,
27
- metadataFoodType: correlation.metadata?[HKMetadataKeyFoodType] as? String,
28
27
  sampleType: serializeSampleType(correlation.sampleType),
29
28
  startDate: correlation.startDate,
30
29
  endDate: correlation.endDate,
31
30
  hasUndeterminedDuration: correlation.hasUndeterminedDuration,
32
-
33
- metadataWeatherCondition: serializeWeatherCondition(
34
- correlation.metadata?[HKMetadataKeyWeatherCondition] as? HKWeatherCondition),
35
- metadataWeatherHumidity: serializeUnknownQuantityTyped(
36
- quantity: correlation.metadata?[HKMetadataKeyWeatherHumidity] as? HKQuantity),
37
- metadataWeatherTemperature: serializeUnknownQuantityTyped(
38
- quantity: correlation.metadata?[HKMetadataKeyWeatherTemperature] as? HKQuantity),
39
- metadataInsulinDeliveryReason: serializeInsulinDeliveryReason(
40
- correlation.metadata?[HKMetadataKeyInsulinDeliveryReason] as? HKInsulinDeliveryReason),
41
- metadataHeartRateMotionContext: serializeHeartRateMotionContext(
42
- correlation.metadata?[HKMetadataKeyHeartRateMotionContext] as? HKHeartRateMotionContext),
43
-
31
+ metadata: serializeMetadata(correlation.metadata),
44
32
  uuid: correlation.uuid.uuidString,
45
33
  sourceRevision: serializeSourceRevision(correlation.sourceRevision),
46
- device: serializeDevice(hkDevice: correlation.device),
47
- metadata: serializeMetadata(correlation.metadata),
48
-
49
- metadataExternalUUID: correlation.metadata?[HKMetadataKeyExternalUUID] as? String,
50
- metadataTimeZone: correlation.metadata?[HKMetadataKeyTimeZone] as? String,
51
- metadataWasUserEntered: correlation.metadata?[HKMetadataKeyWasUserEntered] as? Bool,
52
- metadataDeviceSerialNumber: correlation.metadata?[HKMetadataKeyDeviceSerialNumber] as? String,
53
- metadataUdiDeviceIdentifier: correlation.metadata?[HKMetadataKeyUDIDeviceIdentifier] as? String,
54
- metadataUdiProductionIdentifier: correlation.metadata?[HKMetadataKeyUDIProductionIdentifier]
55
- as? String,
56
- metadataDigitalSignature: correlation.metadata?[HKMetadataKeyDigitalSignature] as? String,
57
- metadataDeviceName: correlation.metadata?[HKMetadataKeyDeviceName] as? String,
58
- metadataDeviceManufacturerName: correlation.metadata?[HKMetadataKeyDeviceManufacturerName]
59
- as? String,
60
- metadataSyncIdentifier: correlation.metadata?[HKMetadataKeySyncIdentifier] as? String,
61
- metadataSyncVersion: correlation.metadata?[HKMetadataKeySyncVersion] as? Double,
62
- metadataWasTakenInLab: correlation.metadata?[HKMetadataKeyWasTakenInLab] as? Bool,
63
- metadataReferenceRangeLowerLimit: correlation.metadata?[HKMetadataKeyReferenceRangeLowerLimit]
64
- as? Double,
65
- metadataReferenceRangeUpperLimit: correlation.metadata?[HKMetadataKeyReferenceRangeUpperLimit]
66
- as? Double,
67
- metadataAlgorithmVersion: correlation.metadata?[HKMetadataKeyAlgorithmVersion] as? Double
34
+ device: serializeDevice(hkDevice: correlation.device)
68
35
  )
69
36
  }
70
37
 
@@ -38,42 +38,10 @@ private func serializeECGSample(sample: HKElectrocardiogram, includeVoltages: Bo
38
38
  startDate: sample.startDate,
39
39
  endDate: sample.endDate,
40
40
  hasUndeterminedDuration: sample.hasUndeterminedDuration,
41
-
42
- metadataWeatherCondition: serializeWeatherCondition(
43
- sample.metadata?[HKMetadataKeyWeatherCondition] as? HKWeatherCondition),
44
- metadataWeatherHumidity: serializeUnknownQuantityTyped(
45
- quantity: sample.metadata?[HKMetadataKeyWeatherHumidity] as? HKQuantity),
46
- metadataWeatherTemperature: serializeUnknownQuantityTyped(
47
- quantity: sample.metadata?[HKMetadataKeyWeatherTemperature] as? HKQuantity),
48
- metadataInsulinDeliveryReason: serializeInsulinDeliveryReason(
49
- sample.metadata?[HKMetadataKeyInsulinDeliveryReason] as? HKInsulinDeliveryReason),
50
- metadataHeartRateMotionContext: serializeHeartRateMotionContext(
51
- sample.metadata?[HKMetadataKeyHeartRateMotionContext] as? HKHeartRateMotionContext),
52
-
41
+ metadata: serializeMetadata(sample.metadata),
53
42
  uuid: sample.uuid.uuidString,
54
43
  sourceRevision: serializeSourceRevision(sample.sourceRevision),
55
- device: serializeDevice(hkDevice: sample.device),
56
- metadata: serializeMetadata(sample.metadata),
57
-
58
- metadataExternalUUID: sample.metadata?[HKMetadataKeyExternalUUID] as? String,
59
- metadataTimeZone: sample.metadata?[HKMetadataKeyTimeZone] as? String,
60
- metadataWasUserEntered: sample.metadata?[HKMetadataKeyWasUserEntered] as? Bool,
61
- metadataDeviceSerialNumber: sample.metadata?[HKMetadataKeyDeviceSerialNumber] as? String,
62
- metadataUdiDeviceIdentifier: sample.metadata?[HKMetadataKeyUDIDeviceIdentifier] as? String,
63
- metadataUdiProductionIdentifier: sample.metadata?[HKMetadataKeyUDIProductionIdentifier]
64
- as? String,
65
- metadataDigitalSignature: sample.metadata?[HKMetadataKeyDigitalSignature] as? String,
66
- metadataDeviceName: sample.metadata?[HKMetadataKeyDeviceName] as? String,
67
- metadataDeviceManufacturerName: sample.metadata?[HKMetadataKeyDeviceManufacturerName]
68
- as? String,
69
- metadataSyncIdentifier: sample.metadata?[HKMetadataKeySyncIdentifier] as? String,
70
- metadataSyncVersion: sample.metadata?[HKMetadataKeySyncVersion] as? Double,
71
- metadataWasTakenInLab: sample.metadata?[HKMetadataKeyWasTakenInLab] as? Bool,
72
- metadataReferenceRangeLowerLimit: sample.metadata?[HKMetadataKeyReferenceRangeLowerLimit]
73
- as? Double,
74
- metadataReferenceRangeUpperLimit: sample.metadata?[HKMetadataKeyReferenceRangeUpperLimit]
75
- as? Double,
76
- metadataAlgorithmVersion: sample.metadata?[HKMetadataKeyAlgorithmVersion] as? Double
44
+ device: serializeDevice(hkDevice: sample.device)
77
45
  )
78
46
  }
79
47
 
@@ -11,42 +11,10 @@ func serializeHeartbeatSeriesSample(sample: HKHeartbeatSeriesSample) async throw
11
11
  startDate: sample.startDate,
12
12
  endDate: sample.endDate,
13
13
  hasUndeterminedDuration: sample.hasUndeterminedDuration,
14
-
15
- metadataWeatherCondition: serializeWeatherCondition(
16
- sample.metadata?[HKMetadataKeyWeatherCondition] as? HKWeatherCondition),
17
- metadataWeatherHumidity: serializeUnknownQuantityTyped(
18
- quantity: sample.metadata?[HKMetadataKeyWeatherHumidity] as? HKQuantity),
19
- metadataWeatherTemperature: serializeUnknownQuantityTyped(
20
- quantity: sample.metadata?[HKMetadataKeyWeatherTemperature] as? HKQuantity),
21
- metadataInsulinDeliveryReason: serializeInsulinDeliveryReason(
22
- sample.metadata?[HKMetadataKeyInsulinDeliveryReason] as? HKInsulinDeliveryReason),
23
- metadataHeartRateMotionContext: serializeHeartRateMotionContext(
24
- sample.metadata?[HKMetadataKeyHeartRateMotionContext] as? HKHeartRateMotionContext),
25
-
14
+ metadata: serializeMetadata(sample.metadata),
26
15
  uuid: sample.uuid.uuidString,
27
16
  sourceRevision: serializeSourceRevision(sample.sourceRevision),
28
- device: serializeDevice(hkDevice: sample.device),
29
- metadata: serializeMetadata(sample.metadata),
30
-
31
- metadataExternalUUID: sample.metadata?[HKMetadataKeyExternalUUID] as? String,
32
- metadataTimeZone: sample.metadata?[HKMetadataKeyTimeZone] as? String,
33
- metadataWasUserEntered: sample.metadata?[HKMetadataKeyWasUserEntered] as? Bool,
34
- metadataDeviceSerialNumber: sample.metadata?[HKMetadataKeyDeviceSerialNumber] as? String,
35
- metadataUdiDeviceIdentifier: sample.metadata?[HKMetadataKeyUDIDeviceIdentifier] as? String,
36
- metadataUdiProductionIdentifier: sample.metadata?[HKMetadataKeyUDIProductionIdentifier]
37
- as? String,
38
- metadataDigitalSignature: sample.metadata?[HKMetadataKeyDigitalSignature] as? String,
39
- metadataDeviceName: sample.metadata?[HKMetadataKeyDeviceName] as? String,
40
- metadataDeviceManufacturerName: sample.metadata?[HKMetadataKeyDeviceManufacturerName]
41
- as? String,
42
- metadataSyncIdentifier: sample.metadata?[HKMetadataKeySyncIdentifier] as? String,
43
- metadataSyncVersion: sample.metadata?[HKMetadataKeySyncVersion] as? Double,
44
- metadataWasTakenInLab: sample.metadata?[HKMetadataKeyWasTakenInLab] as? Bool,
45
- metadataReferenceRangeLowerLimit: sample.metadata?[HKMetadataKeyReferenceRangeLowerLimit]
46
- as? Double,
47
- metadataReferenceRangeUpperLimit: sample.metadata?[HKMetadataKeyReferenceRangeUpperLimit]
48
- as? Double,
49
- metadataAlgorithmVersion: sample.metadata?[HKMetadataKeyAlgorithmVersion] as? Double
17
+ device: serializeDevice(hkDevice: sample.device)
50
18
  )
51
19
  }
52
20
 
@@ -97,21 +97,6 @@ import NitroModules
97
97
  startDate: sample.startDate,
98
98
  endDate: sample.endDate,
99
99
  hasUndeterminedDuration: sample.hasUndeterminedDuration,
100
-
101
- metadataWeatherCondition: serializeWeatherCondition(
102
- sample.metadata?[HKMetadataKeyWeatherCondition] as? HKWeatherCondition),
103
- metadataWeatherHumidity: serializeUnknownQuantityTyped(
104
- quantity: sample.metadata?[HKMetadataKeyWeatherHumidity] as? HKQuantity),
105
- metadataWeatherTemperature: serializeUnknownQuantityTyped(
106
- quantity: sample.metadata?[HKMetadataKeyWeatherTemperature] as? HKQuantity),
107
- metadataInsulinDeliveryReason: serializeInsulinDeliveryReason(
108
- sample.metadata?[HKMetadataKeyInsulinDeliveryReason] as? HKInsulinDeliveryReason),
109
- metadataHeartRateMotionContext: serializeHeartRateMotionContext(
110
- sample.metadata?[HKMetadataKeyHeartRateMotionContext] as? HKHeartRateMotionContext),
111
-
112
- uuid: sample.uuid.uuidString,
113
- sourceRevision: serializeSourceRevision(sample.sourceRevision),
114
- device: serializeDevice(hkDevice: sample.device),
115
100
  metadata: {
116
101
  var meta = serializeMetadata(sample.metadata)
117
102
  if let nick = info?.nickname {
@@ -119,26 +104,9 @@ import NitroModules
119
104
  }
120
105
  return meta
121
106
  }(),
122
-
123
- metadataExternalUUID: sample.metadata?[HKMetadataKeyExternalUUID] as? String,
124
- metadataTimeZone: sample.metadata?[HKMetadataKeyTimeZone] as? String,
125
- metadataWasUserEntered: sample.metadata?[HKMetadataKeyWasUserEntered] as? Bool,
126
- metadataDeviceSerialNumber: sample.metadata?[HKMetadataKeyDeviceSerialNumber] as? String,
127
- metadataUdiDeviceIdentifier: sample.metadata?[HKMetadataKeyUDIDeviceIdentifier] as? String,
128
- metadataUdiProductionIdentifier: sample.metadata?[HKMetadataKeyUDIProductionIdentifier]
129
- as? String,
130
- metadataDigitalSignature: sample.metadata?[HKMetadataKeyDigitalSignature] as? String,
131
- metadataDeviceName: sample.metadata?[HKMetadataKeyDeviceName] as? String,
132
- metadataDeviceManufacturerName: sample.metadata?[HKMetadataKeyDeviceManufacturerName]
133
- as? String,
134
- metadataSyncIdentifier: sample.metadata?[HKMetadataKeySyncIdentifier] as? String,
135
- metadataSyncVersion: sample.metadata?[HKMetadataKeySyncVersion] as? Double,
136
- metadataWasTakenInLab: sample.metadata?[HKMetadataKeyWasTakenInLab] as? Bool,
137
- metadataReferenceRangeLowerLimit: sample.metadata?[HKMetadataKeyReferenceRangeLowerLimit]
138
- as? Double,
139
- metadataReferenceRangeUpperLimit: sample.metadata?[HKMetadataKeyReferenceRangeUpperLimit]
140
- as? Double,
141
- metadataAlgorithmVersion: sample.metadata?[HKMetadataKeyAlgorithmVersion] as? Double
107
+ uuid: sample.uuid.uuidString,
108
+ sourceRevision: serializeSourceRevision(sample.sourceRevision),
109
+ device: serializeDevice(hkDevice: sample.device)
142
110
  )
143
111
  }
144
112
 
@@ -71,10 +71,10 @@ func getPredicateForWorkoutBase(_ filter: FilterForWorkouts?) -> FilterForWorkou
71
71
  return FilterForWorkoutsBase(
72
72
  workoutActivityType: filter.workoutActivityType,
73
73
  duration: filter.duration,
74
- sources: filter.sources,
74
+ metadata: filter.metadata,
75
75
  uuid: filter.uuid,
76
+ sources: filter.sources,
76
77
  uuids: filter.uuids,
77
- metadata: filter.metadata,
78
78
  date: filter.date,
79
79
  )
80
80
  }
@@ -19,7 +19,7 @@ func emptyStatisticsResponse(from: Date?, to: Date?) -> QueryStatisticsResponse
19
19
  func queryStatisticsForQuantityInternal(
20
20
  quantityType: HKQuantityType,
21
21
  statistics: [StatisticsOptions],
22
- options: StatisticsQueryOptions?
22
+ options: StatisticsQueryOptionsWithStringUnit?
23
23
  ) async throws -> HKStatistics? {
24
24
  let predicate = createPredicateForSamples(options?.filter)
25
25
 
@@ -128,7 +128,7 @@ func queryStatisticsCollectionForQuantityInternal(
128
128
  statistics: [StatisticsOptions],
129
129
  anchorDate: Date,
130
130
  intervalComponents: IntervalComponents,
131
- options: StatisticsQueryOptions?
131
+ options: StatisticsQueryOptionsWithStringUnit?
132
132
  ) async throws -> HKStatisticsCollection? {
133
133
  let predicate = createPredicateForSamples(options?.filter)
134
134
 
@@ -245,15 +245,15 @@ func serializeStatisticsPerSource(gottenStats: HKStatistics, unit: HKUnit)
245
245
 
246
246
  return QueryStatisticsResponseFromSingleSource(
247
247
  source: serializeSource(source),
248
+ startDate: gottenStats.startDate,
249
+ endDate: gottenStats.endDate,
248
250
  duration: duration,
249
251
  averageQuantity: averageQuantity,
250
252
  maximumQuantity: maximumQuantity,
251
253
  minimumQuantity: minimumQuantity,
252
254
  sumQuantity: sumQuantity,
253
255
  mostRecentQuantity: mostRecentQuantity,
254
- mostRecentQuantityDateInterval: mostRecentQuantityDateInterval,
255
- startDate: gottenStats.startDate,
256
- endDate: gottenStats.endDate
256
+ mostRecentQuantityDateInterval: mostRecentQuantityDateInterval
257
257
  )
258
258
  }
259
259
  }
@@ -308,7 +308,7 @@ func handleHKNoDataOrThrow<T>(
308
308
  class QuantityTypeModule: HybridQuantityTypeModuleSpec {
309
309
  func queryStatisticsForQuantitySeparateBySource(
310
310
  identifier: QuantityTypeIdentifier, statistics: [StatisticsOptions],
311
- options: StatisticsQueryOptions?
311
+ options: StatisticsQueryOptionsWithStringUnit?
312
312
  ) -> Promise<[QueryStatisticsResponseFromSingleSource]> {
313
313
  return Promise.async {
314
314
  let quantityType = try initializeQuantityType(identifier.stringValue)
@@ -331,7 +331,7 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
331
331
 
332
332
  func queryStatisticsCollectionForQuantitySeparateBySource(
333
333
  identifier: QuantityTypeIdentifier, statistics: [StatisticsOptions], anchorDate: Date,
334
- intervalComponents: IntervalComponents, options: StatisticsQueryOptions?
334
+ intervalComponents: IntervalComponents, options: StatisticsQueryOptionsWithStringUnit?
335
335
  ) -> Promise<[QueryStatisticsResponseFromSingleSource]> {
336
336
  return Promise.async {
337
337
  let quantityType = try initializeQuantityType(identifier.stringValue)
@@ -380,7 +380,7 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
380
380
  func queryStatisticsForQuantity(
381
381
  identifier: QuantityTypeIdentifier,
382
382
  statistics: [StatisticsOptions],
383
- options: StatisticsQueryOptions?
383
+ options: StatisticsQueryOptionsWithStringUnit?
384
384
  ) -> Promise<QueryStatisticsResponse> {
385
385
  return Promise.async {
386
386
  let quantityType = try initializeQuantityType(identifier.stringValue)
@@ -407,7 +407,7 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
407
407
 
408
408
  func queryStatisticsCollectionForQuantity(
409
409
  identifier: QuantityTypeIdentifier, statistics: [StatisticsOptions], anchorDate: Date,
410
- intervalComponents: IntervalComponents, options: StatisticsQueryOptions?
410
+ intervalComponents: IntervalComponents, options: StatisticsQueryOptionsWithStringUnit?
411
411
  ) -> Promise<[QueryStatisticsResponse]> {
412
412
  return Promise.async {
413
413
  let quantityType = try initializeQuantityType(identifier.stringValue)
@@ -434,7 +434,7 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
434
434
  }
435
435
 
436
436
  func queryQuantitySamplesWithAnchor(
437
- identifier: QuantityTypeIdentifier, options: QueryOptionsWithAnchorAndUnit
437
+ identifier: QuantityTypeIdentifier, options: QueryOptionsWithAnchorAndStringUnit
438
438
  ) -> Promise<QuantitySamplesWithAnchorResponse> {
439
439
  return Promise.async {
440
440
  let quantityType = try initializeQuantityType(identifier.stringValue)
@@ -505,7 +505,7 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
505
505
  }
506
506
 
507
507
  func queryQuantitySamples(
508
- identifier: QuantityTypeIdentifier, options: QueryOptionsWithSortOrderAndUnit
508
+ identifier: QuantityTypeIdentifier, options: QueryOptionsWithSortOrderAndStringUnit
509
509
  ) -> Promise<[QuantitySample]> {
510
510
  return Promise.async {
511
511
  let quantityType = try initializeQuantityType(identifier.stringValue)