@kingstinct/react-native-healthkit 8.4.0 → 8.6.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/ios/Helpers.swift +180 -31
- package/ios/ReactNativeHealthkit.m +14 -0
- package/ios/ReactNativeHealthkit.swift +504 -268
- package/lib/commonjs/index.ios.js +19 -1
- package/lib/commonjs/index.ios.js.map +1 -1
- package/lib/commonjs/index.native.js +7 -1
- package/lib/commonjs/index.native.js.map +1 -1
- package/lib/commonjs/native-types.js +16 -1
- package/lib/commonjs/native-types.js.map +1 -1
- package/lib/commonjs/test-setup.js +3 -1
- package/lib/commonjs/test-setup.js.map +1 -1
- package/lib/commonjs/utils/saveStateOfMindSample.js +17 -0
- package/lib/commonjs/utils/saveStateOfMindSample.js.map +1 -0
- package/lib/commonjs/utils/subscribeToChanges.js.map +1 -1
- package/lib/commonjs/utils/workoutSessionMirroringStartHandler.js +17 -0
- package/lib/commonjs/utils/workoutSessionMirroringStartHandler.js.map +1 -0
- package/lib/module/index.ios.js +5 -1
- package/lib/module/index.ios.js.map +1 -1
- package/lib/module/index.native.js +5 -1
- package/lib/module/index.native.js.map +1 -1
- package/lib/module/native-types.js +16 -0
- package/lib/module/native-types.js.map +1 -1
- package/lib/module/test-setup.js +3 -1
- package/lib/module/test-setup.js.map +1 -1
- package/lib/module/utils/saveStateOfMindSample.js +10 -0
- package/lib/module/utils/saveStateOfMindSample.js.map +1 -0
- package/lib/module/utils/subscribeToChanges.js.map +1 -1
- package/lib/module/utils/workoutSessionMirroringStartHandler.js +11 -0
- package/lib/module/utils/workoutSessionMirroringStartHandler.js.map +1 -0
- package/lib/typescript/src/index.ios.d.ts +5 -1
- package/lib/typescript/src/index.native.d.ts +2 -2
- package/lib/typescript/src/native-types.d.ts +43 -2
- package/lib/typescript/src/utils/saveStateOfMindSample.d.ts +11 -0
- package/lib/typescript/src/utils/workoutSessionMirroringStartHandler.d.ts +8 -0
- package/package.json +1 -1
- package/src/index.ios.tsx +6 -0
- package/src/index.native.tsx +6 -0
- package/src/native-types.ts +58 -3
- package/src/test-setup.ts +2 -0
- package/src/utils/saveStateOfMindSample.ts +38 -0
- package/src/utils/subscribeToChanges.ts +1 -1
- package/src/utils/workoutSessionMirroringStartHandler.ts +11 -0
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
|
-
|
|
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
|
+
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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)
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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? {
|
|
@@ -70,6 +71,14 @@ func sampleTypeFromString(typeIdentifier: String) -> HKSampleType? {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
#if compiler(>=6)
|
|
75
|
+
if #available(iOS 18, *) {
|
|
76
|
+
if typeIdentifier == HKStateOfMindTypeIdentifier {
|
|
77
|
+
return HKObjectType.stateOfMindType()
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
#endif
|
|
81
|
+
|
|
73
82
|
if typeIdentifier == HKWorkoutTypeIdentifier {
|
|
74
83
|
return HKSampleType.workoutType()
|
|
75
84
|
}
|
|
@@ -102,7 +111,7 @@ func sampleTypesFromDictionary(typeIdentifiers: NSDictionary) -> Set<HKSampleTyp
|
|
|
102
111
|
if item.value as! Bool {
|
|
103
112
|
let sampleType = sampleTypeFromString(typeIdentifier: item.key as! String)
|
|
104
113
|
if sampleType != nil {
|
|
105
|
-
|
|
114
|
+
share.insert(sampleType!)
|
|
106
115
|
}
|
|
107
116
|
}
|
|
108
117
|
}
|
|
@@ -134,11 +143,13 @@ func objectTypeFromString(typeIdentifier: String) -> HKObjectType? {
|
|
|
134
143
|
return HKObjectType.activitySummaryType()
|
|
135
144
|
}
|
|
136
145
|
|
|
137
|
-
if
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
#if compiler(>=6)
|
|
147
|
+
if #available(iOS 18, *) {
|
|
148
|
+
if typeIdentifier == HKStateOfMindTypeIdentifier {
|
|
149
|
+
return HKObjectType.stateOfMindType()
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
#endif
|
|
142
153
|
|
|
143
154
|
if #available(iOS 13, *) {
|
|
144
155
|
if typeIdentifier == HKAudiogramTypeIdentifier {
|
|
@@ -223,23 +234,161 @@ func serializeQuantityIfExists(unit: HKUnit, quantity: HKQuantity?) -> [String:
|
|
|
223
234
|
return serializeQuantity(unit: unit, quantity: quantity)
|
|
224
235
|
}
|
|
225
236
|
|
|
226
|
-
func serializeStatisticIfExists(unit: HKUnit, quantity: HKQuantity?, stats: HKStatistics)
|
|
237
|
+
func serializeStatisticIfExists(unit: HKUnit, quantity: HKQuantity?, stats: HKStatistics)
|
|
238
|
+
-> [String: Any]? {
|
|
227
239
|
guard let quantity = quantity else { return nil }
|
|
228
240
|
return serializeStatistic(unit: unit, quantity: quantity, stats: stats)
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
func parseWorkoutConfiguration(_ dict: NSDictionary) -> HKWorkoutConfiguration {
|
|
232
|
-
|
|
244
|
+
let configuration = HKWorkoutConfiguration()
|
|
245
|
+
|
|
246
|
+
if let activityTypeRaw = dict[HKWorkoutActivityTypePropertyName] as? UInt,
|
|
247
|
+
let activityType = HKWorkoutActivityType(rawValue: activityTypeRaw) {
|
|
248
|
+
configuration.activityType = activityType
|
|
249
|
+
}
|
|
233
250
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
251
|
+
if let locationTypeRaw = dict[HKWorkoutSessionLocationTypePropertyName] as? Int,
|
|
252
|
+
let locationType = HKWorkoutSessionLocationType(rawValue: locationTypeRaw) {
|
|
253
|
+
configuration.locationType = locationType
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return configuration
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
#if compiler(>=6)
|
|
260
|
+
@available(iOS 18.0, *)
|
|
261
|
+
extension HKStateOfMind.Kind: @retroactive CaseIterable, @retroactive CustomStringConvertible {
|
|
262
|
+
public var description: String {
|
|
263
|
+
switch self {
|
|
264
|
+
case .dailyMood: "Daily mood"
|
|
265
|
+
case .momentaryEmotion: "Momentary Emotion"
|
|
266
|
+
@unknown default: "Unknown"
|
|
267
|
+
}
|
|
237
268
|
}
|
|
238
269
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
configuration.locationType = locationType
|
|
270
|
+
public static var allCases: [HKStateOfMind.Kind] {
|
|
271
|
+
[.dailyMood, .momentaryEmotion]
|
|
242
272
|
}
|
|
243
273
|
|
|
244
|
-
|
|
274
|
+
static func convertToStateOfMindKind(int: Int) -> HKStateOfMind.Kind {
|
|
275
|
+
// default to .dailyMood if we receive an int out of bounds
|
|
276
|
+
return HKStateOfMind.Kind(rawValue: int) ?? .dailyMood
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
#endif
|
|
280
|
+
|
|
281
|
+
#if compiler(>=6)
|
|
282
|
+
@available(iOS 18.0, *)
|
|
283
|
+
extension HKStateOfMind.Label: @retroactive CaseIterable, @retroactive CustomStringConvertible {
|
|
284
|
+
public var description: String {
|
|
285
|
+
switch self {
|
|
286
|
+
case .amazed: "Amazed"
|
|
287
|
+
case .amused: "Amused"
|
|
288
|
+
case .angry: "Angry"
|
|
289
|
+
case .anxious: "Anxious"
|
|
290
|
+
case .ashamed: "Ashamed"
|
|
291
|
+
case .brave: "Brave"
|
|
292
|
+
case .calm: "Calm"
|
|
293
|
+
case .content: "Content"
|
|
294
|
+
case .disappointed: "Disappointed"
|
|
295
|
+
case .discouraged: "Discouraged"
|
|
296
|
+
case .disgusted: "Disgusted"
|
|
297
|
+
case .embarrassed: "Embarrassed"
|
|
298
|
+
case .excited: "Excited"
|
|
299
|
+
case .frustrated: "Frustrated"
|
|
300
|
+
case .grateful: "Grateful"
|
|
301
|
+
case .guilty: "Guilty"
|
|
302
|
+
case .happy: "Happy"
|
|
303
|
+
case .hopeless: "Hopeless"
|
|
304
|
+
case .irritated: "Irritated"
|
|
305
|
+
case .jealous: "Jealous"
|
|
306
|
+
case .joyful: "Joyful"
|
|
307
|
+
case .lonely: "Lonely"
|
|
308
|
+
case .passionate: "Passionate"
|
|
309
|
+
case .peaceful: "Peaceful"
|
|
310
|
+
case .proud: "Proud"
|
|
311
|
+
case .relieved: "Relieved"
|
|
312
|
+
case .sad: "Sad"
|
|
313
|
+
case .scared: "Scared"
|
|
314
|
+
case .stressed: "Stressed"
|
|
315
|
+
case .surprised: "Surprised"
|
|
316
|
+
case .worried: "Worried"
|
|
317
|
+
case .annoyed: "Annoyed"
|
|
318
|
+
case .confident: "Confident"
|
|
319
|
+
case .drained: "Drained"
|
|
320
|
+
case .hopeful: "Hopeful"
|
|
321
|
+
case .indifferent: "Indifferent"
|
|
322
|
+
case .overwhelmed: "Overwhelmed"
|
|
323
|
+
case .satisfied: "Satisfied"
|
|
324
|
+
@unknown default: "Unknown"
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
public static var allCases: [HKStateOfMind.Label] {
|
|
329
|
+
[
|
|
330
|
+
.amazed, .amused, .angry, .anxious, .ashamed,
|
|
331
|
+
.brave, .calm, .content, .disappointed, .discouraged,
|
|
332
|
+
.disgusted, .embarrassed, .excited, .frustrated, .grateful,
|
|
333
|
+
.guilty, .happy, .hopeless, .irritated, .jealous,
|
|
334
|
+
.joyful, .lonely, .passionate, .peaceful, .proud,
|
|
335
|
+
.relieved, .sad, .scared, .stressed, .surprised,
|
|
336
|
+
.worried, .annoyed, .confident, .drained, .hopeful,
|
|
337
|
+
.indifferent, .overwhelmed, .satisfied
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static func convertToStateOfMindLabels(intArray: [Int]) -> [HKStateOfMind.Label] {
|
|
342
|
+
return intArray.compactMap { index in
|
|
343
|
+
// if any int are out of bounds return nil instead of crashing
|
|
344
|
+
guard index >= 0 && index < HKStateOfMind.Label.allCases.count else { return nil }
|
|
345
|
+
return HKStateOfMind.Label(rawValue: index)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
#endif
|
|
350
|
+
|
|
351
|
+
#if compiler(>=6)
|
|
352
|
+
@available(iOS 18.0, *)
|
|
353
|
+
extension HKStateOfMind.Association: @retroactive CaseIterable, @retroactive CustomStringConvertible {
|
|
354
|
+
public var description: String {
|
|
355
|
+
switch self {
|
|
356
|
+
case .community: "Community"
|
|
357
|
+
case .currentEvents: "Current Events"
|
|
358
|
+
case .dating: "Dating"
|
|
359
|
+
case .education: "Education"
|
|
360
|
+
case .family: "Family"
|
|
361
|
+
case .fitness: "Fitness"
|
|
362
|
+
case .friends: "Friends"
|
|
363
|
+
case .health: "Health"
|
|
364
|
+
case .hobbies: "Hobbies"
|
|
365
|
+
case .identity: "Identity"
|
|
366
|
+
case .money: "Money"
|
|
367
|
+
case .partner: "Partner"
|
|
368
|
+
case .selfCare: "Self Care"
|
|
369
|
+
case .spirituality: "Spirituality"
|
|
370
|
+
case .tasks: "Tasks"
|
|
371
|
+
case .travel: "Travel"
|
|
372
|
+
case .work: "Work"
|
|
373
|
+
case .weather: "Weather"
|
|
374
|
+
@unknown default: "Unknown"
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
public static var allCases: [HKStateOfMind.Association] {
|
|
379
|
+
[
|
|
380
|
+
.community, .currentEvents, .dating, .education, .family,
|
|
381
|
+
.fitness, .friends, .health, .hobbies, .identity,
|
|
382
|
+
.money, .partner, .selfCare, .spirituality, .tasks,
|
|
383
|
+
.travel, .work, .weather
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
static func convertToStateOfMindAssociations(intArray: [Int]) -> [HKStateOfMind.Association] {
|
|
388
|
+
return intArray.compactMap { index in
|
|
389
|
+
guard index >= 0 && index < HKStateOfMind.Association.allCases.count else { return nil }
|
|
390
|
+
return HKStateOfMind.Association(rawValue: index)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
245
393
|
}
|
|
394
|
+
#endif
|
|
@@ -88,6 +88,16 @@ RCT_EXTERN_METHOD(saveCategorySample:(NSString)typeIdentifier
|
|
|
88
88
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
89
89
|
reject:(RCTPromiseRejectBlock)reject
|
|
90
90
|
)
|
|
91
|
+
RCT_EXTERN_METHOD(saveStateOfMindSample:(NSDate)date
|
|
92
|
+
kind:(NSInteger)kind
|
|
93
|
+
valence:(double)valence
|
|
94
|
+
labels:(NSArray)labels
|
|
95
|
+
associations:(NSArray)associations
|
|
96
|
+
metadata:(NSDictionary)metadata
|
|
97
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
98
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
99
|
+
)
|
|
100
|
+
|
|
91
101
|
|
|
92
102
|
RCT_EXTERN_METHOD(queryWorkoutSamplesWithAnchor:(NSString)energyUnitString
|
|
93
103
|
distanceUnitString:(NSString)distanceUnitString
|
|
@@ -253,4 +263,8 @@ RCT_EXTERN_METHOD(queryStateOfMindSamples:(NSDate)from
|
|
|
253
263
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
254
264
|
reject:(RCTPromiseRejectBlock)reject)
|
|
255
265
|
|
|
266
|
+
RCT_EXTERN_METHOD(workoutSessionMirroringStartHandler:(RCTPromiseResolveBlock)resolve
|
|
267
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
268
|
+
)
|
|
269
|
+
|
|
256
270
|
@end
|