@kingstinct/react-native-healthkit 8.3.0 → 8.5.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 (39) hide show
  1. package/README.md +10 -3
  2. package/ios/Constants.swift +1 -0
  3. package/ios/Helpers.swift +40 -30
  4. package/ios/ReactNativeHealthkit.m +7 -0
  5. package/ios/ReactNativeHealthkit.swift +356 -208
  6. package/lib/commonjs/index.ios.js +10 -1
  7. package/lib/commonjs/index.ios.js.map +1 -1
  8. package/lib/commonjs/index.native.js +7 -4
  9. package/lib/commonjs/index.native.js.map +1 -1
  10. package/lib/commonjs/native-types.js +94 -1
  11. package/lib/commonjs/native-types.js.map +1 -1
  12. package/lib/commonjs/test-setup.js +2 -1
  13. package/lib/commonjs/test-setup.js.map +1 -1
  14. package/lib/commonjs/utils/queryStateOfMindSamples.js +22 -0
  15. package/lib/commonjs/utils/queryStateOfMindSamples.js.map +1 -0
  16. package/lib/module/index.ios.js +4 -2
  17. package/lib/module/index.ios.js.map +1 -1
  18. package/lib/module/index.native.js +5 -3
  19. package/lib/module/index.native.js.map +1 -1
  20. package/lib/module/native-types.js +96 -0
  21. package/lib/module/native-types.js.map +1 -1
  22. package/lib/module/test-setup.js +2 -1
  23. package/lib/module/test-setup.js.map +1 -1
  24. package/lib/module/utils/queryStateOfMindSamples.js +14 -0
  25. package/lib/module/utils/queryStateOfMindSamples.js.map +1 -0
  26. package/lib/typescript/src/index.ios.d.ts +8 -1
  27. package/lib/typescript/src/index.native.d.ts +2 -2
  28. package/lib/typescript/src/native-types.d.ts +117 -1
  29. package/lib/typescript/src/utils/queryStateOfMindSamples.d.ts +7 -0
  30. package/package.json +1 -1
  31. package/src/index.ios.tsx +3 -0
  32. package/src/index.native.tsx +4 -1
  33. package/src/native-types.ts +131 -0
  34. package/src/test-setup.ts +1 -0
  35. package/src/utils/queryStateOfMindSamples.ts +14 -0
  36. package/ios/ReactNativeHealthkit.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  37. package/ios/ReactNativeHealthkit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  38. package/ios/ReactNativeHealthkit.xcodeproj/project.xcworkspace/xcuserdata/robertherber.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  39. package/ios/ReactNativeHealthkit.xcodeproj/xcuserdata/robertherber.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
package/README.md CHANGED
@@ -131,13 +131,20 @@ Some imperative examples:
131
131
  ```
132
132
 
133
133
  ### HealthKit Anchors (breaking change in 6.0)
134
- In 6.0 you can use HealthKit anchors to get changes and deleted items which is very useful for syncing. This is a breaking change - but a very easy one to handle that TypeScript should help you with. Most queries now return an object containing samples which is what was returned as only an array before. In addition you also get deletedSamples and a newAnchor you can use for more advanced use cases, example:
134
+ In 6.0 you can use HealthKit anchors to get changes and deleted items which is very useful for syncing. This is a breaking change - but a very easy one to handle that TypeScript should help you with. Most queries now return an object containing samples which is what was returned as only an array before.
135
+
136
+ ```newAnchor``` is a base64-encoded string returned from HealthKit that contain sync information. After each successful sync, store the anchor for the next time your anchor query is called to only return the values that have changed.
137
+
138
+ ```limit``` will indicate how many records to consider when sycning data, you can set this value to 0 indicate no limit.
139
+
140
+ Example:
141
+
135
142
  ```TypeScript
