@capgo/capacitor-health 8.2.17 → 8.3.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.
@@ -27,6 +27,19 @@ enum HealthManagerError: LocalizedError {
27
27
  }
28
28
  }
29
29
 
30
+ /// WorkoutType enum that maps TypeScript workout types to iOS HealthKit HKWorkoutActivityType values.
31
+ ///
32
+ /// This enum provides bidirectional mapping between the plugin's TypeScript workout types and
33
+ /// native iOS HealthKit workout activity types. The mapping is designed to provide maximum
34
+ /// compatibility across all iOS versions.
35
+ ///
36
+ /// iOS Version Compatibility:
37
+ /// - Most workout types are available on all supported iOS versions
38
+ /// - cardioDance and socialDance require iOS 14.0+ and fallback to .dance on older versions
39
+ /// - transition requires iOS 16.0+ and falls back to .other on older versions
40
+ /// - underwaterDiving requires iOS 17.0+ and falls back to .swimming on older versions
41
+ ///
42
+ /// Note: The enum case names match the TypeScript WorkoutType union type for consistency.
30
43
  enum WorkoutType: String, CaseIterable {
31
44
  case running
32
45
  case cycling
@@ -49,6 +62,66 @@ enum WorkoutType: String, CaseIterable {
49
62
  case waterPolo
50
63
  case waterSports
51
64
  case wrestling
65
+ case archery
66
+ case australianFootball
67
+ case badminton
68
+ case barre
69
+ case bowling
70
+ case boxing
71
+ case climbing
72
+ case cooldown
73
+ case coreTraining
74
+ case cricket
75
+ case crossCountrySkiing
76
+ case curling
77
+ case dance
78
+ case discSports
79
+ case downhillSkiing
80
+ case equestrianSports
81
+ case fencing
82
+ case fishing
83
+ case fitnessGaming
84
+ case flexibility
85
+ case functionalStrengthTraining
86
+ case golf
87
+ case gymnastics
88
+ case handball
89
+ case handCycling
90
+ case highIntensityIntervalTraining
91
+ case hockey
92
+ case hunting
93
+ case jumpRope
94
+ case kickboxing
95
+ case lacrosse
96
+ case martialArts
97
+ case mindAndBody
98
+ case mixedCardio
99
+ case paddleSports
100
+ case pickleball
101
+ case pilates
102
+ case play
103
+ case preparationAndRecovery
104
+ case racquetball
105
+ case rugby
106
+ case sailing
107
+ case skatingSports
108
+ case snowboarding
109
+ case snowSports
110
+ case softball
111
+ case squash
112
+ case stairs
113
+ case stepTraining
114
+ case surfingSports
115
+ case tableTennis
116
+ case taiChi
117
+ case trackAndField
118
+ case transition
119
+ case underwaterDiving
120
+ case volleyball
121
+ case wheelchairRunPace
122
+ case wheelchairWalkPace
123
+ case cardioDance
124
+ case socialDance
52
125
  case other
53
126
 
54
127
  func hkWorkoutActivityType() -> HKWorkoutActivityType {
@@ -95,6 +168,142 @@ enum WorkoutType: String, CaseIterable {
95
168
  return .waterSports
96
169
  case .wrestling:
97
170
  return .wrestling
171
+ case .archery:
172
+ return .archery
173
+ case .australianFootball:
174
+ return .australianFootball
175
+ case .badminton:
176
+ return .badminton
177
+ case .barre:
178
+ return .barre
179
+ case .bowling:
180
+ return .bowling
181
+ case .boxing:
182
+ return .boxing
183
+ case .climbing:
184
+ return .climbing
185
+ case .cooldown:
186
+ return .cooldown
187
+ case .coreTraining:
188
+ return .coreTraining
189
+ case .cricket:
190
+ return .cricket
191
+ case .crossCountrySkiing:
192
+ return .crossCountrySkiing
193
+ case .curling:
194
+ return .curling
195
+ case .dance:
196
+ return .dance
197
+ case .discSports:
198
+ return .discSports
199
+ case .downhillSkiing:
200
+ return .downhillSkiing
201
+ case .equestrianSports:
202
+ return .equestrianSports
203
+ case .fencing:
204
+ return .fencing
205
+ case .fishing:
206
+ return .fishing
207
+ case .fitnessGaming:
208
+ return .fitnessGaming
209
+ case .flexibility:
210
+ return .flexibility
211
+ case .functionalStrengthTraining:
212
+ return .functionalStrengthTraining
213
+ case .golf:
214
+ return .golf
215
+ case .gymnastics:
216
+ return .gymnastics
217
+ case .handball:
218
+ return .handball
219
+ case .handCycling:
220
+ return .handCycling
221
+ case .highIntensityIntervalTraining:
222
+ return .highIntensityIntervalTraining
223
+ case .hockey:
224
+ return .hockey
225
+ case .hunting:
226
+ return .hunting
227
+ case .jumpRope:
228
+ return .jumpRope
229
+ case .kickboxing:
230
+ return .kickboxing
231
+ case .lacrosse:
232
+ return .lacrosse
233
+ case .martialArts:
234
+ return .martialArts
235
+ case .mindAndBody:
236
+ return .mindAndBody
237
+ case .mixedCardio:
238
+ return .mixedCardio
239
+ case .paddleSports:
240
+ return .paddleSports
241
+ case .pickleball:
242
+ return .pickleball
243
+ case .pilates:
244
+ return .pilates
245
+ case .play:
246
+ return .play
247
+ case .preparationAndRecovery:
248
+ return .preparationAndRecovery
249
+ case .racquetball:
250
+ return .racquetball
251
+ case .rugby:
252
+ return .rugby
253
+ case .sailing:
254
+ return .sailing
255
+ case .skatingSports:
256
+ return .skatingSports
257
+ case .snowboarding:
258
+ return .snowboarding
259
+ case .snowSports:
260
+ return .snowSports
261
+ case .softball:
262
+ return .softball
263
+ case .squash:
264
+ return .squash
265
+ case .stairs:
266
+ return .stairs
267
+ case .stepTraining:
268
+ return .stepTraining
269
+ case .surfingSports:
270
+ return .surfingSports
271
+ case .tableTennis:
272
+ return .tableTennis
273
+ case .taiChi:
274
+ return .taiChi
275
+ case .trackAndField:
276
+ return .trackAndField
277
+ case .transition:
278
+ // transition requires iOS 16.0+, fallback to other for older versions
279
+ if #available(iOS 16.0, *) {
280
+ return .transition
281
+ }
282
+ return .other
283
+ case .underwaterDiving:
284
+ // underwaterDiving requires iOS 17.0+, fallback to swimming for older versions
285
+ if #available(iOS 17.0, *) {
286
+ return .underwaterDiving
287
+ }
288
+ return .swimming
289
+ case .volleyball:
290
+ return .volleyball
291
+ case .wheelchairRunPace:
292
+ return .wheelchairRunPace
293
+ case .wheelchairWalkPace:
294
+ return .wheelchairWalkPace
295
+ case .cardioDance:
296
+ // cardioDance requires iOS 14.0+, fallback to dance for older versions
297
+ if #available(iOS 14.0, *) {
298
+ return .cardioDance
299
+ }
300
+ return .dance
301
+ case .socialDance:
302
+ // socialDance requires iOS 14.0+, fallback to dance for older versions
303
+ if #available(iOS 14.0, *) {
304
+ return .socialDance
305
+ }
306
+ return .dance
98
307
  case .other:
