@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.
- package/README.md +10 -3
- package/ios/Constants.swift +1 -0
- package/ios/Helpers.swift +40 -30
- package/ios/ReactNativeHealthkit.m +7 -0
- package/ios/ReactNativeHealthkit.swift +356 -208
- package/lib/commonjs/index.ios.js +10 -1
- package/lib/commonjs/index.ios.js.map +1 -1
- package/lib/commonjs/index.native.js +7 -4
- package/lib/commonjs/index.native.js.map +1 -1
- package/lib/commonjs/native-types.js +94 -1
- package/lib/commonjs/native-types.js.map +1 -1
- package/lib/commonjs/test-setup.js +2 -1
- package/lib/commonjs/test-setup.js.map +1 -1
- package/lib/commonjs/utils/queryStateOfMindSamples.js +22 -0
- package/lib/commonjs/utils/queryStateOfMindSamples.js.map +1 -0
- package/lib/module/index.ios.js +4 -2
- package/lib/module/index.ios.js.map +1 -1
- package/lib/module/index.native.js +5 -3
- package/lib/module/index.native.js.map +1 -1
- package/lib/module/native-types.js +96 -0
- package/lib/module/native-types.js.map +1 -1
- package/lib/module/test-setup.js +2 -1
- package/lib/module/test-setup.js.map +1 -1
- package/lib/module/utils/queryStateOfMindSamples.js +14 -0
- package/lib/module/utils/queryStateOfMindSamples.js.map +1 -0
- package/lib/typescript/src/index.ios.d.ts +8 -1
- package/lib/typescript/src/index.native.d.ts +2 -2
- package/lib/typescript/src/native-types.d.ts +117 -1
- package/lib/typescript/src/utils/queryStateOfMindSamples.d.ts +7 -0
- package/package.json +1 -1
- package/src/index.ios.tsx +3 -0
- package/src/index.native.tsx +4 -1
- package/src/native-types.ts +131 -0
- package/src/test-setup.ts +1 -0
- package/src/utils/queryStateOfMindSamples.ts +14 -0
- package/ios/ReactNativeHealthkit.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/ReactNativeHealthkit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/ios/ReactNativeHealthkit.xcodeproj/project.xcworkspace/xcuserdata/robertherber.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- 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.
|
|
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
|
|
143
|
+
const { newAnchor, samples, deletedSamples } = await queryQuantitySamplesWithAnchor(HKQuantityTypeIdentifier.stepCount, {
|
|
137
144
|
limit: 2,
|
|
138
145
|
})
|
|
139
146
|
|
|
140
|
-
const nextResult = await
|
|
147
|
+
const nextResult = await queryQuantitySamplesWithAnchor(HKQuantityTypeIdentifier.stepCount, {
|
|
141
148
|
limit: 2,
|
|
142
149
|
anchor: newAnchor,
|
|
143
150
|
})
|
package/ios/Constants.swift
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
|
|
236
|
+
let configuration = HKWorkoutConfiguration()
|
|
227
237
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
238
|
+
if let activityTypeRaw = dict[HKWorkoutActivityTypePropertyName] as? UInt,
|
|
239
|
+
let activityType = HKWorkoutActivityType(rawValue: activityTypeRaw) {
|
|
240
|
+
configuration.activityType = activityType
|
|
241
|
+
}
|
|
232
242
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
if let locationTypeRaw = dict[HKWorkoutSessionLocationTypePropertyName] as? Int,
|
|
244
|
+
let locationType = HKWorkoutSessionLocationType(rawValue: locationTypeRaw) {
|
|
245
|
+
configuration.locationType = locationType
|
|
246
|
+
}
|
|
237
247
|
|
|
238
|
-
|
|
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
|