@kingstinct/react-native-healthkit 12.1.2 → 12.2.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 (266) hide show
  1. package/ios/CategoryTypeModule.swift +49 -97
  2. package/ios/CharacteristicTypeModule.swift +77 -63
  3. package/ios/CoreModule.swift +324 -280
  4. package/ios/CorrelationTypeModule.swift +192 -144
  5. package/ios/ElectrocardiogramModule.swift +185 -194
  6. package/ios/HeartbeatSeriesModule.swift +123 -171
  7. package/ios/Helpers.swift +312 -571
  8. package/ios/MedicationModule.swift +259 -0
  9. package/ios/PredicateHelpers.swift +334 -0
  10. package/ios/QuantityTypeModule.swift +297 -378
  11. package/ios/Serializers.swift +273 -210
  12. package/ios/SourceProxy.swift +2 -2
  13. package/ios/StateOfMindModule.swift +179 -125
  14. package/ios/WorkoutProxy.swift +235 -112
  15. package/ios/WorkoutsModule.swift +214 -262
  16. package/lib/commonjs/healthkit.ios.js +22 -2
  17. package/lib/commonjs/healthkit.js +35 -5
  18. package/lib/commonjs/hooks/useStatisticsForQuantity.js +1 -1
  19. package/lib/commonjs/hooks/useSubscribeToCategorySamples.js +20 -0
  20. package/lib/commonjs/modules.js +2 -1
  21. package/lib/commonjs/specs/MedicationModule.nitro.js +27 -0
  22. package/lib/commonjs/types/Constants.js +2 -1
  23. package/lib/commonjs/types/QuantityType.js +8 -1
  24. package/lib/commonjs/types/QueryOptions.js +18 -0
  25. package/lib/commonjs/types/WeatherCondition.js +32 -32
  26. package/lib/commonjs/types/Workouts.js +1 -50
  27. package/lib/commonjs/utils/getCategorySampleById.js +1 -1
  28. package/lib/commonjs/utils/getQuantitySampleById.js +1 -1
  29. package/lib/commonjs/utils/getWorkoutById.js +1 -1
  30. package/lib/commonjs/utils/subscribeToCategorySamples.js +29 -0
  31. package/lib/commonjs/utils/subscribeToQuantitySamples.js +8 -25
  32. package/lib/module/healthkit.ios.js +20 -2
  33. package/lib/module/healthkit.js +32 -2
  34. package/lib/module/hooks/useStatisticsForQuantity.js +1 -1
  35. package/lib/module/hooks/useSubscribeToCategorySamples.js +17 -0
  36. package/lib/module/modules.js +1 -0
  37. package/lib/module/specs/MedicationModule.nitro.js +26 -0
  38. package/lib/module/types/Constants.js +1 -0
  39. package/lib/module/types/QuantityType.js +7 -0
  40. package/lib/module/types/QueryOptions.js +17 -1
  41. package/lib/module/types/WeatherCondition.js +31 -31
  42. package/lib/module/types/Workouts.js +0 -49
  43. package/lib/module/utils/getCategorySampleById.js +1 -1
  44. package/lib/module/utils/getQuantitySampleById.js +1 -1
  45. package/lib/module/utils/getWorkoutById.js +1 -1
  46. package/lib/module/utils/subscribeToCategorySamples.js +26 -0
  47. package/lib/module/utils/subscribeToQuantitySamples.js +8 -25
  48. package/lib/typescript/healthkit.d.ts +18 -9
  49. package/lib/typescript/healthkit.ios.d.ts +33 -15
  50. package/lib/typescript/hooks/useSubscribeToCategorySamples.d.ts +3 -0
  51. package/lib/typescript/modules.d.ts +2 -0
  52. package/lib/typescript/specs/CategoryTypeModule.nitro.d.ts +2 -2
  53. package/lib/typescript/specs/CoreModule.nitro.d.ts +2 -1
  54. package/lib/typescript/specs/CorrelationTypeModule.nitro.d.ts +4 -2
  55. package/lib/typescript/specs/ElectrocardiogramModule.nitro.d.ts +1 -1
  56. package/lib/typescript/specs/HeartbeatSeriesModule.nitro.d.ts +1 -1
  57. package/lib/typescript/specs/MedicationModule.nitro.d.ts +56 -0
  58. package/lib/typescript/specs/QuantityTypeModule.nitro.d.ts +4 -4
  59. package/lib/typescript/specs/StateOfMindModule.nitro.d.ts +4 -3
  60. package/lib/typescript/types/CategoryType.d.ts +10 -20
  61. package/lib/typescript/types/Constants.d.ts +1 -0
  62. package/lib/typescript/types/CorrelationType.d.ts +8 -10
  63. package/lib/typescript/types/ElectrocardiogramSample.d.ts +2 -12
  64. package/lib/typescript/types/HeartbeatSeries.d.ts +2 -14
  65. package/lib/typescript/types/QuantitySample.d.ts +2 -8
  66. package/lib/typescript/types/QuantityType.d.ts +7 -8
  67. package/lib/typescript/types/QuantityTypeIdentifier.d.ts +23 -23
  68. package/lib/typescript/types/QueryOptions.d.ts +43 -28
  69. package/lib/typescript/types/Shared.d.ts +52 -7
  70. package/lib/typescript/types/StateOfMind.d.ts +7 -10
  71. package/lib/typescript/types/Subscriptions.d.ts +12 -3
  72. package/lib/typescript/types/WeatherCondition.d.ts +1 -1
  73. package/lib/typescript/types/Workouts.d.ts +28 -81
  74. package/lib/typescript/utils/subscribeToCategorySamples.d.ts +5 -0
  75. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +57 -0
  76. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +592 -389
  77. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +65 -30
  78. package/nitrogen/generated/ios/ReactNativeHealthkitAutolinking.mm +8 -0
  79. package/nitrogen/generated/ios/ReactNativeHealthkitAutolinking.swift +15 -0
  80. package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +32 -26
  81. package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +36 -37
  82. package/nitrogen/generated/ios/c++/HybridCorrelationTypeModuleSpecSwift.hpp +55 -2
  83. package/nitrogen/generated/ios/c++/HybridElectrocardiogramModuleSpecSwift.hpp +36 -30
  84. package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +35 -29
  85. package/nitrogen/generated/ios/c++/HybridMedicationModuleSpecSwift.cpp +11 -0
  86. package/nitrogen/generated/ios/c++/HybridMedicationModuleSpecSwift.hpp +181 -0
  87. package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +48 -42
  88. package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +59 -36
  89. package/nitrogen/generated/ios/c++/HybridWorkoutProxySpecSwift.hpp +150 -29
  90. package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +13 -28
  91. package/nitrogen/generated/ios/swift/AggregationStyle.swift +48 -0
  92. package/nitrogen/generated/ios/swift/CategorySample.swift +571 -24
  93. package/nitrogen/generated/ios/swift/ComparisonPredicateOperator.swift +2 -2
  94. package/nitrogen/generated/ios/swift/CorrelationSample.swift +640 -17
  95. package/nitrogen/generated/ios/swift/{PredicateWithStartAndEnd.swift → DateFilter.swift} +5 -5
  96. package/nitrogen/generated/ios/swift/ECGQueryOptionsWithAnchor.swift +11 -91
  97. package/nitrogen/generated/ios/swift/ECGQueryOptionsWithSortOrder.swift +11 -91
  98. package/nitrogen/generated/ios/swift/ElectrocardiogramSample.swift +570 -72
  99. package/nitrogen/generated/ios/swift/FilterForSamples.swift +349 -12
  100. package/nitrogen/generated/ios/swift/FilterForSamplesBase.swift +234 -0
  101. package/nitrogen/generated/ios/swift/FilterForWorkouts.swift +366 -0
  102. package/nitrogen/generated/ios/swift/FilterForWorkoutsBase.swift +240 -0
  103. package/nitrogen/generated/ios/swift/Func_void_MedicationDoseEventsWithAnchorResponse.swift +47 -0
  104. package/nitrogen/generated/ios/swift/Func_void_QueryCorrelationSamplesWithAnchorResponse.swift +47 -0
  105. package/nitrogen/generated/ios/swift/Func_void_StateOfMindSamplesWithAnchorResponse.swift +47 -0
  106. package/nitrogen/generated/ios/swift/Func_void_std__vector_MedicationDoseEvent_.swift +47 -0
  107. package/nitrogen/generated/ios/swift/Func_void_std__vector_UserAnnotatedMedication_.swift +47 -0
  108. package/nitrogen/generated/ios/swift/GeneralForm.swift +104 -0
  109. package/nitrogen/generated/ios/swift/HeartRateMotionContext.swift +44 -0
  110. package/nitrogen/generated/ios/swift/HeartbeatSeriesSample.swift +565 -37
  111. package/nitrogen/generated/ios/swift/HybridCategoryTypeModuleSpec.swift +1 -1
  112. package/nitrogen/generated/ios/swift/HybridCategoryTypeModuleSpec_cxx.swift +2 -2
  113. package/nitrogen/generated/ios/swift/HybridCoreModuleSpec.swift +2 -1
  114. package/nitrogen/generated/ios/swift/HybridCoreModuleSpec_cxx.swift +19 -31
  115. package/nitrogen/generated/ios/swift/HybridCorrelationTypeModuleSpec.swift +2 -1
  116. package/nitrogen/generated/ios/swift/HybridCorrelationTypeModuleSpec_cxx.swift +21 -2
  117. package/nitrogen/generated/ios/swift/HybridElectrocardiogramModuleSpec.swift +1 -1
  118. package/nitrogen/generated/ios/swift/HybridElectrocardiogramModuleSpec_cxx.swift +2 -2
  119. package/nitrogen/generated/ios/swift/HybridHeartbeatSeriesModuleSpec.swift +1 -1
  120. package/nitrogen/generated/ios/swift/HybridHeartbeatSeriesModuleSpec_cxx.swift +2 -2
  121. package/nitrogen/generated/ios/swift/HybridMedicationModuleSpec.swift +60 -0
  122. package/nitrogen/generated/ios/swift/HybridMedicationModuleSpec_cxx.swift +208 -0
  123. package/nitrogen/generated/ios/swift/HybridQuantityTypeModuleSpec.swift +2 -2
  124. package/nitrogen/generated/ios/swift/HybridQuantityTypeModuleSpec_cxx.swift +9 -43
  125. package/nitrogen/generated/ios/swift/HybridStateOfMindModuleSpec.swift +2 -1
  126. package/nitrogen/generated/ios/swift/HybridStateOfMindModuleSpec_cxx.swift +21 -2
  127. package/nitrogen/generated/ios/swift/HybridWorkoutProxySpec.swift +34 -6
  128. package/nitrogen/generated/ios/swift/HybridWorkoutProxySpec_cxx.swift +376 -36
  129. package/nitrogen/generated/ios/swift/InsulinDeliveryReason.swift +40 -0
  130. package/nitrogen/generated/ios/swift/MedicationConcept.swift +80 -0
  131. package/nitrogen/generated/ios/swift/MedicationDoseEvent.swift +781 -0
  132. package/nitrogen/generated/ios/swift/MedicationDoseEventLogStatus.swift +56 -0
  133. package/nitrogen/generated/ios/swift/MedicationDoseEventScheduleType.swift +40 -0
  134. package/nitrogen/generated/ios/swift/MedicationDoseEventsWithAnchorResponse.swift +81 -0
  135. package/nitrogen/generated/ios/swift/ObjectTypeIdentifier.swift +16 -16
  136. package/nitrogen/generated/ios/swift/PredicateWithMetadataKey.swift +7 -7
  137. package/nitrogen/generated/ios/swift/QuantitySample.swift +574 -27
  138. package/nitrogen/generated/ios/swift/QuantityTypeIdentifier.swift +16 -16
  139. package/nitrogen/generated/ios/swift/QueryCorrelationSamplesWithAnchorResponse.swift +81 -0
  140. package/nitrogen/generated/ios/swift/QueryOptionsWithAnchor.swift +11 -91
  141. package/nitrogen/generated/ios/swift/QueryOptionsWithAnchorAndUnit.swift +11 -91
  142. package/nitrogen/generated/ios/swift/QueryOptionsWithSortOrder.swift +11 -91
  143. package/nitrogen/generated/ios/swift/QueryOptionsWithSortOrderAndUnit.swift +11 -91
  144. package/nitrogen/generated/ios/swift/RelatedCoding.swift +76 -0
  145. package/nitrogen/generated/ios/swift/SampleType.swift +68 -0
  146. package/nitrogen/generated/ios/swift/SampleTypeIdentifier.swift +16 -16
  147. package/nitrogen/generated/ios/swift/SampleTypeIdentifierWriteable.swift +0 -16
  148. package/nitrogen/generated/ios/swift/StateOfMindSample.swift +586 -58
  149. package/nitrogen/generated/ios/swift/StateOfMindSamplesWithAnchorResponse.swift +81 -0
  150. package/nitrogen/generated/ios/swift/StatisticsQueryOptions.swift +7 -75
  151. package/nitrogen/generated/ios/swift/UserAnnotatedMedication.swift +87 -0
  152. package/nitrogen/generated/ios/swift/WeatherCondition.swift +144 -0
  153. package/nitrogen/generated/ios/swift/WorkoutQueryOptions.swift +11 -105
  154. package/nitrogen/generated/ios/swift/WorkoutQueryOptionsWithAnchor.swift +11 -105
  155. package/nitrogen/generated/ios/swift/WorkoutSample.swift +751 -78
  156. package/nitrogen/generated/shared/c++/AggregationStyle.hpp +64 -0
  157. package/nitrogen/generated/shared/c++/CategorySample.hpp +126 -23
  158. package/nitrogen/generated/shared/c++/CorrelationSample.hpp +134 -12
  159. package/nitrogen/generated/shared/c++/{PredicateWithStartAndEnd.hpp → DateFilter.hpp} +10 -10
  160. package/nitrogen/generated/shared/c++/ECGQueryOptionsWithAnchor.hpp +12 -31
  161. package/nitrogen/generated/shared/c++/ECGQueryOptionsWithSortOrder.hpp +12 -31
  162. package/nitrogen/generated/shared/c++/ElectrocardiogramSample.hpp +135 -36
  163. package/nitrogen/generated/shared/c++/FilterForSamples.hpp +124 -0
  164. package/nitrogen/generated/shared/c++/FilterForSamplesBase.hpp +109 -0
  165. package/nitrogen/generated/shared/c++/FilterForWorkouts.hpp +131 -0
  166. package/nitrogen/generated/shared/c++/FilterForWorkoutsBase.hpp +116 -0
  167. package/nitrogen/generated/shared/c++/GeneralForm.hpp +140 -0
  168. package/nitrogen/generated/shared/c++/HeartRateMotionContext.hpp +67 -0
  169. package/nitrogen/generated/shared/c++/HeartbeatSeriesSample.hpp +131 -28
  170. package/nitrogen/generated/shared/c++/HybridCategoryTypeModuleSpec.hpp +1 -2
  171. package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.cpp +1 -0
  172. package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.hpp +10 -28
  173. package/nitrogen/generated/shared/c++/HybridCorrelationTypeModuleSpec.cpp +1 -0
  174. package/nitrogen/generated/shared/c++/HybridCorrelationTypeModuleSpec.hpp +11 -1
  175. package/nitrogen/generated/shared/c++/HybridElectrocardiogramModuleSpec.hpp +1 -2
  176. package/nitrogen/generated/shared/c++/HybridHeartbeatSeriesModuleSpec.hpp +1 -2
  177. package/nitrogen/generated/shared/c++/HybridMedicationModuleSpec.cpp +24 -0
  178. package/nitrogen/generated/shared/c++/HybridMedicationModuleSpec.hpp +80 -0
  179. package/nitrogen/generated/shared/c++/HybridQuantityTypeModuleSpec.cpp +1 -1
  180. package/nitrogen/generated/shared/c++/HybridQuantityTypeModuleSpec.hpp +6 -25
  181. package/nitrogen/generated/shared/c++/HybridStateOfMindModuleSpec.cpp +1 -0
  182. package/nitrogen/generated/shared/c++/HybridStateOfMindModuleSpec.hpp +9 -2
  183. package/nitrogen/generated/shared/c++/HybridWorkoutProxySpec.cpp +33 -5
  184. package/nitrogen/generated/shared/c++/HybridWorkoutProxySpec.hpp +56 -16
  185. package/nitrogen/generated/shared/c++/InsulinDeliveryReason.hpp +62 -0
  186. package/nitrogen/generated/shared/c++/MedicationConcept.hpp +93 -0
  187. package/nitrogen/generated/shared/c++/MedicationDoseEvent.hpp +240 -0
  188. package/nitrogen/generated/shared/c++/MedicationDoseEventLogStatus.hpp +66 -0
  189. package/nitrogen/generated/shared/c++/MedicationDoseEventScheduleType.hpp +62 -0
  190. package/nitrogen/generated/shared/c++/MedicationDoseEventsWithAnchorResponse.hpp +89 -0
  191. package/nitrogen/generated/shared/c++/ObjectTypeIdentifier.hpp +105 -105
  192. package/nitrogen/generated/shared/c++/PredicateWithMetadataKey.hpp +8 -8
  193. package/nitrogen/generated/shared/c++/QuantitySample.hpp +130 -27
  194. package/nitrogen/generated/shared/c++/QuantityTypeIdentifier.hpp +105 -105
  195. package/nitrogen/generated/shared/c++/QueryCorrelationSamplesWithAnchorResponse.hpp +89 -0
  196. package/nitrogen/generated/shared/c++/QueryOptionsWithAnchor.hpp +12 -31
  197. package/nitrogen/generated/shared/c++/QueryOptionsWithAnchorAndUnit.hpp +12 -31
  198. package/nitrogen/generated/shared/c++/QueryOptionsWithSortOrder.hpp +12 -31
  199. package/nitrogen/generated/shared/c++/QueryOptionsWithSortOrderAndUnit.hpp +12 -31
  200. package/nitrogen/generated/shared/c++/RelatedCoding.hpp +84 -0
  201. package/nitrogen/generated/shared/c++/SampleType.hpp +87 -0
  202. package/nitrogen/generated/shared/c++/SampleTypeIdentifier.hpp +105 -105
  203. package/nitrogen/generated/shared/c++/SampleTypeIdentifierWriteable.hpp +105 -121
  204. package/nitrogen/generated/shared/c++/StateOfMindSample.hpp +139 -36
  205. package/nitrogen/generated/shared/c++/StateOfMindSamplesWithAnchorResponse.hpp +89 -0
  206. package/nitrogen/generated/shared/c++/StatisticsQueryOptions.hpp +8 -27
  207. package/nitrogen/generated/shared/c++/UserAnnotatedMedication.hpp +90 -0
  208. package/nitrogen/generated/shared/c++/WeatherCondition.hpp +88 -0
  209. package/nitrogen/generated/shared/c++/WorkoutQueryOptions.hpp +12 -37
  210. package/nitrogen/generated/shared/c++/WorkoutQueryOptionsWithAnchor.hpp +12 -37
  211. package/nitrogen/generated/shared/c++/WorkoutSample.hpp +159 -35
  212. package/package.json +1 -1
  213. package/src/healthkit.ios.ts +30 -0
  214. package/src/healthkit.ts +68 -3
  215. package/src/hooks/useStatisticsForQuantity.ts +1 -1
  216. package/src/hooks/useSubscribeToCategorySamples.ts +31 -0
  217. package/src/modules.ts +4 -0
  218. package/src/specs/CategoryTypeModule.nitro.ts +2 -2
  219. package/src/specs/CoreModule.nitro.ts +3 -0
  220. package/src/specs/CorrelationTypeModule.nitro.ts +11 -3
  221. package/src/specs/ElectrocardiogramModule.nitro.ts +1 -1
  222. package/src/specs/HeartbeatSeriesModule.nitro.ts +1 -1
  223. package/src/specs/MedicationModule.nitro.ts +140 -0
  224. package/src/specs/QuantityTypeModule.nitro.ts +4 -7
  225. package/src/specs/StateOfMindModule.nitro.ts +10 -2
  226. package/src/types/CategoryType.ts +15 -22
  227. package/src/types/Constants.ts +3 -0
  228. package/src/types/CorrelationType.ts +10 -15
  229. package/src/types/ElectrocardiogramSample.ts +2 -14
  230. package/src/types/HeartbeatSeries.ts +2 -15
  231. package/src/types/QuantitySample.ts +2 -8
  232. package/src/types/QuantityType.ts +8 -17
  233. package/src/types/QuantityTypeIdentifier.ts +25 -25
  234. package/src/types/QueryOptions.ts +54 -43
  235. package/src/types/Shared.ts +74 -17
  236. package/src/types/StateOfMind.ts +8 -10
  237. package/src/types/Subscriptions.ts +19 -3
  238. package/src/types/WeatherCondition.ts +1 -1
  239. package/src/types/Workouts.ts +28 -91
  240. package/src/utils/getCategorySampleById.ts +1 -1
  241. package/src/utils/getQuantitySampleById.ts +1 -1
  242. package/src/utils/getWorkoutById.ts +1 -2
  243. package/src/utils/subscribeToCategorySamples.ts +38 -0
  244. package/src/utils/subscribeToQuantitySamples.ts +12 -37
  245. package/nitrogen/generated/ios/swift/FilterForSamplesAnd.swift +0 -94
  246. package/nitrogen/generated/ios/swift/FilterForSamplesOr.swift +0 -94
  247. package/nitrogen/generated/ios/swift/PredicateForSamples.swift +0 -21
  248. package/nitrogen/generated/ios/swift/PredicateForWorkouts.swift +0 -23
  249. package/nitrogen/generated/ios/swift/PredicateForWorkoutsAnd.swift +0 -108
  250. package/nitrogen/generated/ios/swift/PredicateForWorkoutsOr.swift +0 -108
  251. package/nitrogen/generated/ios/swift/PredicateFromWorkout.swift +0 -45
  252. package/nitrogen/generated/ios/swift/PredicateWithMetadataOperator.swift +0 -48
  253. package/nitrogen/generated/ios/swift/PredicateWithUUID.swift +0 -35
  254. package/nitrogen/generated/ios/swift/PredicateWithUUIDs.swift +0 -47
  255. package/nitrogen/generated/ios/swift/Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_FilterForSamplesAnd_FilterForSamplesOr.swift +0 -23
  256. package/nitrogen/generated/ios/swift/Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_WorkoutActivityTypePredicate_WorkoutDurationPredicate_PredicateForWorkoutsOr_PredicateForWorkoutsAnd.swift +0 -25
  257. package/nitrogen/generated/ios/swift/WorkoutActivityTypePredicate.swift +0 -35
  258. package/nitrogen/generated/shared/c++/FilterForSamplesAnd.hpp +0 -90
  259. package/nitrogen/generated/shared/c++/FilterForSamplesOr.hpp +0 -90
  260. package/nitrogen/generated/shared/c++/PredicateForWorkoutsAnd.hpp +0 -96
  261. package/nitrogen/generated/shared/c++/PredicateForWorkoutsOr.hpp +0 -96
  262. package/nitrogen/generated/shared/c++/PredicateFromWorkout.hpp +0 -77
  263. package/nitrogen/generated/shared/c++/PredicateWithMetadataOperator.hpp +0 -84
  264. package/nitrogen/generated/shared/c++/PredicateWithUUID.hpp +0 -75
  265. package/nitrogen/generated/shared/c++/PredicateWithUUIDs.hpp +0 -76
  266. package/nitrogen/generated/shared/c++/WorkoutActivityTypePredicate.hpp +0 -76