99
308
  return .other
100
309
  }
@@ -112,8 +321,11 @@ enum WorkoutType: String, CaseIterable {
112
321
  return .swimming
113
322
  case .yoga:
114
323
  return .yoga
324
+ // Note: Both plugin workout types "strengthTraining" and "traditionalStrengthTraining"
325
+ // are written to HealthKit as HKWorkoutActivityType.traditionalStrengthTraining.
326
+ // When reading from HealthKit we always normalize back to .strengthTraining to keep
327
+ // a single canonical plugin type and maintain backward compatibility.
115
328
  case .traditionalStrengthTraining:
116
- // Map back to strengthTraining for consistency (both map to the same HK type)
117
329
  return .strengthTraining
118
330
  case .hiking:
119
331
  return .hiking
@@ -143,7 +355,140 @@ enum WorkoutType: String, CaseIterable {
143
355
  return .waterSports
144
356
  case .wrestling:
145
357
  return .wrestling
358
+ case .archery:
359
+ return .archery
360
+ case .australianFootball:
361
+ return .australianFootball
362
+ case .badminton:
363
+ return .badminton
364
+ case .barre:
365
+ return .barre
366
+ case .bowling:
367
+ return .bowling
368
+ case .boxing:
369
+ return .boxing
370
+ case .climbing:
371
+ return .climbing
372
+ case .cooldown:
373
+ return .cooldown
374
+ case .coreTraining:
375
+ return .coreTraining
376
+ case .cricket:
377
+ return .cricket
378
+ case .crossCountrySkiing:
379
+ return .crossCountrySkiing
380
+ case .curling:
381
+ return .curling
382
+ case .dance:
383
+ return .dance
384
+ case .discSports:
385
+ return .discSports
386
+ case .downhillSkiing:
387
+ return .downhillSkiing
388
+ case .equestrianSports:
389
+ return .equestrianSports
390
+ case .fencing:
391
+ return .fencing
392
+ case .fishing:
393
+ return .fishing
394
+ case .fitnessGaming:
395
+ return .fitnessGaming
396
+ case .flexibility:
397
+ return .flexibility
398
+ case .functionalStrengthTraining:
399
+ return .functionalStrengthTraining
400
+ case .golf:
401
+ return .golf
402
+ case .gymnastics:
403
+ return .gymnastics
404
+ case .handball:
405
+ return .handball
406
+ case .handCycling:
407
+ return .handCycling
408
+ case .highIntensityIntervalTraining:
409
+ return .highIntensityIntervalTraining
410
+ case .hockey:
411
+ return .hockey
412
+ case .hunting:
413
+ return .hunting
414
+ case .jumpRope:
415
+ return .jumpRope
416
+ case .kickboxing:
417
+ return .kickboxing
418
+ case .lacrosse:
419
+ return .lacrosse
420
+ case .martialArts:
421
+ return .martialArts
422
+ case .mindAndBody:
423
+ return .mindAndBody
424
+ case .mixedCardio:
425
+ return .mixedCardio
426
+ case .paddleSports:
427
+ return .paddleSports
428
+ case .pickleball:
429
+ return .pickleball
430
+ case .pilates:
431
+ return .pilates
432
+ case .play:
433
+ return .play
434
+ case .preparationAndRecovery:
435
+ return .preparationAndRecovery
436
+ case .racquetball:
437
+ return .racquetball
438
+ case .rugby:
439
+ return .rugby
440
+ case .sailing:
441
+ return .sailing
442
+ case .skatingSports:
443
+ return .skatingSports
444
+ case .snowboarding:
445
+ return .snowboarding
446
+ case .snowSports:
447
+ return .snowSports
448
+ case .softball:
449
+ return .softball
450
+ case .squash:
451
+ return .squash
452
+ case .stairs:
453
+ return .stairs
454
+ case .stepTraining:
455
+ return .stepTraining
456
+ case .surfingSports:
457
+ return .surfingSports
458
+ case .tableTennis:
459
+ return .tableTennis
460
+ case .taiChi:
461
+ return .taiChi
462
+ case .trackAndField:
463
+ return .trackAndField
464
+ case .volleyball:
465
+ return .volleyball
466
+ case .wheelchairRunPace:
467
+ return .wheelchairRunPace
468
+ case .wheelchairWalkPace:
469
+ return .wheelchairWalkPace
146
470
  default:
471
+ // Handle iOS 14+ types
472
+ if #available(iOS 14.0, *) {
473
+ if hkType == .cardioDance {
474
+ return .cardioDance
475
+ }
476
+ if hkType == .socialDance {
477
+ return .socialDance
478
+ }
479
+ }
480
+ // Handle iOS 16+ types
481
+ if #available(iOS 16.0, *) {
482
+ if hkType == .transition {
483
+ return .transition
484
+ }
485
+ }
486
+ // Handle iOS 17+ types
487
+ if #available(iOS 17.0, *) {
488
+ if hkType == .underwaterDiving {
489
+ return .underwaterDiving
490
+ }
491
+ }
147
492
  return .other
