@kingstinct/react-native-healthkit 10.0.0 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/ios/CorrelationTypeModule.swift +1 -0
  2. package/ios/Helpers.swift +50 -6
  3. package/ios/QuantityTypeModule.swift +61 -53
  4. package/lib/commonjs/healthkit.js +1 -1
  5. package/lib/module/healthkit.js +1 -1
  6. package/lib/typescript/healthkit.d.ts +4 -4
  7. package/lib/typescript/types/CorrelationType.d.ts +1 -0
  8. package/lib/typescript/types/QuantityType.d.ts +2 -0
  9. package/lib/typescript/types/QueryOptions.d.ts +4 -0
  10. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +62 -0
  11. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +3 -0
  12. package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +3 -0
  13. package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +3 -0
  14. package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +3 -0
  15. package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +3 -0
  16. package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +3 -0
  17. package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +3 -0
  18. package/nitrogen/generated/ios/swift/CorrelationSample.swift +13 -2
  19. package/nitrogen/generated/ios/swift/PredicateWithMetadataKey.swift +94 -2
  20. package/nitrogen/generated/ios/swift/PredicateWithMetadataOperator.swift +48 -0
  21. package/nitrogen/generated/ios/swift/QueryStatisticsResponse.swift +59 -1
  22. package/nitrogen/generated/ios/swift/Variant_String_Double_Bool_Date.swift +18 -0
  23. package/nitrogen/generated/shared/c++/CorrelationSample.hpp +6 -1
  24. package/nitrogen/generated/shared/c++/PredicateWithMetadataKey.hpp +16 -3
  25. package/nitrogen/generated/shared/c++/PredicateWithMetadataOperator.hpp +86 -0
  26. package/nitrogen/generated/shared/c++/QueryStatisticsResponse.hpp +11 -2
  27. package/package.json +1 -1
  28. package/src/healthkit.ts +5 -1
  29. package/src/hooks/queryStatisticsForQuantity.test.ts +32 -0
  30. package/src/types/CorrelationType.ts +1 -0
  31. package/src/types/QuantityType.ts +2 -0
  32. package/src/types/QueryOptions.ts +10 -0
@@ -134,6 +134,7 @@ class CorrelationTypeModule: HybridCorrelationTypeModuleSpec {
134
134
  }
135
135
 