136
- const { newAnchor, samples, deletedSamples } = await queryQuantitySamples(HKQuantityTypeIdentifier.stepCount, {
143
+ const { newAnchor, samples, deletedSamples } = await queryQuantitySamplesWithAnchor(HKQuantityTypeIdentifier.stepCount, {
137
144
  limit: 2,
138
145
  })
139
146
 
140
- const nextResult = await queryQuantitySamples(HKQuantityTypeIdentifier.stepCount, {
147
+ const nextResult = await queryQuantitySamplesWithAnchor(HKQuantityTypeIdentifier.stepCount, {
141
148
  limit: 2,
142
149
  anchor: newAnchor,
143
150
  })
@@ -23,6 +23,7 @@ let HKAudiogramTypeIdentifier = "HKAudiogramTypeIdentifier"
23
23
  let HKWorkoutTypeIdentifier = "HKWorkoutTypeIdentifier"
24
24
  let HKWorkoutRouteTypeIdentifier = "HKWorkoutRouteTypeIdentifier"
25
25
  let HKDataTypeIdentifierHeartbeatSeries = "HKDataTypeIdentifierHeartbeatSeries"
26
+ let HKStateOfMindTypeIdentifier = "HKStateOfMindTypeIdentifier"
26
27
 
27
28
  let HKWorkoutActivityTypePropertyName = "activityType"
28
29
  let HKWorkoutSessionLocationTypePropertyName = "locationType"
package/ios/Helpers.swift CHANGED
@@ -18,7 +18,8 @@ func limitOrNilIfZero(limit: Int) -> Int {
18
18
 
19
19
  func createPredicate(from: Date?, to: Date?) -> NSPredicate? {
20
20
  if from != nil || to != nil {
21
- return HKQuery.predicateForSamples(withStart: from, end: to, options: [.strictEndDate, .strictStartDate])
21
+ return HKQuery.predicateForSamples(
22
+ withStart: from, end: to, options: [.strictEndDate, .strictStartDate])
22
23
  } else {
23
24
  return nil
24
25
  }
@@ -29,23 +30,23 @@ func getSortDescriptors(ascending: Bool) -> [NSSortDescriptor] {
29
30
  }
30
31
 
31
32
  func base64StringToHKQueryAnchor(base64String: String) -> HKQueryAnchor? {
32
- // Step 1: Decode the base64 string to a Data object
33
- guard let data = Data(base64Encoded: base64String) else {
34
- print("Error: Invalid base64 string")
35
- return nil
36
- }
37
-
38
- // Step 2: Use NSKeyedUnarchiver to unarchive the data and create an HKQueryAnchor object
39
- do {
40
- let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
41
- unarchiver.requiresSecureCoding = true
42
- let anchor = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
43
-
44
- return anchor as? HKQueryAnchor
45
- } catch {
46
- print("Error: Unable to unarchive HKQueryAnchor object: \(error)")
47
- return nil
48
- }
33
+ // Step 1: Decode the base64 string to a Data object
34
+ guard let data = Data(base64Encoded: base64String) else {
35
+ print("Error: Invalid base64 string")
36
+ return nil
37
+ }
38
+
39
+ // Step 2: Use NSKeyedUnarchiver to unarchive the data and create an HKQueryAnchor object
40
+ do {
41
+ let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
42
+ unarchiver.requiresSecureCoding = true
43
+ let anchor = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
44
+
45
+ return anchor as? HKQueryAnchor
46
+ } catch {
47
+ print("Error: Unable to unarchive HKQueryAnchor object: \(error)")
48
+ return nil
49
+ }
49
50
  }
50
51
 
51
52
  func sampleTypeFromString(typeIdentifier: String) -> HKSampleType? {
@@ -102,7 +103,7 @@ func sampleTypesFromDictionary(typeIdentifiers: NSDictionary) -> Set<HKSampleTyp
102
103
  if item.value as! Bool {
103
104
  let sampleType = sampleTypeFromString(typeIdentifier: item.key as! String)
104
105
  if sampleType != nil {
105
- share.insert(sampleType!)
106
+ share.insert(sampleType!)
106
107
  }
107
108
  }
108
109
  }
@@ -134,6 +135,14 @@ func objectTypeFromString(typeIdentifier: String) -> HKObjectType? {
134
135
  return HKObjectType.activitySummaryType()
135
136
  }
136
137
 
138
+ #if compiler(>=6)
139
+ if #available(iOS 18, *) {
140
+ if typeIdentifier == HKStateOfMindTypeIdentifier {
141
+ return HKObjectType.stateOfMindType()
142
+ }
143
+ }
144
+ #endif
145
+
137
146
  if #available(iOS 13, *) {
138
147
  if typeIdentifier == HKAudiogramTypeIdentifier {
139
148
  return HKObjectType.audiogramSampleType()
@@ -217,23 +226,24 @@ func serializeQuantityIfExists(unit: HKUnit, quantity: HKQuantity?) -> [String:
217
226
  return serializeQuantity(unit: unit, quantity: quantity)
218
227
  }
219
228
 
220
- func serializeStatisticIfExists(unit: HKUnit, quantity: HKQuantity?, stats: HKStatistics) -> [String: Any]? {
229
+ func serializeStatisticIfExists(unit: HKUnit, quantity: HKQuantity?, stats: HKStatistics)
230
+ -> [String: Any]? {
221
231
  guard let quantity = quantity else { return nil }
222
232
  return serializeStatistic(unit: unit, quantity: quantity, stats: stats)
223
233
  }
224
234
 
225
235
  func parseWorkoutConfiguration(_ dict: NSDictionary) -> HKWorkoutConfiguration {
226
- let configuration = HKWorkoutConfiguration()
236
+ let configuration = HKWorkoutConfiguration()
227
237
 
228
- if let activityTypeRaw = dict[HKWorkoutActivityTypePropertyName] as? UInt,
229
- let activityType = HKWorkoutActivityType(rawValue: activityTypeRaw) {
230
- configuration.activityType = activityType
231
- }
238
+ if let activityTypeRaw = dict[HKWorkoutActivityTypePropertyName] as? UInt,
239
+ let activityType = HKWorkoutActivityType(rawValue: activityTypeRaw) {
240
+ configuration.activityType = activityType
241
+ }
232
242
 
233
- if let locationTypeRaw = dict[HKWorkoutSessionLocationTypePropertyName] as? Int,
234
- let locationType = HKWorkoutSessionLocationType(rawValue: locationTypeRaw) {
235
- configuration.locationType = locationType
236
- }
243
+ if let locationTypeRaw = dict[HKWorkoutSessionLocationTypePropertyName] as? Int,
244
+ let locationType = HKWorkoutSessionLocationType(rawValue: locationTypeRaw) {
245
+ configuration.locationType = locationType
246
+ }
237
247
 
238
- return configuration
248
+ return configuration
239
249
  }
@@ -246,4 +246,11 @@ RCT_EXTERN_METHOD(startWatchAppWithWorkoutConfiguration:(NSDictionary)workoutCon
246
246
  reject:(RCTPromiseRejectBlock)reject
247
247
  )
248
248
 
249
+ RCT_EXTERN_METHOD(queryStateOfMindSamples:(NSDate)from
250
+ to:(NSDate)to
251
+ limit:(NSInteger)limit
252
+ ascending:(BOOL)ascending
253
+ resolve:(RCTPromiseResolveBlock)resolve
254
+ reject:(RCTPromiseRejectBlock)reject)
255
+
249
256
  @end