148
493
  }
149
494
  }
@@ -160,6 +505,18 @@ enum HealthDataType: String, CaseIterable {
160
505
  case oxygenSaturation
161
506
  case restingHeartRate
162
507
  case heartRateVariability
508
+ case bloodPressure
509
+ case bloodGlucose
510
+ case bodyTemperature
511
+ case height
512
+ case flightsClimbed
513
+ case exerciseTime
514
+ case distanceCycling
515
+ case bodyFat
516
+ case basalBodyTemperature
517
+ case basalCalories
518
+ case totalCalories
519
+ case mindfulness
163
520
 
164
521
  func sampleType() throws -> HKSampleType {
165
522
  switch self {
@@ -168,6 +525,16 @@ enum HealthDataType: String, CaseIterable {
168
525
  throw HealthManagerError.dataTypeUnavailable(rawValue)
169
526
  }
170
527
  return type
528
+ case .bloodPressure:
529
+ guard let type = HKObjectType.correlationType(forIdentifier: .bloodPressure) else {
530
+ throw HealthManagerError.dataTypeUnavailable(rawValue)
531
+ }
532
+ return type
533
+ case .mindfulness:
534
+ guard let type = HKObjectType.categoryType(forIdentifier: .mindfulSession) else {
535
+ throw HealthManagerError.dataTypeUnavailable(rawValue)
536
+ }
537
+ return type
171
538
  default:
172
539
  return try quantityType()
173
540
  }
@@ -194,8 +561,32 @@ enum HealthDataType: String, CaseIterable {
194
561
  identifier = .restingHeartRate
195
562
  case .heartRateVariability:
196
563
  identifier = .heartRateVariabilitySDNN
564
+ case .bloodGlucose:
565
+ identifier = .bloodGlucose
566
+ case .bodyTemperature:
567
+ identifier = .bodyTemperature
568
+ case .height:
569
+ identifier = .height
570
+ case .flightsClimbed:
571
+ identifier = .flightsClimbed
572
+ case .exerciseTime:
573
+ identifier = .appleExerciseTime
574
+ case .distanceCycling:
575
+ identifier = .distanceCycling
576
+ case .bodyFat:
577
+ identifier = .bodyFatPercentage
578
+ case .basalBodyTemperature:
579
+ identifier = .basalBodyTemperature
580
+ case .basalCalories:
581
+ identifier = .basalEnergyBurned
582
+ case .totalCalories:
583
+ identifier = .activeEnergyBurned
197
584
  case .sleep:
198
585
  throw HealthManagerError.invalidDataType("Sleep is a category type, not a quantity type")
586
+ case .bloodPressure:
587
+ throw HealthManagerError.invalidDataType("Blood pressure is a correlation type, not a quantity type")
588
+ case .mindfulness:
589
+ throw HealthManagerError.invalidDataType("Mindfulness is a category type, not a quantity type")
199
590
  }
200
591
 
201
592
  guard let type = HKObjectType.quantityType(forIdentifier: identifier) else {
@@ -224,6 +615,28 @@ enum HealthDataType: String, CaseIterable {
224
615
  return HKUnit.secondUnit(with: .milli)
225
616
  case .sleep:
226
617
  return HKUnit.minute()
618
+ case .bloodPressure:
619
+ return HKUnit.millimeterOfMercury()
620
+ case .bloodGlucose:
621
+ return HKUnit.gramUnit(with: .milli).unitDivided(by: HKUnit.literUnit(with: .deci))
622
+ case .bodyTemperature, .basalBodyTemperature:
623
+ return HKUnit.degreeCelsius()
624
+ case .height:
625
+ return HKUnit.meterUnit(with: .centi)
626
+ case .flightsClimbed:
627
+ return HKUnit.count()
628
+ case .exerciseTime:
629
+ return HKUnit.minute()
630
+ case .distanceCycling:
631
+ return HKUnit.meter()
632
+ case .bodyFat:
633
+ return HKUnit.percent()
634
+ case .basalCalories:
635
+ return HKUnit.kilocalorie()
636
+ case .totalCalories:
637
+ return HKUnit.kilocalorie()
638
+ case .mindfulness:
639
+ return HKUnit.minute()
227
640
  }
228
641
  }
229
642
 
@@ -245,6 +658,28 @@ enum HealthDataType: String, CaseIterable {
245
658
  return "millisecond"
246
659
  case .sleep:
247
660
  return "minute"
661
+ case .bloodPressure:
662
+ return "mmHg"
663
+ case .bloodGlucose:
664
+ return "mg/dL"
665
+ case .bodyTemperature, .basalBodyTemperature:
666
+ return "celsius"
667
+ case .height:
668
+ return "centimeter"
669
+ case .flightsClimbed:
670
+ return "count"
671
+ case .exerciseTime:
672
+ return "minute"
673
+ case .distanceCycling:
674
+ return "meter"
675
+ case .bodyFat:
676
+ return "percent"
677
+ case .basalCalories:
678
+ return "kilocalorie"
679
+ case .totalCalories:
680
+ return "kilocalorie"
681
+ case .mindfulness:
682
+ return "minute"
248
683
  }
249
684
  }
250
685
 
@@ -415,6 +850,94 @@ final class Health {
415
850
  healthStore.execute(query)
416
851
  return
417
852
  }
853
+
854
+ // Handle mindfulness as a category sample
855
+ if dataType == .mindfulness {
856
+ let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: queryLimit, sortDescriptors: [sortDescriptor]) { [weak self] _, samples, error in
857
+ guard let self = self else { return }
858
+
859
+ if let error = error {
860
+ completion(.failure(error))
861
+ return
862
+ }
863
+
864
+ guard let categorySamples = samples as? [HKCategorySample] else {
865
+ completion(.success([]))
866
+ return
867
+ }
868
+
869
+ let results = categorySamples.map { sample -> [String: Any] in
870
+ let durationMinutes = sample.endDate.timeIntervalSince(sample.startDate) / 60.0
871
+
872
+ var payload: [String: Any] = [
873
+ "dataType": dataType.rawValue,
874
+ "value": durationMinutes,
875
+ "unit": dataType.unitIdentifier,
876
+ "startDate": self.isoFormatter.string(from: sample.startDate),
877
+ "endDate": self.isoFormatter.string(from: sample.endDate)
878
+ ]
879
+
880
+ let source = sample.sourceRevision.source
881
+ payload["sourceName"] = source.name
882
+ payload["sourceId"] = source.bundleIdentifier
883
+
884
+ return payload
885
+ }
886
+
887
+ completion(.success(results))
888
+ }
889
+ healthStore.execute(query)
890
+ return
891
+ }
892
+
893
+ // Handle blood pressure as a correlation sample
894
+ if dataType == .bloodPressure {
895
+ let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: queryLimit, sortDescriptors: [sortDescriptor]) { [weak self] _, samples, error in
896
+ guard let self = self else { return }
897
+
898
+ if let error = error {
899
+ completion(.failure(error))
900
+ return
901
+ }
902
+
903
+ guard let correlations = samples as? [HKCorrelation] else {
904
+ completion(.success([]))
905
+ return
906
+ }
907
+
908
+ let results = correlations.compactMap { correlation -> [String: Any]? in
909
+ guard let systolicType = HKObjectType.quantityType(forIdentifier: .bloodPressureSystolic),
910
+ let diastolicType = HKObjectType.quantityType(forIdentifier: .bloodPressureDiastolic),
911
+ let systolicSample = correlation.objects(for: systolicType).first as? HKQuantitySample,
912
+ let diastolicSample = correlation.objects(for: diastolicType).first as? HKQuantitySample else {
913
+ return nil
914
+ }
915
+
916
+ let systolicValue = systolicSample.quantity.doubleValue(for: HKUnit.millimeterOfMercury())
917
+ let diastolicValue = diastolicSample.quantity.doubleValue(for: HKUnit.millimeterOfMercury())
918
+
919
+ var payload: [String: Any] = [
920
+ "dataType": dataType.rawValue,
921
+ "value": systolicValue,
922
+ "unit": dataType.unitIdentifier,
923
+ "startDate": self.isoFormatter.string(from: correlation.startDate),
924
+ "endDate": self.isoFormatter.string(from: correlation.endDate),
925
+ "systolic": systolicValue,
926
+ "diastolic": diastolicValue
927
+ ]
928
+
929
+ let source = correlation.sourceRevision.source
930
+ payload["sourceName"] = source.name
931
+ payload["sourceId"] = source.bundleIdentifier
932
+
933
+ return payload
934
+ }
935
+
936
+ completion(.success(results))
937
+ }
938
+ healthStore.execute(query)
939
+ return
940
+ }
418
941
 