136
136
  return CorrelationSample(
137
+ uuid: correlation.uuid.uuidString,
137
138
  correlationType: CorrelationTypeIdentifier(fromString: correlation.correlationType.identifier)!,
138
139
  objects: objects,
139
140
  metadata: serializeMetadata(correlation.metadata),
package/ios/Helpers.swift CHANGED
@@ -39,7 +39,7 @@ func createPredicateForWorkout(filter: PredicateForWorkouts) throws -> NSPredica
39
39
  case .second(let uuidsWrapper):
40
40
  return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
41
41
  case .third(let metadataKey):
42
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
42
+ return try createMetadataPredicate(metadataKey: metadataKey)
43
43
  case .fourth(let dateFilter):
44
44
  return createDatePredicate(dateFilter: dateFilter)
45
45
  case .fifth(let w):
@@ -69,7 +69,7 @@ func createPredicateForWorkout(filter: Variant_PredicateWithUUID_PredicateWithUU
69
69
  case .second(let uuidsWrapper):
70
70
  return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
71
71
  case .third(let metadataKey):
72
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
72
+ return try createMetadataPredicate(metadataKey: metadataKey)
73
73
  case .fourth(let dateFilter):
74
74
  return createDatePredicate(dateFilter: dateFilter)
75
75
  case .fifth(let w):
@@ -136,6 +136,50 @@ func createUUIDsPredicate(uuidsWrapper: PredicateWithUUIDs) -> NSPredicate {
136
136
  return HKQuery.predicateForObjects(with: Set(uuids))
137
137
  }
138
138
 
139
+ func createMetadataPredicate(metadataKey: PredicateWithMetadataKey) throws -> NSPredicate {
140
+ guard let valueVariant = metadataKey.value else {
141
+ return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
142
+ }
143
+
144
+ let actualValue: Any
145
+
146
+ switch valueVariant {
147
+ case .first(let stringValue):
148
+ actualValue = stringValue
149
+ case .second(let doubleValue):
150
+ actualValue = NSNumber(value: doubleValue)
151
+ case .third(let boolValue):
152
+ actualValue = NSNumber(value: boolValue ? 1 : 0)
153
+ case .fourth(let dateValue):
154
+ actualValue = dateValue
155
+ }
156
+
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
174
+ }
175
+
176
+ return HKQuery.predicateForObjects(
177
+ withMetadataKey: metadataKey.withMetadataKey,
178
+ operatorType: operatorType,
179
+ value: actualValue
180
+ )
181
+ }
182
+
139
183
  func createPredicate(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_PredicateWithMetadataKey_PredicateWithStartAndEnd_PredicateFromWorkout_FilterForSamplesAnd_FilterForSamplesOr?) throws -> NSPredicate? {
140
184
  if let filter = filter {
141
185
  switch filter {
@@ -144,7 +188,7 @@ func createPredicate(filter: Variant_PredicateWithUUID_PredicateWithUUIDs_Predic
144
188
  case .second(let uuidsWrapper):
145
189
  return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
146
190
  case .third(let metadataKey):
147
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
191
+ return try createMetadataPredicate(metadataKey: metadataKey)
148
192
  case .fourth(let dateFilter):
149
193
  return createDatePredicate(dateFilter: dateFilter)
150
194
  case .fifth(let w):
@@ -173,7 +217,7 @@ func createPredicateForSamples(filter: PredicateForSamples) throws -> NSPredicat
173
217
  case .second(let uuidsWrapper):
174
218
  return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
175
219
  case .third(let metadataKey):
176
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
220
+ return try createMetadataPredicate(metadataKey: metadataKey)
177
221
  case .fourth(let dateFilter):
178
222
  return createDatePredicate(dateFilter: dateFilter)
179
223
  case .fifth(let w):
@@ -191,7 +235,7 @@ func createPredicateForSamples(filter: FilterForSamples) throws -> NSPredicate {
191
235
  case .second(let uuidsWrapper):
192
236
  return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
193
237
  case .third(let metadataKey):
194
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
238
+ return try createMetadataPredicate(metadataKey: metadataKey)
195
239
  case .fourth(let dateFilter):
196
240
  return createDatePredicate(dateFilter: dateFilter)
197
241
  case .fifth(let w):
@@ -218,7 +262,7 @@ func createPredicateForSamples(filter: Variant_PredicateWithUUID_PredicateWithUU
218
262
  case .second(let uuidsWrapper):
219
263
  return createUUIDsPredicate(uuidsWrapper: uuidsWrapper)
220
264
  case .third(let metadataKey):
221
- return HKQuery.predicateForObjects(withMetadataKey: metadataKey.withMetadataKey)
265
+ return try createMetadataPredicate(metadataKey: metadataKey)
222
266
  case .fourth(let dateFilter):
223
267
  return createDatePredicate(dateFilter: dateFilter)
224
268
  case .fifth(let w):
@@ -178,71 +178,76 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
178
178
  quantitySamplePredicate: predicate,
179
179
  options: buildStatisticsOptions(statistics: statistics)
180
180
  ) { (_, stats: HKStatistics?, error: Error?) in
181
- if let error = error {
182
- continuation.resume(throwing: error)
183
- return
184
- }
181
+ DispatchQueue.main.async {
182
+ if let error = error {
183
+ continuation.resume(throwing: error)
184
+ return
185
+ }
185
186
 
186
- guard let gottenStats = stats else {
187
- let emptyResponse = QueryStatisticsResponse()
188
- continuation.resume(returning: emptyResponse)
189
- return
190
- }
187
+ guard let gottenStats = stats else {
188
+ let emptyResponse = QueryStatisticsResponse()
189
+ continuation.resume(returning: emptyResponse)
190
+ return
191
+ }
191
192
 
192
- var response = QueryStatisticsResponse()
193
+ var response = QueryStatisticsResponse()
193
194
 
194
- if let averageQuantity = gottenStats.averageQuantity() {
195
- response.averageQuantity = Quantity(
196
- unit: unit.unitString,
197
- quantity: averageQuantity.doubleValue(for: unit)
198
- )
199
- }
200
- if let maximumQuantity = gottenStats.maximumQuantity() {
201
- response.maximumQuantity = Quantity(
202
- unit: unit.unitString,
203
- quantity: maximumQuantity.doubleValue(for: unit)
204
- )
205
- }
206
- if let minimumQuantity = gottenStats.minimumQuantity() {
207
- response.minimumQuantity = Quantity(
208
- unit: unit.unitString,
209
- quantity: minimumQuantity.doubleValue(for: unit)
210
- )
211
- }
212
- if let sumQuantity = gottenStats.sumQuantity() {
213
- response.sumQuantity = Quantity(
214
- unit: unit.unitString,
215
- quantity: sumQuantity.doubleValue(for: unit)
216
- )
217
- }
195
+ response.startDate = gottenStats.startDate
196
+ response.endDate = gottenStats.endDate
218
197
 
219
- if #available(iOS 12, *) {
220
- if let mostRecent = gottenStats.mostRecentQuantity() {
221
- response.mostRecentQuantity = Quantity(
198
+ if let averageQuantity = gottenStats.averageQuantity() {
199
+ response.averageQuantity = Quantity(
222
200
  unit: unit.unitString,
223
- quantity: mostRecent.doubleValue(for: unit)
201
+ quantity: averageQuantity.doubleValue(for: unit)
224
202
  )
225
203
  }
226
-
227
- if let mostRecentDateInterval = gottenStats.mostRecentQuantityDateInterval() {
228
- response.mostRecentQuantityDateInterval = QuantityDateInterval(
229
- from: mostRecentDateInterval.start,
230
- to: mostRecentDateInterval.end
204
+ if let maximumQuantity = gottenStats.maximumQuantity() {
205
+ response.maximumQuantity = Quantity(
206
+ unit: unit.unitString,
207
+ quantity: maximumQuantity.doubleValue(for: unit)
231
208
  )
232
209
  }
233
- }
234
-
235
- if #available(iOS 13, *) {
236
- if let duration = gottenStats.duration() {
237
- let durationUnit = HKUnit.second()
238
- response.duration = Quantity(
239
- unit: durationUnit.unitString,
240
- quantity: duration.doubleValue(for: durationUnit)
210
+ if let minimumQuantity = gottenStats.minimumQuantity() {
211
+ response.minimumQuantity = Quantity(
212
+ unit: unit.unitString,
213
+ quantity: minimumQuantity.doubleValue(for: unit)
214
+ )
215
+ }
216
+ if let sumQuantity = gottenStats.sumQuantity() {
217
+ response.sumQuantity = Quantity(
218
+ unit: unit.unitString,
219
+ quantity: sumQuantity.doubleValue(for: unit)
241
220
  )
242
221
  }
243
- }
244
222
 
245
- continuation.resume(returning: response)
223
+ if #available(iOS 12, *) {
224
+ if let mostRecent = gottenStats.mostRecentQuantity() {
225
+ response.mostRecentQuantity = Quantity(
226
+ unit: unit.unitString,
227
+ quantity: mostRecent.doubleValue(for: unit)
228
+ )
229
+ }
230
+
231
+ if let mostRecentDateInterval = gottenStats.mostRecentQuantityDateInterval() {
232
+ response.mostRecentQuantityDateInterval = QuantityDateInterval(
233
+ from: mostRecentDateInterval.start,
234
+ to: mostRecentDateInterval.end
235
+ )
236
+ }
237
+ }
238
+
239
+ if #available(iOS 13, *) {
240
+ if let duration = gottenStats.duration() {
241
+ let durationUnit = HKUnit.second()
242
+ response.duration = Quantity(
243
+ unit: durationUnit.unitString,
244
+ quantity: duration.doubleValue(for: durationUnit)
245
+ )
246
+ }
247
+ }
248
+
249
+ continuation.resume(returning: response)
250
+ }
246
251
  }
247
252
 
248
253
  store.execute(query)
@@ -323,6 +328,9 @@ class QuantityTypeModule: HybridQuantityTypeModuleSpec {
323
328
  statistics.enumerateStatistics(from: enumerateFrom, to: enumerateTo) { stats, _ in
324
329
  var response = QueryStatisticsResponse()
325
330
 
331
+ response.startDate = stats.startDate
332
+ response.endDate = stats.endDate
333
+
326
334
  if let averageQuantity = stats.averageQuantity() {
327
335
  response.averageQuantity = Quantity(
328
336
  unit: unit.unitString,
@@ -74,7 +74,7 @@ exports.queryStatisticsCollectionForQuantity = UnavailableFnFromModule('querySta
74
74
  exports.saveQuantitySample = UnavailableFnFromModule('saveQuantitySample', Promise.resolve(false));
75
75
  exports.isQuantityCompatibleWithUnit = UnavailableFnFromModule('isQuantityCompatibleWithUnit', false);
76
76
  // CategoryTypeModule functions
77
- function queryCategorySamples(_categoryTypeIdentifier) {
77
+ function queryCategorySamples(_categoryTypeIdentifier, _options) {
78
78
  if (react_native_1.Platform.OS !== 'ios' && !hasWarned) {
79
79
  console.warn(notAvailableError);
80
80
  hasWarned = true;
@@ -52,7 +52,7 @@ export const queryStatisticsCollectionForQuantity = UnavailableFnFromModule('que
52
52
  export const saveQuantitySample = UnavailableFnFromModule('saveQuantitySample', Promise.resolve(false));
53
53
  export const isQuantityCompatibleWithUnit = UnavailableFnFromModule('isQuantityCompatibleWithUnit', false);
54
54
  // CategoryTypeModule functions
55
- export function queryCategorySamples(_categoryTypeIdentifier) {
55
+ export function queryCategorySamples(_categoryTypeIdentifier, _options) {
56
56
  if (Platform.OS !== 'ios' && !hasWarned) {
57
57
  console.warn(notAvailableError);
58
58
  hasWarned = true;
@@ -5,7 +5,7 @@ import type { CategorySamplesWithAnchorResponseTyped, CategorySampleTyped } from
5
5
  import type { CategoryTypeIdentifier } from './types/CategoryTypeIdentifier';
6
6
  import { BiologicalSex, BloodType, FitzpatrickSkinType, WheelchairUse } from './types/Characteristics';
7
7
  import type { QuantitySample } from './types/QuantitySample';
8
- import type { QueryOptionsWithAnchor } from './types/QueryOptions';
8
+ import type { QueryOptionsWithAnchor, QueryOptionsWithSortOrder } from './types/QueryOptions';
9
9
  export * from './types';
10
10
  export declare const authorizationStatusFor: (type: import("./types").ObjectTypeIdentifier) => AuthorizationStatus;
11
11
  export declare const disableAllBackgroundDelivery: () => Promise<boolean>;
@@ -35,18 +35,18 @@ export declare const queryStatisticsForQuantity: (identifier: import("./types").
35
35
  export declare const queryStatisticsCollectionForQuantity: (identifier: import("./types").QuantityTypeIdentifier, statistics: readonly import("./types").StatisticsOptions[], anchorDate: string, intervalComponents: import("./types").IntervalComponents, options?: import("./types").StatisticsQueryOptions) => Promise<readonly import("./types").QueryStatisticsResponse[]>;
36
36
  export declare const saveQuantitySample: (identifier: import("./types").QuantityTypeIdentifier, unit: string, value: number, start: Date, end: Date, metadata: import("react-native-nitro-modules").AnyMap) => Promise<boolean>;
37
37
  export declare const isQuantityCompatibleWithUnit: (identifier: import("./types").QuantityTypeIdentifier, unit: string) => boolean;
38
- export declare function queryCategorySamples<T extends CategoryTypeIdentifier>(_categoryTypeIdentifier: T): Promise<CategorySampleTyped<T>[]>;
38
+ export declare function queryCategorySamples<T extends CategoryTypeIdentifier>(_categoryTypeIdentifier: T, _options?: QueryOptionsWithSortOrder): Promise<CategorySampleTyped<T>[]>;
39
39
  export declare function queryCategorySamplesWithAnchor<T extends CategoryTypeIdentifier>(_categoryTypeIdentifier: T, _options: QueryOptionsWithAnchor): Promise<CategorySamplesWithAnchorResponseTyped<T>>;
40
40
  export declare const saveCategorySample: <T extends CategoryTypeIdentifier>(identifier: T, value: import("./types").CategoryValueForIdentifier, startDate: Date, endDate: Date, metadata: import("./types").MetadataForCategoryIdentifier<T>) => Promise<boolean>;
41
41
  export declare const queryCorrelationSamples: (typeIdentifier: import("./types").CorrelationTypeIdentifier, from: Date, to: Date) => Promise<readonly import("./types").CorrelationSample[]>;
42
42
  export declare const saveCorrelationSample: (typeIdentifier: import("./types").CorrelationTypeIdentifier, samples: import("./types").SampleForSaving[], start: Date, end: Date, metadata: import("react-native-nitro-modules").AnyMap) => Promise<boolean>;
43
- export declare const queryHeartbeatSeriesSamples: (options?: import("./types").QueryOptionsWithSortOrder) => Promise<readonly import("./types").HeartbeatSeriesSample[]>;
43
+ export declare const queryHeartbeatSeriesSamples: (options?: QueryOptionsWithSortOrder) => Promise<readonly import("./types").HeartbeatSeriesSample[]>;
44
44
  export declare const queryHeartbeatSeriesSamplesWithAnchor: (options: QueryOptionsWithAnchor) => Promise<import("./types").HeartbeatSeriesSamplesWithAnchorResponse>;
45
45
  export declare const queryWorkoutSamples: (options: import("./types").WorkoutQueryOptions) => Promise<WorkoutProxy[]>;
46
46
  export declare const queryWorkoutSamplesWithAnchor: (options: import("./types").WorkoutQueryOptionsWithAnchor) => Promise<import("./types").QueryWorkoutSamplesWithAnchorResponse>;
47
47
  export declare const saveWorkoutSample: (workoutActivityType: import("./types").WorkoutActivityType, quantities: readonly import("./types").QuantitySampleForSaving[], startDate: Date, endDate: Date, totals: import("./types").WorkoutTotals, metadata: import("react-native-nitro-modules").AnyMap) => Promise<WorkoutProxy>;
48
48
  export declare const startWatchApp: (workoutConfiguration: import("./types").WorkoutConfiguration) => Promise<boolean>;
49
- export declare const queryStateOfMindSamples: (options?: import("./types").QueryOptionsWithSortOrder) => Promise<readonly import("./types").StateOfMindSample[]>;
49
+ export declare const queryStateOfMindSamples: (options?: QueryOptionsWithSortOrder) => Promise<readonly import("./types").StateOfMindSample[]>;
50
50
  export declare const saveStateOfMindSample: (date: Date, kind: import("./types").StateOfMindKind, valence: number, labels: readonly import("./types").StateOfMindLabel[], associations: readonly import("./types").StateOfMindAssociation[], metadata?: import("react-native-nitro-modules").AnyMap) => Promise<boolean>;
51
51
  export declare function getMostRecentCategorySample<T extends CategoryTypeIdentifier>(_identifier: T): Promise<CategorySampleTyped<T> | undefined>;
52
52
  export declare const getMostRecentQuantitySample: typeof import("./healthkit.ios").getMostRecentQuantitySample;
@@ -8,6 +8,7 @@ import type { GenericMetadata } from './Shared';
8
8
  export type CorrelationTypeIdentifier = 'HKCorrelationTypeIdentifierBloodPressure' | 'HKCorrelationTypeIdentifierFood';
9
9
  type CorrelationObject = CategorySample | QuantitySample;
10
10
  export interface CorrelationSample {
11
+ readonly uuid: string;
11
12
  readonly correlationType: CorrelationTypeIdentifier;
12
13
  readonly objects: readonly CorrelationObject[];
13
14
  readonly metadata: AnyMap;
@@ -15,6 +15,8 @@ export interface QueryStatisticsResponse {
15
15
  readonly mostRecentQuantity?: Quantity;
16
16
  readonly mostRecentQuantityDateInterval?: QuantityDateInterval;
17
17
  readonly duration?: Quantity;
18
+ readonly startDate?: Date;
19
+ readonly endDate?: Date;
18
20
  }
19
21
  export interface QuantitySamplesWithAnchorResponse {
20
22
  readonly samples: readonly QuantitySample[];
@@ -11,8 +11,12 @@ type PredicateWithStartAndEnd = {
11
11
  readonly strictEndDate?: boolean;
12
12
  readonly strictStartDate?: boolean;
13
13
  };
14
+ type PredicateWithMetadataOperator = 'equalTo' | 'notEqualTo' | 'greaterThan' | 'lessThan';
15
+ type PredicateWithMetadataValue = string | number | Date | boolean;
14
16
  type PredicateWithMetadataKey = {
15
17
  readonly withMetadataKey: string;
18
+ readonly operatorType?: PredicateWithMetadataOperator;
19
+ readonly value?: PredicateWithMetadataValue;
16
20
  };
17
21
  export type FilterForSamplesAnd = {
18
22
  readonly AND: PredicateForSamples[];
@@ -84,6 +84,8 @@ namespace margelo::nitro::healthkit { struct PredicateForWorkoutsOr; }
84
84
  namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
85
85
  // Forward declaration of `PredicateWithMetadataKey` to properly resolve imports.
86
86
  namespace margelo::nitro::healthkit { struct PredicateWithMetadataKey; }
87
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
88
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
87
89
  // Forward declaration of `PredicateWithStartAndEnd` to properly resolve imports.
88
90
  namespace margelo::nitro::healthkit { struct PredicateWithStartAndEnd; }
89
91
  // Forward declaration of `PredicateWithUUID` to properly resolve imports.
@@ -217,6 +219,7 @@ namespace ReactNativeHealthkit { class HybridWorkoutsModuleSpec_cxx; }
217
219
  #include "PredicateForWorkoutsOr.hpp"
218
220
  #include "PredicateFromWorkout.hpp"
219
221
  #include "PredicateWithMetadataKey.hpp"
222
+ #include "PredicateWithMetadataOperator.hpp"
220
223
  #include "PredicateWithStartAndEnd.hpp"
221
224
  #include "PredicateWithUUID.hpp"
222
225
  #include "PredicateWithUUIDs.hpp"
@@ -442,6 +445,65 @@ namespace margelo::nitro::healthkit::bridge::swift {
442
445
  return vector;
443
446
  }
444
447
 
448
+ // pragma MARK: std::optional<PredicateWithMetadataOperator>
449
+ /**
450
+ * Specialized version of `std::optional<PredicateWithMetadataOperator>`.
451
+ */
452
+ using std__optional_PredicateWithMetadataOperator_ = std::optional<PredicateWithMetadataOperator>;
453
+ inline std::optional<PredicateWithMetadataOperator> create_std__optional_PredicateWithMetadataOperator_(const PredicateWithMetadataOperator& value) {
454
+ return std::optional<PredicateWithMetadataOperator>(value);
455
+ }
456
+
457
+ // pragma MARK: std::variant<std::string, double, bool, std::chrono::system_clock::time_point>
458
+ /**
459
+ * Wrapper struct for `std::variant<std::string, double, bool, std::chrono::system_clock::time_point>`.
460
+ * std::variant cannot be used in Swift because of a Swift bug.
461
+ * Not even specializing it works. So we create a wrapper struct.
462
+ */
463
+ struct std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ {
464
+ std::variant<std::string, double, bool, std::chrono::system_clock::time_point> variant;
465
+ std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(std::variant<std::string, double, bool, std::chrono::system_clock::time_point> variant): variant(variant) { }
466
+ operator std::variant<std::string, double, bool, std::chrono::system_clock::time_point>() const {
467
+ return variant;
468
+ }
469
+ inline size_t index() const {
470
+ return variant.index();
471
+ }
472
+ inline std::string get_0() const {
473
+ return std::get<0>(variant);
474
+ }
475
+ inline double get_1() const {
476
+ return std::get<1>(variant);
477
+ }
478
+ inline bool get_2() const {
479
+ return std::get<2>(variant);
480
+ }
481
+ inline std::chrono::system_clock::time_point get_3() const {
482
+ return std::get<3>(variant);
483
+ }
484
+ };
485
+ inline std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(const std::string& value) {
486
+ return std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(value);
487
+ }
488
+ inline std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(double value) {
489
+ return std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(value);
490
+ }
491
+ inline std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(bool value) {
492
+ return std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(value);
493
+ }
494
+ inline std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(std::chrono::system_clock::time_point value) {
495
+ return std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(value);
496
+ }
497
+
498
+ // pragma MARK: std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>
499
+ /**
500
+ * Specialized version of `std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>`.
501
+ */
502
+ using std__optional_std__variant_std__string__double__bool__std__chrono__system_clock__time_point__ = std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>;
503
+ inline std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> create_std__optional_std__variant_std__string__double__bool__std__chrono__system_clock__time_point__(const std::variant<std::string, double, bool, std::chrono::system_clock::time_point>& value) {
504
+ return std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>(value);
505
+ }
506
+
445
507
  // pragma MARK: std::optional<std::chrono::system_clock::time_point>
446
508
  /**
447
509
  * Specialized version of `std::optional<std::chrono::system_clock::time_point>`.
@@ -86,6 +86,8 @@ namespace margelo::nitro::healthkit { struct PredicateForWorkoutsOr; }
86
86
  namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
87
87
  // Forward declaration of `PredicateWithMetadataKey` to properly resolve imports.
88
88
  namespace margelo::nitro::healthkit { struct PredicateWithMetadataKey; }
89
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
90
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
89
91
  // Forward declaration of `PredicateWithStartAndEnd` to properly resolve imports.
90
92
  namespace margelo::nitro::healthkit { struct PredicateWithStartAndEnd; }
91
93
  // Forward declaration of `PredicateWithUUID` to properly resolve imports.
@@ -212,6 +214,7 @@ namespace margelo::nitro::healthkit { struct WorkoutTotals; }
212
214
  #include "PredicateForWorkoutsOr.hpp"
213
215
  #include "PredicateFromWorkout.hpp"
214
216
  #include "PredicateWithMetadataKey.hpp"
217
+ #include "PredicateWithMetadataOperator.hpp"
215
218
  #include "PredicateWithStartAndEnd.hpp"
216
219
  #include "PredicateWithUUID.hpp"
217
220
  #include "PredicateWithUUIDs.hpp"
@@ -40,6 +40,8 @@ namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
40
40
  namespace margelo::nitro::healthkit { struct FilterForSamplesAnd; }
41
41
  // Forward declaration of `FilterForSamplesOr` to properly resolve imports.
42
42
  namespace margelo::nitro::healthkit { struct FilterForSamplesOr; }
43
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
44
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
43
45
  // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
44
46
  namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
45
47
  // Forward declaration of `CategorySamplesWithAnchorResponse` to properly resolve imports.
@@ -70,6 +72,7 @@ namespace margelo::nitro::healthkit { struct QueryOptionsWithAnchor; }
70
72
  #include "PredicateFromWorkout.hpp"
71
73
  #include "FilterForSamplesAnd.hpp"
72
74
  #include "FilterForSamplesOr.hpp"
75
+ #include "PredicateWithMetadataOperator.hpp"
73
76
  #include "HybridWorkoutProxySpec.hpp"
74
77
  #include "CategorySamplesWithAnchorResponse.hpp"
75
78
  #include "DeletedSample.hpp"
@@ -46,6 +46,8 @@ namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
46
46
  namespace margelo::nitro::healthkit { struct FilterForSamplesAnd; }
47
47
  // Forward declaration of `FilterForSamplesOr` to properly resolve imports.
48
48
  namespace margelo::nitro::healthkit { struct FilterForSamplesOr; }
49
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
50
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
49
51
  // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
50
52
  namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
51
53
 
@@ -73,6 +75,7 @@ namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
73
75
  #include "PredicateFromWorkout.hpp"
74
76
  #include "FilterForSamplesAnd.hpp"
75
77
  #include "FilterForSamplesOr.hpp"
78
+ #include "PredicateWithMetadataOperator.hpp"
76
79
  #include <chrono>
77
80
  #include "HybridWorkoutProxySpec.hpp"
78
81
  #include <unordered_map>
@@ -40,6 +40,8 @@ namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
40
40
  namespace margelo::nitro::healthkit { struct FilterForSamplesAnd; }
41
41
  // Forward declaration of `FilterForSamplesOr` to properly resolve imports.
42
42
  namespace margelo::nitro::healthkit { struct FilterForSamplesOr; }
43
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
44
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
43
45
  // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
44
46
  namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
45
47
  // Forward declaration of `HeartbeatSeriesSamplesWithAnchorResponse` to properly resolve imports.
@@ -70,6 +72,7 @@ namespace margelo::nitro::healthkit { struct QueryOptionsWithAnchor; }
70
72
  #include "PredicateFromWorkout.hpp"
71
73
  #include "FilterForSamplesAnd.hpp"
72
74
  #include "FilterForSamplesOr.hpp"
75
+ #include "PredicateWithMetadataOperator.hpp"
73
76
  #include "HybridWorkoutProxySpec.hpp"
74
77
  #include "HeartbeatSeriesSamplesWithAnchorResponse.hpp"
75
78
  #include "DeletedSample.hpp"
@@ -30,6 +30,8 @@ namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
30
30
  namespace margelo::nitro::healthkit { struct FilterForSamplesAnd; }
31
31
  // Forward declaration of `FilterForSamplesOr` to properly resolve imports.
32
32
  namespace margelo::nitro::healthkit { struct FilterForSamplesOr; }
33
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
34
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
33
35
  // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
34
36
  namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
35
37
  // Forward declaration of `QuantitySample` to properly resolve imports.
@@ -76,6 +78,7 @@ namespace margelo::nitro::healthkit { struct QueryOptionsWithAnchorAndUnit; }
76
78
  #include "FilterForSamplesOr.hpp"
77
79
  #include <vector>
78
80
  #include <optional>
81
+ #include "PredicateWithMetadataOperator.hpp"
79
82
  #include <memory>
80
83
  #include "HybridWorkoutProxySpec.hpp"
81
84
  #include "QuantitySample.hpp"
@@ -46,6 +46,8 @@ namespace margelo::nitro::healthkit { struct PredicateFromWorkout; }
46
46
  namespace margelo::nitro::healthkit { struct FilterForSamplesAnd; }
47
47
  // Forward declaration of `FilterForSamplesOr` to properly resolve imports.
48
48
  namespace margelo::nitro::healthkit { struct FilterForSamplesOr; }
49
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
50
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
49
51
  // Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
50
52
  namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
51
53
 
@@ -73,6 +75,7 @@ namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
73
75
  #include "PredicateFromWorkout.hpp"
74
76
  #include "FilterForSamplesAnd.hpp"
75
77
  #include "FilterForSamplesOr.hpp"
78
+ #include "PredicateWithMetadataOperator.hpp"
76
79
  #include "HybridWorkoutProxySpec.hpp"
77
80
 
78
81
  #include "ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp"
@@ -52,6 +52,8 @@ namespace margelo::nitro::healthkit { struct WorkoutDurationPredicate; }
52
52
  namespace margelo::nitro::healthkit { struct PredicateForWorkoutsOr; }
53
53
  // Forward declaration of `PredicateForWorkoutsAnd` to properly resolve imports.
54
54
  namespace margelo::nitro::healthkit { struct PredicateForWorkoutsAnd; }
55
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
56
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
55
57
  // Forward declaration of `ComparisonPredicateOperator` to properly resolve imports.
56
58
  namespace margelo::nitro::healthkit { enum class ComparisonPredicateOperator; }
57
59
  // Forward declaration of `WorkoutQueryOptions` to properly resolve imports.
@@ -88,6 +90,7 @@ namespace margelo::nitro::healthkit { enum class WorkoutSessionLocationType; }
88
90
  #include "WorkoutDurationPredicate.hpp"
89
91
  #include "PredicateForWorkoutsOr.hpp"
90
92
  #include "PredicateForWorkoutsAnd.hpp"
93
+ #include "PredicateWithMetadataOperator.hpp"
91
94
  #include "ComparisonPredicateOperator.hpp"
92
95
  #include "WorkoutQueryOptions.hpp"
93
96
  #include "WorkoutConfiguration.hpp"
@@ -18,8 +18,8 @@ public extension CorrelationSample {
18
18
  /**
19
19
  * Create a new instance of `CorrelationSample`.
20
20
  */
21
- init(correlationType: CorrelationTypeIdentifier, objects: [CorrelationObject], metadata: AnyMap, startDate: Date, endDate: Date) {
22
- self.init(correlationType, { () -> bridge.std__vector_std__variant_CategorySample__QuantitySample__ in
21
+ init(uuid: String, correlationType: CorrelationTypeIdentifier, objects: [CorrelationObject], metadata: AnyMap, startDate: Date, endDate: Date) {
22
+ self.init(std.string(uuid), correlationType, { () -> bridge.std__vector_std__variant_CategorySample__QuantitySample__ in
23
23
  var __vector = bridge.create_std__vector_std__variant_CategorySample__QuantitySample__(objects.count)
24
24
  for __item in objects {
25
25
  __vector.push_back({ () -> bridge.std__variant_CategorySample__QuantitySample_ in
@@ -35,6 +35,17 @@ public extension CorrelationSample {
35
35
  }(), metadata.cppPart, startDate.toCpp(), endDate.toCpp())
36
36
  }
37
37
 
38
+ var uuid: String {
39
+ @inline(__always)
40
+ get {
41
+ return String(self.__uuid)
42
+ }
43
+ @inline(__always)
44
+ set {
45
+ self.__uuid = std.string(newValue)
46
+ }
47
+ }
48
+
38
49
  var correlationType: CorrelationTypeIdentifier {
39
50
  @inline(__always)
40
51
  get {
@@ -18,8 +18,31 @@ public extension PredicateWithMetadataKey {
18
18
  /**
19
19
  * Create a new instance of `PredicateWithMetadataKey`.
20
20
  */
21
- init(withMetadataKey: String) {
22
- self.init(std.string(withMetadataKey))
21
+ init(withMetadataKey: String, operatorType: PredicateWithMetadataOperator?, value: Variant_String_Double_Bool_Date?) {
22
+ self.init(std.string(withMetadataKey), { () -> bridge.std__optional_PredicateWithMetadataOperator_ in
23
+ if let __unwrappedValue = operatorType {
24
+ return bridge.create_std__optional_PredicateWithMetadataOperator_(__unwrappedValue)
25
+ } else {
26
+ return .init()
27
+ }
28
+ }(), { () -> bridge.std__optional_std__variant_std__string__double__bool__std__chrono__system_clock__time_point__ in
29
+ if let __unwrappedValue = value {
30
+ return bridge.create_std__optional_std__variant_std__string__double__bool__std__chrono__system_clock__time_point__({ () -> bridge.std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ in
31
+ switch __unwrappedValue {
32
+ case .first(let __value):
33
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(std.string(__value))
34
+ case .second(let __value):
35
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__value)
36
+ case .third(let __value):
37
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__value)
38
+ case .fourth(let __value):
39
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__value.toCpp())
40
+ }
41
+ }().variant)
42
+ } else {
43
+ return .init()
44
+ }
45
+ }())
23
46
  }
24
47
 
25
48
  var withMetadataKey: String {
@@ -32,4 +55,73 @@ public extension PredicateWithMetadataKey {
32
55
  self.__withMetadataKey = std.string(newValue)
33
56
  }
34
57
  }
58
+
59
+ var operatorType: PredicateWithMetadataOperator? {
60
+ @inline(__always)
61
+ get {
62
+ return self.__operatorType.value
63
+ }
64
+ @inline(__always)
65
+ set {
66
+ self.__operatorType = { () -> bridge.std__optional_PredicateWithMetadataOperator_ in
67
+ if let __unwrappedValue = newValue {
68
+ return bridge.create_std__optional_PredicateWithMetadataOperator_(__unwrappedValue)
69
+ } else {
70
+ return .init()
71
+ }
72
+ }()
73
+ }
74
+ }
75
+
76
+ var value: Variant_String_Double_Bool_Date? {
77
+ @inline(__always)
78
+ get {
79
+ return { () -> Variant_String_Double_Bool_Date? in
80
+ if let __unwrapped = self.__value.value {
81
+ return { () -> Variant_String_Double_Bool_Date in
82
+ let __variant = bridge.std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__unwrapped)
83
+ switch __variant.index() {
84
+ case 0:
85
+ let __actual = __variant.get_0()
86
+ return .first(String(__actual))
87
+ case 1:
88
+ let __actual = __variant.get_1()
89
+ return .second(__actual)
90
+ case 2:
91
+ let __actual = __variant.get_2()
92
+ return .third(__actual)
93
+ case 3:
94
+ let __actual = __variant.get_3()
95
+ return .fourth(Date(fromChrono: __actual))
96
+ default:
97
+ fatalError("Variant can never have index \(__variant.index())!")
98
+ }
99
+ }()
100
+ } else {
101
+ return nil
102
+ }
103
+ }()
104
+ }
105
+ @inline(__always)
106
+ set {
107
+ self.__value = { () -> bridge.std__optional_std__variant_std__string__double__bool__std__chrono__system_clock__time_point__ in
108
+ if let __unwrappedValue = newValue {
109
+ return bridge.create_std__optional_std__variant_std__string__double__bool__std__chrono__system_clock__time_point__({ () -> bridge.std__variant_std__string__double__bool__std__chrono__system_clock__time_point_ in
110
+ switch __unwrappedValue {
111
+ case .first(let __value):
112
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(std.string(__value))
113
+ case .second(let __value):
114
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__value)
115
+ case .third(let __value):
116
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__value)
117
+ case .fourth(let __value):
118
+ return bridge.create_std__variant_std__string__double__bool__std__chrono__system_clock__time_point_(__value.toCpp())
119
+ }
120
+ }().variant)
121
+ } else {
122
+ return .init()
123
+ }
124
+ }()
125
+ }
126
+ }
35
127
  }
@@ -0,0 +1,48 @@
1
+ ///
2
+ /// PredicateWithMetadataOperator.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2025 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ /**
9
+ * Represents the JS union `PredicateWithMetadataOperator`, backed by a C++ enum.
10
+ */
11
+ public typealias PredicateWithMetadataOperator = margelo.nitro.healthkit.PredicateWithMetadataOperator
12
+
13
+ public extension PredicateWithMetadataOperator {
14
+ /**
15
+ * Get a PredicateWithMetadataOperator for the given String value, or
16
+ * return `nil` if the given value was invalid/unknown.
17
+ */
18
+ init?(fromString string: String) {
19
+ switch string {
20
+ case "equalTo":
21
+ self = .equalto
22
+ case "notEqualTo":
23
+ self = .notequalto
24
+ case "greaterThan":
25
+ self = .greaterthan
26
+ case "lessThan":
27
+ self = .lessthan
28
+ default:
29
+ return nil
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Get the String value this PredicateWithMetadataOperator represents.
35
+ */
36
+ var stringValue: String {
37
+ switch self {
38
+ case .equalto:
39
+ return "equalTo"
40
+ case .notequalto:
41
+ return "notEqualTo"
42
+ case .greaterthan:
43
+ return "greaterThan"
44
+ case .lessthan:
45
+ return "lessThan"
46
+ }
47
+ }
48
+ }
@@ -18,7 +18,7 @@ public extension QueryStatisticsResponse {
18
18
  /**
19
19
  * Create a new instance of `QueryStatisticsResponse`.
20
20
  */
21
- init(averageQuantity: Quantity?, maximumQuantity: Quantity?, minimumQuantity: Quantity?, sumQuantity: Quantity?, mostRecentQuantity: Quantity?, mostRecentQuantityDateInterval: QuantityDateInterval?, duration: Quantity?) {
21
+ init(averageQuantity: Quantity?, maximumQuantity: Quantity?, minimumQuantity: Quantity?, sumQuantity: Quantity?, mostRecentQuantity: Quantity?, mostRecentQuantityDateInterval: QuantityDateInterval?, duration: Quantity?, startDate: Date?, endDate: Date?) {
22
22
  self.init({ () -> bridge.std__optional_Quantity_ in
23
23
  if let __unwrappedValue = averageQuantity {
24
24
  return bridge.create_std__optional_Quantity_(__unwrappedValue)
@@ -61,6 +61,18 @@ public extension QueryStatisticsResponse {
61
61
  } else {
62
62
  return .init()
63
63
  }
64
+ }(), { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
65
+ if let __unwrappedValue = startDate {
66
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
67
+ } else {
68
+ return .init()
69
+ }
70
+ }(), { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
71
+ if let __unwrappedValue = endDate {
72
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
73
+ } else {
74
+ return .init()
75
+ }
64
76
  }())
65
77
  }
66
78
 
@@ -224,4 +236,50 @@ public extension QueryStatisticsResponse {
224
236
  }()
225
237
  }
226
238
  }
239
+
240
+ var startDate: Date? {
241
+ @inline(__always)
242
+ get {
243
+ return { () -> Date? in
244
+ if let __unwrapped = self.__startDate.value {
245
+ return Date(fromChrono: __unwrapped)
246
+ } else {
247
+ return nil
248
+ }
249
+ }()
250
+ }
251
+ @inline(__always)
252
+ set {
253
+ self.__startDate = { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
254
+ if let __unwrappedValue = newValue {
255
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
256
+ } else {
257
+ return .init()
258
+ }
259
+ }()
260
+ }
261
+ }
262
+
263
+ var endDate: Date? {
264
+ @inline(__always)
265
+ get {
266
+ return { () -> Date? in
267
+ if let __unwrapped = self.__endDate.value {
268
+ return Date(fromChrono: __unwrapped)
269
+ } else {
270
+ return nil
271
+ }
272
+ }()
273
+ }
274
+ @inline(__always)
275
+ set {
276
+ self.__endDate = { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
277
+ if let __unwrappedValue = newValue {
278
+ return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
279
+ } else {
280
+ return .init()
281
+ }
282
+ }()
283
+ }
284
+ }
227
285
  }
@@ -0,0 +1,18 @@
1
+ ///
2
+ /// Variant_String_Double_Bool_Date.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2025 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ /**
9
+ * An Swift enum with associated values representing a Variant/Union type.
10
+ * JS type: `string | number | boolean | date`
11
+ */
12
+ @frozen
13
+ public indirect enum Variant_String_Double_Bool_Date {
14
+ case first(String)
15
+ case second(Double)
16
+ case third(Bool)
17
+ case fourth(Date)
18
+ }
@@ -27,6 +27,7 @@ namespace margelo::nitro::healthkit { struct QuantitySample; }
27
27
  // Forward declaration of `AnyMap` to properly resolve imports.
28
28
  namespace NitroModules { class AnyMap; }
29
29
 
30
+ #include <string>
30
31
  #include "CorrelationTypeIdentifier.hpp"
31
32
  #include <vector>
32
33
  #include <variant>
@@ -42,6 +43,7 @@ namespace margelo::nitro::healthkit {
42
43
  */
43
44
  struct CorrelationSample {
44
45
  public:
46
+ std::string uuid SWIFT_PRIVATE;
45
47
  CorrelationTypeIdentifier correlationType SWIFT_PRIVATE;
46
48
  std::vector<std::variant<CategorySample, QuantitySample>> objects SWIFT_PRIVATE;
47
49
  std::shared_ptr<AnyMap> metadata SWIFT_PRIVATE;
@@ -50,7 +52,7 @@ namespace margelo::nitro::healthkit {
50
52
 
51
53
  public:
52
54
  CorrelationSample() = default;
53
- explicit CorrelationSample(CorrelationTypeIdentifier correlationType, std::vector<std::variant<CategorySample, QuantitySample>> objects, std::shared_ptr<AnyMap> metadata, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate): correlationType(correlationType), objects(objects), metadata(metadata), startDate(startDate), endDate(endDate) {}
55
+ explicit CorrelationSample(std::string uuid, CorrelationTypeIdentifier correlationType, std::vector<std::variant<CategorySample, QuantitySample>> objects, std::shared_ptr<AnyMap> metadata, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate): uuid(uuid), correlationType(correlationType), objects(objects), metadata(metadata), startDate(startDate), endDate(endDate) {}
54
56
  };
55
57
 
56
58
  } // namespace margelo::nitro::healthkit
@@ -65,6 +67,7 @@ namespace margelo::nitro {
65
67
  static inline CorrelationSample fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
66
68
  jsi::Object obj = arg.asObject(runtime);
67
69
  return CorrelationSample(
70
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "uuid")),
68
71
  JSIConverter<CorrelationTypeIdentifier>::fromJSI(runtime, obj.getProperty(runtime, "correlationType")),
69
72
  JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::fromJSI(runtime, obj.getProperty(runtime, "objects")),
70
73
  JSIConverter<std::shared_ptr<AnyMap>>::fromJSI(runtime, obj.getProperty(runtime, "metadata")),
@@ -74,6 +77,7 @@ namespace margelo::nitro {
74
77
  }
75
78
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const CorrelationSample& arg) {
76
79
  jsi::Object obj(runtime);
80
+ obj.setProperty(runtime, "uuid", JSIConverter<std::string>::toJSI(runtime, arg.uuid));
77
81
  obj.setProperty(runtime, "correlationType", JSIConverter<CorrelationTypeIdentifier>::toJSI(runtime, arg.correlationType));
78
82
  obj.setProperty(runtime, "objects", JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::toJSI(runtime, arg.objects));
79
83
  obj.setProperty(runtime, "metadata", JSIConverter<std::shared_ptr<AnyMap>>::toJSI(runtime, arg.metadata));
@@ -86,6 +90,7 @@ namespace margelo::nitro {
86
90
  return false;
87
91
  }
88
92
  jsi::Object obj = value.getObject(runtime);
93
+ if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "uuid"))) return false;
89
94
  if (!JSIConverter<CorrelationTypeIdentifier>::canConvert(runtime, obj.getProperty(runtime, "correlationType"))) return false;
90
95
  if (!JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::canConvert(runtime, obj.getProperty(runtime, "objects"))) return false;
91
96
  if (!JSIConverter<std::shared_ptr<AnyMap>>::canConvert(runtime, obj.getProperty(runtime, "metadata"))) return false;
@@ -18,9 +18,14 @@
18
18
  #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
19
  #endif
20
20
 
21
-
21
+ // Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
22
+ namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
22
23
 
23
24
  #include <string>
25
+ #include <optional>
26
+ #include "PredicateWithMetadataOperator.hpp"
27
+ #include <variant>
28
+ #include <chrono>
24
29
 
25
30
  namespace margelo::nitro::healthkit {
26
31
 
@@ -30,10 +35,12 @@ namespace margelo::nitro::healthkit {
30
35
  struct PredicateWithMetadataKey {
31
36
  public:
32
37
  std::string withMetadataKey SWIFT_PRIVATE;
38
+ std::optional<PredicateWithMetadataOperator> operatorType SWIFT_PRIVATE;
39
+ std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> value SWIFT_PRIVATE;
33
40
 
34
41
  public:
35
42
  PredicateWithMetadataKey() = default;
36
- explicit PredicateWithMetadataKey(std::string withMetadataKey): withMetadataKey(withMetadataKey) {}
43
+ explicit PredicateWithMetadataKey(std::string withMetadataKey, std::optional<PredicateWithMetadataOperator> operatorType, std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> value): withMetadataKey(withMetadataKey), operatorType(operatorType), value(value) {}
37
44
  };
38
45
 
39
46
  } // namespace margelo::nitro::healthkit
@@ -48,12 +55,16 @@ namespace margelo::nitro {
48
55
  static inline PredicateWithMetadataKey fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
49
56
  jsi::Object obj = arg.asObject(runtime);
50
57
  return PredicateWithMetadataKey(
51
- JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "withMetadataKey"))
58
+ JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "withMetadataKey")),
59
+ JSIConverter<std::optional<PredicateWithMetadataOperator>>::fromJSI(runtime, obj.getProperty(runtime, "operatorType")),
60
+ JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::fromJSI(runtime, obj.getProperty(runtime, "value"))
52
61
  );
53
62
  }
54
63
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const PredicateWithMetadataKey& arg) {
55
64
  jsi::Object obj(runtime);
56
65
  obj.setProperty(runtime, "withMetadataKey", JSIConverter<std::string>::toJSI(runtime, arg.withMetadataKey));
66
+ obj.setProperty(runtime, "operatorType", JSIConverter<std::optional<PredicateWithMetadataOperator>>::toJSI(runtime, arg.operatorType));
67
+ obj.setProperty(runtime, "value", JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::toJSI(runtime, arg.value));
57
68
  return obj;
58
69
  }
59
70
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -62,6 +73,8 @@ namespace margelo::nitro {
62
73
  }
63
74
  jsi::Object obj = value.getObject(runtime);
64
75
  if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "withMetadataKey"))) return false;
76
+ if (!JSIConverter<std::optional<PredicateWithMetadataOperator>>::canConvert(runtime, obj.getProperty(runtime, "operatorType"))) return false;
77
+ if (!JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::canConvert(runtime, obj.getProperty(runtime, "value"))) return false;
65
78
  return true;
66
79
  }
67
80
  };
@@ -0,0 +1,86 @@
1
+ ///
2
+ /// PredicateWithMetadataOperator.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2025 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/NitroHash.hpp>)
11
+ #include <NitroModules/NitroHash.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
16
+ #include <NitroModules/JSIConverter.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
21
+ #include <NitroModules/NitroDefines.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+
26
+ namespace margelo::nitro::healthkit {
27
+
28
+ /**
29
+ * An enum which can be represented as a JavaScript union (PredicateWithMetadataOperator).
30
+ */
31
+ enum class PredicateWithMetadataOperator {
32
+ EQUALTO SWIFT_NAME(equalto) = 0,
33
+ NOTEQUALTO SWIFT_NAME(notequalto) = 1,
34
+ GREATERTHAN SWIFT_NAME(greaterthan) = 2,
35
+ LESSTHAN SWIFT_NAME(lessthan) = 3,
36
+ } CLOSED_ENUM;
37
+
38
+ } // namespace margelo::nitro::healthkit
39
+
40
+ namespace margelo::nitro {
41
+
42
+ using namespace margelo::nitro::healthkit;
43
+
44
+ // C++ PredicateWithMetadataOperator <> JS PredicateWithMetadataOperator (union)
45
+ template <>
46
+ struct JSIConverter<PredicateWithMetadataOperator> final {
47
+ static inline PredicateWithMetadataOperator fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
48
+ std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
49
+ switch (hashString(unionValue.c_str(), unionValue.size())) {
50
+ case hashString("equalTo"): return PredicateWithMetadataOperator::EQUALTO;
51
+ case hashString("notEqualTo"): return PredicateWithMetadataOperator::NOTEQUALTO;
52
+ case hashString("greaterThan"): return PredicateWithMetadataOperator::GREATERTHAN;
53
+ case hashString("lessThan"): return PredicateWithMetadataOperator::LESSTHAN;
54
+ default: [[unlikely]]
55
+ throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum PredicateWithMetadataOperator - invalid value!");
56
+ }
57
+ }
58
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, PredicateWithMetadataOperator arg) {
59
+ switch (arg) {
60
+ case PredicateWithMetadataOperator::EQUALTO: return JSIConverter<std::string>::toJSI(runtime, "equalTo");
61
+ case PredicateWithMetadataOperator::NOTEQUALTO: return JSIConverter<std::string>::toJSI(runtime, "notEqualTo");
62
+ case PredicateWithMetadataOperator::GREATERTHAN: return JSIConverter<std::string>::toJSI(runtime, "greaterThan");
63
+ case PredicateWithMetadataOperator::LESSTHAN: return JSIConverter<std::string>::toJSI(runtime, "lessThan");
64
+ default: [[unlikely]]
65
+ throw std::invalid_argument("Cannot convert PredicateWithMetadataOperator to JS - invalid value: "
66
+ + std::to_string(static_cast<int>(arg)) + "!");
67
+ }
68
+ }
69
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
70
+ if (!value.isString()) {
71
+ return false;
72
+ }
73
+ std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
74
+ switch (hashString(unionValue.c_str(), unionValue.size())) {
75
+ case hashString("equalTo"):
76
+ case hashString("notEqualTo"):
77
+ case hashString("greaterThan"):
78
+ case hashString("lessThan"):
79
+ return true;
80
+ default:
81
+ return false;
82
+ }
83
+ }
84
+ };
85
+
86
+ } // namespace margelo::nitro
@@ -26,6 +26,7 @@ namespace margelo::nitro::healthkit { struct QuantityDateInterval; }
26
26
  #include <optional>
27
27
  #include "Quantity.hpp"
28
28
  #include "QuantityDateInterval.hpp"
29
+ #include <chrono>
29
30
 
30
31
  namespace margelo::nitro::healthkit {
31
32
 
@@ -41,10 +42,12 @@ namespace margelo::nitro::healthkit {
41
42
  std::optional<Quantity> mostRecentQuantity SWIFT_PRIVATE;
42
43
  std::optional<QuantityDateInterval> mostRecentQuantityDateInterval SWIFT_PRIVATE;
43
44
  std::optional<Quantity> duration SWIFT_PRIVATE;
45
+ std::optional<std::chrono::system_clock::time_point> startDate SWIFT_PRIVATE;
46
+ std::optional<std::chrono::system_clock::time_point> endDate SWIFT_PRIVATE;
44
47
 
45
48
  public:
46
49
  QueryStatisticsResponse() = default;
47
- explicit QueryStatisticsResponse(std::optional<Quantity> averageQuantity, std::optional<Quantity> maximumQuantity, std::optional<Quantity> minimumQuantity, std::optional<Quantity> sumQuantity, std::optional<Quantity> mostRecentQuantity, std::optional<QuantityDateInterval> mostRecentQuantityDateInterval, std::optional<Quantity> duration): averageQuantity(averageQuantity), maximumQuantity(maximumQuantity), minimumQuantity(minimumQuantity), sumQuantity(sumQuantity), mostRecentQuantity(mostRecentQuantity), mostRecentQuantityDateInterval(mostRecentQuantityDateInterval), duration(duration) {}
50
+ explicit QueryStatisticsResponse(std::optional<Quantity> averageQuantity, std::optional<Quantity> maximumQuantity, std::optional<Quantity> minimumQuantity, std::optional<Quantity> sumQuantity, std::optional<Quantity> mostRecentQuantity, std::optional<QuantityDateInterval> mostRecentQuantityDateInterval, std::optional<Quantity> duration, std::optional<std::chrono::system_clock::time_point> startDate, std::optional<std::chrono::system_clock::time_point> endDate): averageQuantity(averageQuantity), maximumQuantity(maximumQuantity), minimumQuantity(minimumQuantity), sumQuantity(sumQuantity), mostRecentQuantity(mostRecentQuantity), mostRecentQuantityDateInterval(mostRecentQuantityDateInterval), duration(duration), startDate(startDate), endDate(endDate) {}
48
51
  };
49
52
 
50
53
  } // namespace margelo::nitro::healthkit
@@ -65,7 +68,9 @@ namespace margelo::nitro {
65
68
  JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "sumQuantity")),
66
69
  JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "mostRecentQuantity")),
67
70
  JSIConverter<std::optional<QuantityDateInterval>>::fromJSI(runtime, obj.getProperty(runtime, "mostRecentQuantityDateInterval")),
68
- JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "duration"))
71
+ JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "duration")),
72
+ JSIConverter<std::optional<std::chrono::system_clock::time_point>>::fromJSI(runtime, obj.getProperty(runtime, "startDate")),
73
+ JSIConverter<std::optional<std::chrono::system_clock::time_point>>::fromJSI(runtime, obj.getProperty(runtime, "endDate"))
69
74
  );
70
75
  }
71
76
  static inline jsi::Value toJSI(jsi::Runtime& runtime, const QueryStatisticsResponse& arg) {
@@ -77,6 +82,8 @@ namespace margelo::nitro {
77
82
  obj.setProperty(runtime, "mostRecentQuantity", JSIConverter<std::optional<Quantity>>::toJSI(runtime, arg.mostRecentQuantity));
78
83
  obj.setProperty(runtime, "mostRecentQuantityDateInterval", JSIConverter<std::optional<QuantityDateInterval>>::toJSI(runtime, arg.mostRecentQuantityDateInterval));
79
84
  obj.setProperty(runtime, "duration", JSIConverter<std::optional<Quantity>>::toJSI(runtime, arg.duration));
85
+ obj.setProperty(runtime, "startDate", JSIConverter<std::optional<std::chrono::system_clock::time_point>>::toJSI(runtime, arg.startDate));
86
+ obj.setProperty(runtime, "endDate", JSIConverter<std::optional<std::chrono::system_clock::time_point>>::toJSI(runtime, arg.endDate));
80
87
  return obj;
81
88
  }
82
89
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
@@ -91,6 +98,8 @@ namespace margelo::nitro {
91
98
  if (!JSIConverter<std::optional<Quantity>>::canConvert(runtime, obj.getProperty(runtime, "mostRecentQuantity"))) return false;
92
99
  if (!JSIConverter<std::optional<QuantityDateInterval>>::canConvert(runtime, obj.getProperty(runtime, "mostRecentQuantityDateInterval"))) return false;
93
100
  if (!JSIConverter<std::optional<Quantity>>::canConvert(runtime, obj.getProperty(runtime, "duration"))) return false;
101
+ if (!JSIConverter<std::optional<std::chrono::system_clock::time_point>>::canConvert(runtime, obj.getProperty(runtime, "startDate"))) return false;
102
+ if (!JSIConverter<std::optional<std::chrono::system_clock::time_point>>::canConvert(runtime, obj.getProperty(runtime, "endDate"))) return false;
94
103
  return true;
95
104
  }
96
105
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kingstinct/react-native-healthkit",
3
- "version": "10.0.0",
3
+ "version": "10.1.0",
4
4
  "description": "React Native bindings for HealthKit",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
package/src/healthkit.ts CHANGED
@@ -21,7 +21,10 @@ import {
21
21
  WheelchairUse,
22
22
  } from './types/Characteristics'
23
23
  import type { QuantitySample } from './types/QuantitySample'
24
- import type { QueryOptionsWithAnchor } from './types/QueryOptions'
24
+ import type {
25
+ QueryOptionsWithAnchor,
26
+ QueryOptionsWithSortOrder,
27
+ } from './types/QueryOptions'
25
28
 
26
29
  export * from './types'
27
30
 
@@ -174,6 +177,7 @@ export const isQuantityCompatibleWithUnit = UnavailableFnFromModule(
174
177
  // CategoryTypeModule functions
175
178
  export function queryCategorySamples<T extends CategoryTypeIdentifier>(
176
179
  _categoryTypeIdentifier: T,
180
+ _options?: QueryOptionsWithSortOrder,
177
181
  ): Promise<CategorySampleTyped<T>[]> {
178
182
  if (Platform.OS !== 'ios' && !hasWarned) {
179
183
  console.warn(notAvailableError)
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Test case to verify that queryStatisticsForQuantity resolves when no data is present
3
+ */
4
+
5
+ import { describe, expect, test } from 'bun:test'
6
+ import type { QueryStatisticsResponse } from '../types/QuantityType'
7
+
8
+ describe('queryStatisticsForQuantity', () => {
9
+ test('should resolve with empty response when no data is present', async () => {
10
+ // This test would normally require running on iOS simulator or device
11
+ // For now, we're just testing the TypeScript interface
12
+
13
+ const mockEmptyResponse: QueryStatisticsResponse = {}
14
+
15
+ // Verify that empty response is properly typed
16
+ expect(mockEmptyResponse.averageQuantity).toBeUndefined()
17
+ expect(mockEmptyResponse.sumQuantity).toBeUndefined()
18
+ expect(mockEmptyResponse.startDate).toBeUndefined()
19
+ expect(mockEmptyResponse.endDate).toBeUndefined()
20
+ })
21
+
22
+ test('should handle date range with no data', async () => {
23
+ // This is more of a documentation of the expected behavior
24
+ // The query should resolve with an empty response object
25
+ // when there's no data in the specified timeframe
26
+ const expectedResult: QueryStatisticsResponse = {
27
+ // All properties should be undefined for empty result
28
+ }
29
+
30
+ expect(expectedResult).toBeDefined()
31
+ })
32
+ })
@@ -13,6 +13,7 @@ export type CorrelationTypeIdentifier =
13
13
  type CorrelationObject = CategorySample | QuantitySample
14
14
 
15
15
  export interface CorrelationSample {
16
+ readonly uuid: string
16
17
  readonly correlationType: CorrelationTypeIdentifier
17
18
  readonly objects: readonly CorrelationObject[]
18
19
  readonly metadata: AnyMap
@@ -28,6 +28,8 @@ export interface QueryStatisticsResponse {
28
28
  readonly mostRecentQuantity?: Quantity
29
29
  readonly mostRecentQuantityDateInterval?: QuantityDateInterval
30
30
  readonly duration?: Quantity
31
+ readonly startDate?: Date
32
+ readonly endDate?: Date
31
33
  }
32
34
 
33
35
  export interface QuantitySamplesWithAnchorResponse {
@@ -15,8 +15,18 @@ type PredicateWithStartAndEnd = {
15
15
  readonly strictStartDate?: boolean
16
16
  }
17
17
 
18
+ type PredicateWithMetadataOperator =
19
+ | 'equalTo'
20
+ | 'notEqualTo'
21
+ | 'greaterThan'
22
+ | 'lessThan'
23
+
24
+ type PredicateWithMetadataValue = string | number | Date | boolean
25
+
18
26
  type PredicateWithMetadataKey = {
19
27
  readonly withMetadataKey: string
28
+ readonly operatorType?: PredicateWithMetadataOperator
29
+ readonly value?: PredicateWithMetadataValue
20
30
  }
21
31
 
22
32
  export type FilterForSamplesAnd = {