package/ios/Helpers.swift CHANGED
@@ -9,689 +9,430 @@ import Foundation
9
9
  import HealthKit
10
10
  import NitroModules
11
11
 
12
- func dateOrNilIfZero(_ timestamp: Double?) -> Date? {
13
- if let timestamp = timestamp {
14
- if timestamp == 0 {
15
- return nil
16
- }
17
- return Date.init(timeIntervalSince1970: timestamp)
18
- }
19
- return nil
12
+ func getQueryLimit(_ limit: Double) -> Int {
13
+ if limit == .infinity || limit <= 0 || limit == .nan || limit == .signalingNaN {
14
+ return HKObjectQueryNoLimit
15
+ }
20
16
 
17
+ return Int(limit)
21
18
  }
22
19
 
23
- func getQueryLimit(_ limit: Double?) -> Int {
24
- if let limit = limit {
25
- if limit == .infinity || limit <= 0 {
26
- return HKObjectQueryNoLimit
27
- }
28
-
29
- return Int(limit)
30
- }
31
-
32
- return HKObjectQueryNoLimit
20
+ struct AnchoredQueryResponse {
21
+ var samples: [HKSample]
22
+ var deletedSamples: [DeletedSample]
23
+ var newAnchor: String
33
24
  }
34
25
 
35
- func createPredicateForWorkout(filter: PredicateForWorkouts) throws -> NSPredicate {
36
- switch filter {
37
- case .first(let uuidWrapper):
38
- return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
39
- case .second(let uuidsWrapper):
40
- return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
41
- case .third(let metadataKey):
42
- return try createMetadataPredicate(metadataKey: metadataKey)
43
- case .fourth(let dateFilter):
44
- return createDatePredicate(dateFilter: dateFilter)
45
- case .fifth(let w):
46
- if let w = w.workout as? WorkoutProxy {
47
- return w.workoutPredicate
48
- }
49
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
50
- case .sixth(let activityType):
51
- if let activityType = HKWorkoutActivityType.init(rawValue: UInt(activityType.workoutActivityType.rawValue)) {
52
- return HKQuery.predicateForWorkouts(with: activityType)
53
- } else {
54
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized workoutActivityType with identifier \(activityType.workoutActivityType.rawValue)")
55
- }
56
- case .seventh(let durationPredicate):
57
- if let op = NSComparisonPredicate.Operator(rawValue: UInt(durationPredicate.predicateOperator.rawValue)) {
58
- return HKQuery.predicateForWorkouts(with: op, duration: durationPredicate.durationInSeconds)
59
- }
60
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized workout duration predicate operator \(durationPredicate.predicateOperator.rawValue)")
61
- }
62
- }
26
+ func sampleAnchoredQueryAsync(
27
+ sampleType: HKSampleType,
28
+ limit: Double,
29
+ queryAnchor: String?,
30
+ predicate: NSPredicate?
31
+ ) async throws -> AnchoredQueryResponse {
32
+ let queryAnchor = try deserializeHKQueryAnchor(base64String: queryAnchor)
33
+
34
+ return try await withCheckedThrowingContinuation { continuation in
35
+ let query = HKAnchoredObjectQuery(
36
+ type: sampleType,
37
+ predicate: predicate,
38
+ anchor: queryAnchor,
39
+ limit: getQueryLimit(limit)
40
+ ) {
41
+ (
42
+ _: HKAnchoredObjectQuery, samples: [HKSample]?, deletedSamples: [HKDeletedObject]?,
43
+ newAnchor:
44
+ HKQueryAnchor?, error: Error?
45
+ ) in
46
+ if let error = error {
47
+ return continuation.resume(throwing: error)
48
+ }
63
49
 
64
- func createPredicateForWorkout(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_WorkoutActivityTypePredicate_WorkoutDurationPredicate_PredicateForWorkoutsOr_PredicateForWorkoutsAnd?) throws -> NSPredicate? {
65
- if let filter = filter {
66
- switch filter {
67
- case .first(let uuidWrapper):
68
- return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
69
- case .second(let uuidsWrapper):
70
- return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
71
- case .third(let metadataKey):
72
- return try createMetadataPredicate(metadataKey: metadataKey)
73
- case .fourth(let dateFilter):
74
- return createDatePredicate(dateFilter: dateFilter)
75
- case .fifth(let w):
76
- if let w = w.workout as? WorkoutProxy {
77
- return w.workoutPredicate
78
- }
79
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
80
- case .sixth(let activityType):
81
- if let activityType = HKWorkoutActivityType.init(rawValue: UInt(activityType.workoutActivityType.rawValue)) {
82
- return HKQuery.predicateForWorkouts(with: activityType)
83
- } else {
84
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized workoutActivityType with identifier \(activityType.workoutActivityType.rawValue)")
85
- }
86
- case .seventh(let durationPredicate):
87
- if let op = NSComparisonPredicate.Operator(rawValue: UInt(durationPredicate.predicateOperator.rawValue)) {
88
- return HKQuery.predicateForWorkouts(with: op, duration: durationPredicate.durationInSeconds)
89
- }
90
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized workout duration predicate operator \(durationPredicate.predicateOperator.rawValue)")
91
-
92
- case .eigth(let or):
93
- return NSCompoundPredicate.init(andPredicateWithSubpredicates: try or.OR.map { predicate in
94
- return try createPredicateForWorkout(filter: predicate)
95
- })
96
- case .ninth(let and):
97
- return NSCompoundPredicate.init(orPredicateWithSubpredicates: try and.AND
98
- .map { predicate in
99
- return try createPredicateForWorkout(filter: predicate)
100
- })
101
- }
50
+ if let samples = samples, let deletedSamples = deletedSamples,
51
+ let newAnchor = serializeAnchor(anchor: newAnchor) {
52
+ return continuation.resume(
53
+ returning: AnchoredQueryResponse(
54
+ samples: samples,
55
+ deletedSamples: deletedSamples.map({ deletedSample in
56
+ return serializeDeletedSample(sample: deletedSample)
57
+ }),
58
+ newAnchor: newAnchor
59
+ )
60
+ )
61
+ }
62
+
63
+ return continuation.resume(
64
+ throwing: runtimeErrorWithPrefix("Unexpected empty response"))
102
65
  }
103
66
 
104
- return nil
67
+ store.execute(query)
68
+ }
105
69
  }
106
70
 
107
- func createDatePredicate(dateFilter: PredicateWithStartAndEnd) -> NSPredicate {
108
- let strictStartDate = dateFilter.strictStartDate ?? false
109
- let strictEndDate = dateFilter.strictEndDate ?? false
110
-
111
- let options: HKQueryOptions = strictStartDate && strictEndDate
112
- ? [.strictStartDate, .strictEndDate]
113
- : strictEndDate
114
- ? .strictEndDate
115
- : strictStartDate
116
- ? .strictStartDate
117
- : []
118
-
119
- return HKQuery.predicateForSamples(
120
- withStart: dateFilter.startDate,
121
- end: dateFilter.endDate,
122
- options: options
123
- )
71
+ func serializeAnchor(anchor: HKQueryAnchor?) -> String? {
72
+ return toBase64(anchor)
124
73
  }
125
74
 
126
- func createUUIDsPredicate(uuidsWrapper: PredicateWithUUIDs) -> NSPredicate {
127
- let uuids = uuidsWrapper.uuids.compactMap { uuidStr -> UUID? in
128
- do {
129
- let uuid = try initializeUUID(uuidStr)
130
- return uuid
131
- } catch {
132
- print(error.localizedDescription)
133
- return nil
134
- }
135
- }
136
- return HKQuery.predicateForObjects(with: Set(uuids))
75
+ func toBase64(_ data: Any?) -> String? {
76
+ if let data = data {
77
+ let data = NSKeyedArchiver.archivedData(withRootObject: data)
78
+ let encoded = data.base64EncodedString()
79
+
80
+ return encoded
81
+ }
82
+
83
+ return nil
137
84
  }
138
85
 
139
- func createMetadataPredicate(metadataKey: PredicateWithMetadataKey) throws -> NSPredicate {
140
- guard let valueVariant = metadataKey.value else {
141
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
142
- }
86
+ func sampleQueryAsync(
87
+ sampleType: HKSampleType,
88
+ limit: Double,
89
+ predicate: NSPredicate?,
90
+ sortDescriptors: [NSSortDescriptor]?
91
+ ) async throws -> [HKSample] {
92
+ let limit = getQueryLimit(limit)
93
+ return try await withCheckedThrowingContinuation { continuation in
94
+ let q = HKSampleQuery(
95
+ sampleType: sampleType,
96
+ predicate: predicate,
97
+ limit: limit,
98
+ sortDescriptors: sortDescriptors,
99
+ ) { (_: HKSampleQuery, samples: [HKSample]?, error: Error?) in
100
+ if let error = error {
101
+ return continuation.resume(throwing: error)
102
+ }
143
103
 
144
- let actualValue: Any
145
-
146
- switch valueVariant {
147
- case .first(let boolValue):
148
- actualValue = NSNumber(value: boolValue ? 1 : 0)
149
- case .second(let stringValue):
150
- actualValue = stringValue
151
- case .third(let doubleValue):
152
- actualValue = NSNumber(value: doubleValue)
153
- case .fourth(let dateValue):
154
- actualValue = dateValue
155
- }
104
+ if let samples = samples {
105
+ return continuation.resume(returning: samples)
106
+ }
156
107
 
157
- let operatorType: NSComparisonPredicate.Operator
158
-
159
- if let operatorTypeValue = metadataKey.operatorType {
160
- switch operatorTypeValue {
161
- case PredicateWithMetadataOperator.equalto:
162
- operatorType = .equalTo
163
- case PredicateWithMetadataOperator.notequalto:
164
- operatorType = .notEqualTo
165
- case PredicateWithMetadataOperator.greaterthan:
166
- operatorType = .greaterThan
167
- case PredicateWithMetadataOperator.lessthan:
168
- operatorType = .lessThan
169
- default:
170
- throw RuntimeError.error(withMessage: "Unsupported operator: \(operatorTypeValue)")
171
- }
172
- } else {
173
- operatorType = .equalTo
108
+ return continuation.resume(
109
+ throwing: runtimeErrorWithPrefix("Unexpected empty response"))
174
110
  }
175
111
 
176
- return HKQuery.predicateForObjects(
177
- withMetadataKey: metadataKey.withMetadataKey,
178
- operatorType: operatorType,
179
- value: actualValue
180
- )
112
+ store.execute(q)
113
+ }
181
114
  }
182
115
 
183
- func createPredicate(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_FilterForSamplesAnd_FilterForSamplesOr?) throws -> NSPredicate? {
184
- if let filter = filter {
185
- switch filter {
186
- case .first(let uuidWrapper):
187
- return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
188
- case .second(let uuidsWrapper):
189
- return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
190
- case .third(let metadataKey):
191
- return try createMetadataPredicate(metadataKey: metadataKey)
192
- case .fourth(let dateFilter):
193
- return createDatePredicate(dateFilter: dateFilter)
194
- case .fifth(let w):
195
- if let w = w.workout as? WorkoutProxy {
196
- return w.workoutPredicate
197
- }
198
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
199
- case .sixth(let and):
200
- return NSCompoundPredicate.init(andPredicateWithSubpredicates: try and.AND.map { predicate in
201
- return try createPredicateForSamples(filter: predicate)
202
- })
203
- case .seventh(let or):
204
- return NSCompoundPredicate.init(orPredicateWithSubpredicates: try or.OR
205
- .map { predicate in
206
- return try createPredicateForSamples(filter: predicate)
207
- })
208
- }
116
+ func saveAsync(sample: HKObject) async throws -> Bool {
117
+ return try await withCheckedThrowingContinuation { continuation in
118
+ store.save(sample) { (success: Bool, error: Error?) in
119
+ if let error = error {
120
+ continuation.resume(throwing: error)
121
+ } else {
122
+ continuation.resume(returning: success)
123
+ }
209
124
  }
210
- return nil
125
+ }
211
126
  }
212
127
 
213
- func createPredicateForSamples(filter: PredicateForSamples) throws -> NSPredicate {
214
- switch filter {
215
- case .first(let uuidWrapper):
216
- return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
217
- case .second(let uuidsWrapper):
218
- return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
219
- case .third(let metadataKey):
220
- return try createMetadataPredicate(metadataKey: metadataKey)
221
- case .fourth(let dateFilter):
222
- return createDatePredicate(dateFilter: dateFilter)
223
- case .fifth(let w):
224
- if let w = w.workout as? WorkoutProxy {
225
- return w.workoutPredicate
226
- }
227
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
228
- }
128
+ func getSortDescriptors(ascending: Bool?) -> [NSSortDescriptor] {
129
+ return [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: ascending ?? false)]
229
130
  }
230
131
 
231
- func createPredicateForSamples(filter: FilterForSamples) throws -> NSPredicate {
232
- switch filter {
233
- case .first(let uuidWrapper):
234
- return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
235
- case .second(let uuidsWrapper):
236
- return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
237
- case .third(let metadataKey):
238
- return try createMetadataPredicate(metadataKey: metadataKey)
239
- case .fourth(let dateFilter):
240
- return createDatePredicate(dateFilter: dateFilter)
241
- case .fifth(let w):
242
- if let w = w.workout as? WorkoutProxy {
243
- return w.workoutPredicate
244
- }
245
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
246
- case .sixth(let and):
247
- return NSCompoundPredicate.init(andPredicateWithSubpredicates: try and.AND.map { predicate in
248
- return try createPredicateForSamples(filter: predicate)
249
- })
250
- case .seventh(let or):
251
- return NSCompoundPredicate.init(orPredicateWithSubpredicates: try or.OR
252
- .map { predicate in
253
- return try createPredicateForSamples(filter: predicate)
254
- })
132
+ func fromBase64(base64String: String?) throws -> Any? {
133
+ if let base64String = base64String {
134
+ if base64String.isEmpty {
135
+ return nil
255
136
  }
256
- }
257
137
 
258
- func createPredicateForSamples(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_FilterForSamplesAnd_FilterForSamplesOr) throws -> NSPredicate {
259
- switch filter {
260
- case .first(let uuidWrapper):
261
- return HKQuery.predicateForObject(with: try initializeUUID(uuidWrapper.uuid))
262
- case .second(let uuidsWrapper):
263
- return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
264
- case .third(let metadataKey):
265
- return try createMetadataPredicate(metadataKey: metadataKey)
266
- case .fourth(let dateFilter):
267
- return createDatePredicate(dateFilter: dateFilter)
268
- case .fifth(let w):
269
- if let w = w.workout as? WorkoutProxy {
270
- return w.workoutPredicate
271
- }
272
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize workout for filter")
273
- case .sixth(let and):
274
- return NSCompoundPredicate.init(andPredicateWithSubpredicates: try and.AND.map { predicate in
275
- return try createPredicateForSamples(filter: predicate)
276
- })
277
- case .seventh(let or):
278
- return NSCompoundPredicate.init(orPredicateWithSubpredicates: try or.OR
279
- .map { predicate in
280
- return try createPredicateForSamples(filter: predicate)
281
- })
138
+ // Step 1: Decode the base64 string to a Data object
139
+ guard let data = Data(base64Encoded: base64String) else {
140
+ throw runtimeErrorWithPrefix("Invalid base64 string: \(base64String)")
282
141
  }
283
- }
284
-
285
- func getSortDescriptors(ascending: Bool?) -> [NSSortDescriptor] {
286
- return [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: ascending ?? false)]
287
- }
288
142
 
289
- func getSortDescsdsdriptors(ascending: Bool?) -> [NSSortDescriptor] {
290
- return [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: ascending ?? false)]
143
+ // Step 2: Use NSKeyedUnarchiver to unarchive the data and create an HKQueryAnchor object
144
+ do {
145
+ let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
146
+ unarchiver.requiresSecureCoding = true
147
+ return try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
148
+ } catch {
149
+ throw runtimeErrorWithPrefix(
150
+ "Error recreating HKQueryAnchor object: \(error.localizedDescription)")
151
+ }
152
+ }
153
+ return nil
291
154
  }
292
155
 
293
156
  func deserializeHKQueryAnchor(base64String: String?) throws -> HKQueryAnchor? {
294
- if let base64String = base64String {
295
- if base64String.isEmpty {
296
- return nil
297
- }
298
-
299
- // Step 1: Decode the base64 string to a Data object
300
- guard let data = Data(base64Encoded: base64String) else {
301
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Invalid base64 string: \(base64String)")
302
- }
303
-
304
- // Step 2: Use NSKeyedUnarchiver to unarchive the data and create an HKQueryAnchor object
305
- do {
306
- let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
307
- unarchiver.requiresSecureCoding = true
308
- let anchor = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
309
-
310
- return anchor as? HKQueryAnchor
311
- } catch {
312
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Error recreating HKQueryAnchor object: \(error.localizedDescription)")
313
- }
314
- }
315
- return nil
157
+ return try fromBase64(base64String: base64String) as? HKQueryAnchor
316
158
  }
317
159
 
318
160
  func initializeCategoryType(_ identifier: String) throws -> HKCategoryType {
319
- let identifier = HKCategoryTypeIdentifier(rawValue: identifier)
320
- if let sampleType = HKSampleType.categoryType(forIdentifier: identifier) {
321
- return sampleType
322
- }
161
+ let identifier = HKCategoryTypeIdentifier(rawValue: identifier)
162
+ if let sampleType = HKSampleType.categoryType(forIdentifier: identifier) {
163
+ return sampleType
164
+ }
323
165
 
324
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized categoryType with identifier \(identifier)")
166
+ throw runtimeErrorWithPrefix(
167
+ "Failed to initialize unrecognized categoryType with identifier \(identifier)")
325
168
  }
326
169
 
327
170
  func initializeWorkoutActivityType(_ typeIdentifier: UInt) throws -> HKWorkoutActivityType {
328
- if let type = HKWorkoutActivityType.init(rawValue: typeIdentifier) {
329
- return type
330
- }
171
+ if let type = HKWorkoutActivityType.init(rawValue: typeIdentifier) {
172
+ return type
173
+ }
331
174
 
332
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized quantityType with identifier \(typeIdentifier)")
175
+ throw runtimeErrorWithPrefix(
176
+ "Failed to initialize unrecognized quantityType with identifier \(typeIdentifier)")
333
177
  }
334
178
 
335
179
  func initializeQuantityType(_ identifier: String) throws -> HKQuantityType {
336
- let identifier = HKQuantityTypeIdentifier(rawValue: identifier)
180
+ let identifier = HKQuantityTypeIdentifier(rawValue: identifier)
337
181
 
338
- if let sampleType = HKSampleType.quantityType(forIdentifier: identifier) {
339
- return sampleType
340
- }
182
+ if let sampleType = HKSampleType.quantityType(forIdentifier: identifier) {
183
+ return sampleType
184
+ }
341
185
 
342
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized quantityType with identifier \(identifier)")
186
+ throw runtimeErrorWithPrefix(
187
+ "Failed to initialize unrecognized quantityType with identifier \(identifier)")
343
188
  }
344
189
 
345
190
  func initializeCorrelationType(_ identifier: String) throws -> HKCorrelationType {
346
- let identifier = HKCorrelationTypeIdentifier(rawValue: identifier)
191
+ let identifier = HKCorrelationTypeIdentifier(rawValue: identifier)
347
192
 
348
- if let sampleType = HKSampleType.correlationType(forIdentifier: identifier) {
349
- return sampleType
350
- }
193
+ if let sampleType = HKSampleType.correlationType(forIdentifier: identifier) {
194
+ return sampleType
195
+ }
351
196
 
352
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized correlationType with identifier \(identifier)")
197
+ throw runtimeErrorWithPrefix(
198
+ "Failed to initialize unrecognized correlationType with identifier \(identifier)")
353
199
  }
354
200
 
355
201
  func initializeSeriesType(_ identifier: String) throws -> HKSeriesType {
356
- if let seriesType = HKObjectType.seriesType(forIdentifier: identifier) {
357
- return seriesType
358
- }
202
+ if let seriesType = HKObjectType.seriesType(forIdentifier: identifier) {
203
+ return seriesType
204
+ }
359
205
 
360
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized seriesType with identifier \(identifier)")
206
+ throw runtimeErrorWithPrefix(
207
+ "Failed to initialize unrecognized seriesType with identifier \(identifier)")
361
208
  }
362
209
 
363
210
  func sampleTypeFrom(sampleTypeIdentifier: SampleTypeIdentifier) throws -> HKSampleType {
364
- if let sampleType = try sampleTypeFromStringNullable(typeIdentifier: sampleTypeIdentifier.stringValue) {
365
- return sampleType
366
- }
367
-
368
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized sampleType with identifier \(sampleTypeIdentifier.stringValue)")
211
+ if let sampleType = try sampleTypeFromStringNullable(
212
+ typeIdentifier: sampleTypeIdentifier.stringValue) {
213
+ return sampleType
214
+ }
215
+
216
+ throw runtimeErrorWithPrefix(
217
+ "Failed to initialize unrecognized sampleType with identifier \(sampleTypeIdentifier.stringValue)"
218
+ )
369
219
  }
370
220
 
371
- func sampleTypeFrom(sampleTypeIdentifierWriteable: SampleTypeIdentifierWriteable) throws -> HKSampleType {
372
- if let sampleType = try sampleTypeFromStringNullable(typeIdentifier: sampleTypeIdentifierWriteable.stringValue) {
373
- return sampleType
374
- }
221
+ func sampleTypeFrom(sampleTypeIdentifierWriteable: SampleTypeIdentifierWriteable) throws
222
+ -> HKSampleType {
223
+ if let sampleType = try sampleTypeFromStringNullable(
224
+ typeIdentifier: sampleTypeIdentifierWriteable.stringValue) {
225
+ return sampleType
226
+ }
375
227
 
376
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed to initialize unrecognized sampleType with identifier \(sampleTypeIdentifierWriteable.stringValue)")
228
+ throw runtimeErrorWithPrefix(
229
+ "Failed to initialize unrecognized sampleType with identifier \(sampleTypeIdentifierWriteable.stringValue)"
230
+ )
377
231
  }
378
232
 
379
233
  private func sampleTypeFromStringNullable(typeIdentifier: String) throws -> HKSampleType? {
380
- if typeIdentifier.starts(with: HKQuantityTypeIdentifier_PREFIX) {
381
- return try initializeQuantityType(typeIdentifier)
382
- }
234
+ if typeIdentifier.starts(with: HKQuantityTypeIdentifier_PREFIX) {
235
+ return try initializeQuantityType(typeIdentifier)
236
+ }
383
237
 
384
- if typeIdentifier.starts(with: HKCategoryTypeIdentifier_PREFIX) {
385
- return try initializeCategoryType(typeIdentifier)
386
- }
238
+ if typeIdentifier.starts(with: HKCategoryTypeIdentifier_PREFIX) {
239
+ return try initializeCategoryType(typeIdentifier)
240
+ }
387
241
 
388
- if typeIdentifier.starts(with: HKCorrelationTypeIdentifier_PREFIX) {
389
- return try initializeCorrelationType(typeIdentifier)
390
- }
242
+ if typeIdentifier.starts(with: HKCorrelationTypeIdentifier_PREFIX) {
243
+ return try initializeCorrelationType(typeIdentifier)
244
+ }
391
245
 
392
- if typeIdentifier == HKWorkoutTypeIdentifier {
393
- return HKSampleType.workoutType()
394
- }
246
+ if typeIdentifier == HKWorkoutTypeIdentifier {
247
+ return HKSampleType.workoutType()
248
+ }
395
249
 
396
- if #available(iOS 11.0, *) {
397
- if typeIdentifier == HKWorkoutRouteTypeIdentifier {
398
- return try initializeSeriesType(typeIdentifier)
399
- }
250
+ if #available(iOS 11.0, *) {
251
+ if typeIdentifier == HKWorkoutRouteTypeIdentifier {
252
+ return try initializeSeriesType(typeIdentifier)
400
253
  }
254
+ }
401
255
 
402
- if #available(iOS 13, *) {
403
- if typeIdentifier == HKAudiogramTypeIdentifier {
404
- return HKObjectType.audiogramSampleType()
405
- }
256
+ if #available(iOS 13, *) {
257
+ if typeIdentifier == HKAudiogramTypeIdentifier {
258
+ return HKObjectType.audiogramSampleType()
259
+ }
406
260
 
407
- if typeIdentifier == HKDataTypeIdentifierHeartbeatSeries {
408
- return try initializeSeriesType(typeIdentifier)
409
- }
261
+ if typeIdentifier == HKDataTypeIdentifierHeartbeatSeries {
262
+ return try initializeSeriesType(typeIdentifier)
263
+ }
410
264
 
411
- if typeIdentifier == HKAudiogramTypeIdentifier {
412
- return HKSampleType.audiogramSampleType()
413
- }
265
+ if typeIdentifier == HKAudiogramTypeIdentifier {
266
+ return HKSampleType.audiogramSampleType()
414
267
  }
268
+ }
415
269
 
416
- if #available(iOS 14, *) {
417
- if typeIdentifier == HKElectrocardiogramType {
418
- return HKSampleType.electrocardiogramType()
419
- }
270
+ if #available(iOS 14, *) {
271
+ if typeIdentifier == HKElectrocardiogramType {
272
+ return HKSampleType.electrocardiogramType()
420
273
  }
274
+ }
421
275
 
422
- #if compiler(>=6)
423
- if #available(iOS 18, *) {
424
- if typeIdentifier == HKStateOfMindTypeIdentifier {
425
- return HKObjectType.stateOfMindType()
426
- }
427
- }
428
- #endif
276
+ #if compiler(>=6)
277
+ if #available(iOS 18, *) {
278
+ if typeIdentifier == HKStateOfMindTypeIdentifier {
279
+ return HKObjectType.stateOfMindType()
280
+ }
281
+ }
282
+ #endif
429
283
 
430
- return nil
284
+ return nil
431
285
  }
432
286
 
433
287
  func objectTypesFromArray(typeIdentifiers: [ObjectTypeIdentifier]) -> Set<HKObjectType> {
434
- var share = Set<HKObjectType>()
435
- for typeIdentifier in typeIdentifiers {
436
- do {
437
- let objectType = try objectTypeFrom(objectTypeIdentifier: typeIdentifier)
438
- share.insert(objectType)
439
- } catch {
440
- print(error.localizedDescription)
441
- }
442
- }
443
- return share
288
+ var share = Set<HKObjectType>()
289
+ for typeIdentifier in typeIdentifiers {
290
+ do {
291
+ let objectType = try objectTypeFrom(objectTypeIdentifier: typeIdentifier)
292
+ share.insert(objectType)
293
+ } catch {
294
+ warnWithPrefix("objectTypesFromArray: \(error.localizedDescription)")
295
+ }
296
+ }
297
+ return share
444
298
  }
445
299
 
446
300
  func initializeUUID(_ uuidString: String) throws -> UUID {
447
- if let uuid = UUID(uuidString: uuidString) {
448
- return uuid
449
- }
301
+ if let uuid = UUID(uuidString: uuidString) {
302
+ return uuid
303
+ }
450
304
 
451
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Got invalid UUID: \(uuidString)")
305
+ throw runtimeErrorWithPrefix("Got invalid UUID: \(uuidString)")
452
306
  }
453
307
 
454
308
  func sampleTypesFromArray(typeIdentifiers: [SampleTypeIdentifier]) -> Set<HKSampleType> {
455
- return Set(typeIdentifiers.compactMap { typeIdentifier in
456
- do {
457
- let sampleType = try sampleTypeFrom(sampleTypeIdentifier: typeIdentifier)
458
- return sampleType
459
- } catch {
460
- print(error.localizedDescription)
461
- }
462
- return nil
309
+ return Set(
310
+ typeIdentifiers.compactMap { typeIdentifier in
311
+ do {
312
+ let sampleType = try sampleTypeFrom(sampleTypeIdentifier: typeIdentifier)
313
+ return sampleType
314
+ } catch {
315
+ warnWithPrefix("sampleTypesFromArray: \(error.localizedDescription)")
316
+ }
317
+ return nil
463
318
  })
464
319
  }
465
320
 
466
- func sampleTypesFromArray(typeIdentifiersWriteable: [SampleTypeIdentifierWriteable]) -> Set<HKSampleType> {
467
- return Set(typeIdentifiersWriteable.compactMap { typeIdentifier in
468
- do {
469
- let sampleType = try sampleTypeFrom(sampleTypeIdentifierWriteable: typeIdentifier)
470
- return sampleType
471
- } catch {
472
- print(error.localizedDescription)
473
- }
474
- return nil
321
+ func sampleTypesFromArray(typeIdentifiersWriteable: [SampleTypeIdentifierWriteable]) -> Set<
322
+ HKSampleType
323
+ > {
324
+ return Set(
325
+ typeIdentifiersWriteable.compactMap { typeIdentifier in
326
+ do {
327
+ let sampleType = try sampleTypeFrom(sampleTypeIdentifierWriteable: typeIdentifier)
328
+ return sampleType
329
+ } catch {
330
+ warnWithPrefix("sampleTypesFromArray: \(error.localizedDescription)")
331
+ }
332
+ return nil
475
333
  })
476
334
  }
477
335
 
478
336
  // objectType is wider than sampleType, so it uses it under the hood
479
337
  func objectTypeFrom(objectTypeIdentifier: ObjectTypeIdentifier) throws -> HKObjectType {
480
- let typeIdentifier = objectTypeIdentifier.stringValue
481
- if let sampleType = try sampleTypeFromStringNullable(typeIdentifier: typeIdentifier) {
482
- return sampleType
483
- }
338
+ let typeIdentifier = objectTypeIdentifier.stringValue
339
+ if let sampleType = try sampleTypeFromStringNullable(typeIdentifier: typeIdentifier) {
340
+ return sampleType
341
+ }
484
342
 
485
- if typeIdentifier.starts(with: HKCharacteristicTypeIdentifier_PREFIX) {
486
- let identifier = HKCharacteristicTypeIdentifier.init(rawValue: typeIdentifier)
487
- if let type = HKObjectType.characteristicType(forIdentifier: identifier) as HKObjectType? {
488
- return type
489
- }
343
+ if typeIdentifier.starts(with: HKCharacteristicTypeIdentifier_PREFIX) {
344
+ let identifier = HKCharacteristicTypeIdentifier.init(rawValue: typeIdentifier)
345
+ if let type = HKObjectType.characteristicType(forIdentifier: identifier) as HKObjectType? {
346
+ return type
490
347
  }
348
+ }
491
349
 
492
- if typeIdentifier == HKActivitySummaryTypeIdentifier {
493
- return HKObjectType.activitySummaryType()
494
- }
350
+ if typeIdentifier == HKActivitySummaryTypeIdentifier {
351
+ return HKObjectType.activitySummaryType()
352
+ }
495
353
 
496
- throw RuntimeError.error(withMessage: "[react-native-healthkit] Failed initializing unrecognized objectType identifier " + typeIdentifier)
354
+ throw runtimeErrorWithPrefix(
355
+ "Failed initializing unrecognized objectType identifier " + typeIdentifier)
497
356
  }
498
357
 
499
358
  func hkStatisticsOptionsFromOptions(_ options: NSArray) -> HKStatisticsOptions {
500
- var opts = HKStatisticsOptions()
501
-
502
- for o in options {
503
- guard let str = o as? String else { continue }
504
-
505
- switch str {
506
- case "cumulativeSum":
507
- opts.insert(.cumulativeSum)
508
- case "discreteAverage":
509
- opts.insert(.discreteAverage)
510
- case "discreteMax":
511
- opts.insert(.discreteMax)
512
- case "discreteMin":
513
- opts.insert(.discreteMin)
514
- case "duration":
515
- if #available(iOS 13, *) {
516
- opts.insert(.duration)
517
- }
518
- case "mostRecent":
519
- if #available(iOS 13, *) {
520
- opts.insert(.mostRecent)
521
- }
522
- case "separateBySource":
523
- opts.insert(.separateBySource)
524
- default:
525
- continue
526
- }
359
+ var opts = HKStatisticsOptions()
360
+
361
+ for o in options {
362
+ guard let str = o as? String else { continue }
363
+
364
+ switch str {
365
+ case "cumulativeSum":
366
+ opts.insert(.cumulativeSum)
367
+ case "discreteAverage":
368
+ opts.insert(.discreteAverage)
369
+ case "discreteMax":
370
+ opts.insert(.discreteMax)
371
+ case "discreteMin":
372
+ opts.insert(.discreteMin)
373
+ case "duration":
374
+ if #available(iOS 13, *) {
375
+ opts.insert(.duration)
376
+ }
377
+ case "mostRecent":
378
+ if #available(iOS 13, *) {
379
+ opts.insert(.mostRecent)
380
+ }
381
+ case "separateBySource":
382
+ opts.insert(.separateBySource)
383
+ default:
384
+ continue
527
385
  }
386
+ }
528
387
 
529
- return opts
388
+ return opts
530
389
  }
531
390
 
532
391
  func componentsFromInterval(_ interval: NSDictionary) -> DateComponents {
533
- let componentKeys: [String: WritableKeyPath<DateComponents, Int?>] = [
534
- "minute": \.minute,
535
- "hour": \.hour,
536
- "day": \.day,
537
- "month": \.month,
538
- "year": \.year
539
- ]
540
-
541
- var intervalComponents = DateComponents()
542
- for (key, keyPath) in componentKeys {
543
- if let value = interval[key] as? Int {
544
- intervalComponents[keyPath: keyPath] = value
545
- }
546
- }
547
- return intervalComponents
392
+ let componentKeys: [String: WritableKeyPath<DateComponents, Int?>] = [
393
+ "minute": \.minute,
394
+ "hour": \.hour,
395
+ "day": \.day,
396
+ "month": \.month,
397
+ "year": \.year,
398
+ ]
399
+
400
+ var intervalComponents = DateComponents()
401
+ for (key, keyPath) in componentKeys {
402
+ if let value = interval[key] as? Int {
403
+ intervalComponents[keyPath: keyPath] = value
404
+ }
405
+ }
406
+ return intervalComponents
548
407
  }
549
408
 
550
409
  func parseWorkoutConfiguration(_ config: WorkoutConfiguration) -> HKWorkoutConfiguration {
551
- let configuration = HKWorkoutConfiguration()
410
+ let configuration = HKWorkoutConfiguration()
552
411
 
553
- if let activityType = HKWorkoutActivityType(rawValue: UInt(config.activityType.rawValue)) {
554
- configuration.activityType = activityType
555
- }
412
+ if let activityType = HKWorkoutActivityType(rawValue: UInt(config.activityType.rawValue)) {
413
+ configuration.activityType = activityType
414
+ }
556
415
 
557
- if let locationTypeRaw = config.locationType,
558
- let locationType = HKWorkoutSessionLocationType(rawValue: Int(locationTypeRaw.rawValue)) {
559
- configuration.locationType = locationType
560
- }
416
+ if let locationTypeRaw = config.locationType,
417
+ let locationType = HKWorkoutSessionLocationType(rawValue: Int(locationTypeRaw.rawValue)) {
418
+ configuration.locationType = locationType
419
+ }
561
420
 
562
- return configuration
421
+ return configuration
563
422
  }
564
423
 
565
- // Returns all available HKQuantityTypeIdentifier raw values as an array of String
566
- func allQuantityTypeIdentifiers() -> [String] {
567
- let allIdentifiers: [HKQuantityTypeIdentifier] = [
568
- .bodyMassIndex,
569
- .bodyFatPercentage,
570
- .height,
571
- .bodyMass,
572
- .leanBodyMass,
573
- .waistCircumference,
574
- .stepCount,
575
- .distanceWalkingRunning,
576
- .distanceCycling,
577
- .distanceWheelchair,
578
- .basalEnergyBurned,
579
- .activeEnergyBurned,
580
- .flightsClimbed,
581
- .nikeFuel,
582
- .appleExerciseTime,
583
- .pushCount,
584
- .distanceSwimming,
585
- .swimmingStrokeCount,
586
- .vo2Max,
587
- .distanceDownhillSnowSports,
588
- .appleStandTime,
589
- .walkingSpeed,
590
- .walkingDoubleSupportPercentage,
591
- .walkingAsymmetryPercentage,
592
- .walkingStepLength,
593
- .sixMinuteWalkTestDistance,
594
- .stairAscentSpeed,
595
- .stairDescentSpeed,
596
- .heartRate,
597
- .bodyTemperature,
598
- .basalBodyTemperature,
599
- .bloodPressureSystolic,
600
- .bloodPressureDiastolic,
601
- .respiratoryRate,
602
- .restingHeartRate,
603
- .walkingHeartRateAverage,
604
- .heartRateVariabilitySDNN,
605
- .oxygenSaturation,
606
- .peripheralPerfusionIndex,
607
- .bloodGlucose,
608
- .numberOfTimesFallen,
609
- .electrodermalActivity,
610
- .inhalerUsage,
611
- .insulinDelivery,
612
- .bloodAlcoholContent,
613
- .forcedVitalCapacity,
614
- .forcedExpiratoryVolume1,
615
- .peakExpiratoryFlowRate,
616
- .environmentalAudioExposure,
617
- .headphoneAudioExposure,
618
- .dietaryFatTotal,
619
- .dietaryFatPolyunsaturated,
620
- .dietaryFatMonounsaturated,
621
- .dietaryFatSaturated,
622
- .dietaryCholesterol,
623
- .dietarySodium,
624
- .dietaryCarbohydrates,
625
- .dietaryFiber,
626
- .dietarySugar,
627
- .dietaryEnergyConsumed,
628
- .dietaryProtein,
629
- .dietaryVitaminA,
630
- .dietaryVitaminB6,
631
- .dietaryVitaminB12,
632
- .dietaryVitaminC,
633
- .dietaryVitaminD,
634
- .dietaryVitaminE,
635
- .dietaryVitaminK,
636
- .dietaryCalcium,
637
- .dietaryIron,
638
- .dietaryThiamin,
639
- .dietaryRiboflavin,
640
- .dietaryNiacin,
641
- .dietaryFolate,
642
- .dietaryBiotin,
643
- .dietaryPantothenicAcid,
644
- .dietaryPhosphorus,
645
- .dietaryIodine,
646
- .dietaryMagnesium,
647
- .dietaryZinc,
648
- .dietarySelenium,
649
- .dietaryCopper,
650
- .dietaryManganese,
651
- .dietaryChromium,
652
- .dietaryMolybdenum,
653
- .dietaryChloride,
654
- .dietaryPotassium,
655
- .dietaryCaffeine,
656
- .dietaryWater,
657
- .uvExposure
658
- // Add more identifiers as needed for your iOS version
659
- ]
660
- let supported = allIdentifiers.compactMap { identifier in
661
- HKObjectType.quantityType(forIdentifier: identifier) != nil ? identifier.rawValue : nil
662
- }
663
- let missing = allIdentifiers.filter { HKObjectType.quantityType(forIdentifier: $0) == nil }
664
- if !missing.isEmpty {
665
- print("[react-native-healthkit] Warning: The following HKQuantityTypeIdentifiers are not available on this iOS version: \(missing.map { $0.rawValue })")
666
- }
667
- // --- New logic: Warn if any available identifier is not in the hardcoded list ---
668
- // Try common HealthKit identifier strings (brute-force, as Apple does not provide a list)
669
- let knownPrefixes = [
670
- "HKQuantityTypeIdentifier",
671
- "HKQuantityTypeIdentifierDietary",
672
- "HKQuantityTypeIdentifierEnvironmental",
673
- "HKQuantityTypeIdentifierBlood",
674
- "HKQuantityTypeIdentifierBody",
675
- "HKQuantityTypeIdentifierDistance",
676
- "HKQuantityTypeIdentifierHeart",
677
- "HKQuantityTypeIdentifierRespiratory",
678
- "HKQuantityTypeIdentifierWalking",
679
- "HKQuantityTypeIdentifierSwimming",
680
- "HKQuantityTypeIdentifierApple"
681
- ]
682
- var foundButNotListed: [String] = []
683
- // Try all possible identifier strings (brute-force for demonstration, not exhaustive)
684
- for codePoint in 0..<300 {
685
- for prefix in knownPrefixes {
686
- let candidate = prefix + String(codePoint)
687
- if let type = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier(rawValue: candidate)),
688
- !allIdentifiers.contains(where: { $0.rawValue == candidate }) {
689
- foundButNotListed.append(candidate)
690
- }
691
- }
692
- }
693
- if !foundButNotListed.isEmpty {
694
- print("[react-native-healthkit] Warning: The following HKQuantityTypeIdentifiers are available on this iOS version but NOT included in the hardcoded list: \(foundButNotListed)")
695
- }
696
- return supported
424
+ func anyMapToDictionary(_ anyMap: AnyMap) -> [String: Any] {
425
+ var dict = [String: Any]()
426
+ anyMap.getAllKeys().forEach { key in
427
+ dict[key] = getAnyMapValue(anyMap, key: key)
428
+ }
429
+ return dict
430
+ }
431
+
432
+ func runtimeErrorWithPrefix(_ withMessage: String) -> Error {
433
+ return RuntimeError.error(withMessage: "[react-native-healthkit] \(withMessage)")
434
+ }
435
+
436
+ func warnWithPrefix(_ withMessage: String) {
437
+ print("[react-native-healthkit] \(withMessage)")
697
438
  }