419
942
  // Handle quantity samples
420
943
  let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: queryLimit, sortDescriptors: [sortDescriptor]) { [weak self] _, samples, error in
@@ -481,7 +1004,7 @@ final class Health {
481
1004
  }
482
1005
  }
483
1006
 
484
- func saveSample(dataTypeIdentifier: String, value: Double, unitIdentifier: String?, startDateString: String?, endDateString: String?, metadata: [String: String]?, completion: @escaping (Result<Void, Error>) -> Void) throws {
1007
+ func saveSample(dataTypeIdentifier: String, value: Double, unitIdentifier: String?, startDateString: String?, endDateString: String?, metadata: [String: String]?, systolic: Double?, diastolic: Double?, completion: @escaping (Result<Void, Error>) -> Void) throws {
485
1008
  guard HKHealthStore.isHealthDataAvailable() else {
486
1009
  throw HealthManagerError.healthDataUnavailable
487
1010
  }
@@ -526,6 +1049,63 @@ final class Health {
526
1049
  }
527
1050
  return
528
1051
  }
1052
+
1053
+ // Handle mindfulness as a category sample
1054
+ if dataType == .mindfulness {
1055
+ guard let categoryType = HKObjectType.categoryType(forIdentifier: .mindfulSession) else {
1056
+ throw HealthManagerError.dataTypeUnavailable(dataTypeIdentifier)
1057
+ }
1058
+ let sample = HKCategorySample(type: categoryType, value: 0, start: startDate, end: endDate, metadata: metadataDictionary)
1059
+
1060
+ healthStore.save(sample) { success, error in
1061
+ if let error = error {
1062
+ completion(.failure(error))
1063
+ return
1064
+ }
1065
+
1066
+ if success {
1067
+ completion(.success(()))
1068
+ } else {
1069
+ completion(.failure(HealthManagerError.operationFailed("Failed to save the sample.")))
1070
+ }
1071
+ }
1072
+ return
1073
+ }
1074
+
1075
+ // Handle blood pressure as a correlation sample
1076
+ if dataType == .bloodPressure {
1077
+ guard let systolicValue = systolic, let diastolicValue = diastolic else {
1078
+ throw HealthManagerError.operationFailed("Blood pressure requires both systolic and diastolic values")
1079
+ }
1080
+
1081
+ guard let systolicType = HKObjectType.quantityType(forIdentifier: .bloodPressureSystolic),
1082
+ let diastolicType = HKObjectType.quantityType(forIdentifier: .bloodPressureDiastolic),
1083
+ let correlationType = HKObjectType.correlationType(forIdentifier: .bloodPressure) else {
1084
+ throw HealthManagerError.dataTypeUnavailable(dataTypeIdentifier)
1085
+ }
1086
+
1087
+ let systolicQuantity = HKQuantity(unit: HKUnit.millimeterOfMercury(), doubleValue: systolicValue)
1088
+ let diastolicQuantity = HKQuantity(unit: HKUnit.millimeterOfMercury(), doubleValue: diastolicValue)
1089
+
1090
+ let systolicSample = HKQuantitySample(type: systolicType, quantity: systolicQuantity, start: startDate, end: endDate)
1091
+ let diastolicSample = HKQuantitySample(type: diastolicType, quantity: diastolicQuantity, start: startDate, end: endDate)
1092
+
1093
+ let correlation = HKCorrelation(type: correlationType, start: startDate, end: endDate, objects: [systolicSample, diastolicSample], metadata: metadataDictionary)
1094
+
1095
+ healthStore.save(correlation) { success, error in
1096
+ if let error = error {
1097
+ completion(.failure(error))
1098
+ return
1099
+ }
1100
+
1101
+ if success {
1102
+ completion(.success(()))
1103
+ } else {
1104
+ completion(.failure(HealthManagerError.operationFailed("Failed to save the sample.")))
1105
+ }
1106
+ }
1107
+ return
1108
+ }
529
1109
 
530
1110
  // Handle quantity samples
531
1111
  let sampleType = try dataType.quantityType()
@@ -3,7 +3,7 @@ import Capacitor
3
3
 
4
4
  @objc(HealthPlugin)
5
5
  public class HealthPlugin: CAPPlugin, CAPBridgedPlugin {
6
- private let pluginVersion: String = "8.2.17"
6
+ private let pluginVersion: String = "8.3.0"
7
7
  public let identifier = "HealthPlugin"
8
8
  public let jsName = "Health"
9
9
  public let pluginMethods: [CAPPluginMethod] = [
@@ -110,6 +110,9 @@ public class HealthPlugin: CAPPlugin, CAPBridgedPlugin {
110
110
  result[entry.key] = stringValue
111
111
  }
112
112
  }
113
+
114
+ let systolic = call.getDouble("systolic")
115
+ let diastolic = call.getDouble("diastolic")
113
116
 
114
117
  do {
115
118
  try implementation.saveSample(
@@ -118,7 +121,9 @@ public class HealthPlugin: CAPPlugin, CAPBridgedPlugin {
118
121
  unitIdentifier: unit,
119
122
  startDateString: startDate,
120
123
  endDateString: endDate,
121
- metadata: metadata
124
+ metadata: metadata,
125
+ systolic: systolic,
126
+ diastolic: diastolic
122
127
  ) { result in
123
128
  DispatchQueue.main.async {
124
129
  switch result {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-health",
3
- "version": "8.2.17",
3
+ "version": "8.3.0",
4
4
  "description": "Capacitor plugin to interact with data from Apple HealthKit and Health Connect",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",