@capgo/capacitor-health 8.5.0 → 8.5.2

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.
@@ -330,7 +330,7 @@ class HealthPlugin : Plugin() {
330
330
  @PluginMethod
331
331
  fun openHealthConnectSettings(call: PluginCall) {
332
332
  try {
333
- val intent = Intent(HEALTH_CONNECT_SETTINGS_ACTION)
333
+ val intent = Intent(HealthConnectClient.ACTION_HEALTH_CONNECT_SETTINGS)
334
334
  intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
335
335
  context.startActivity(intent)
336
336
  call.resolve()
@@ -440,6 +440,5 @@ class HealthPlugin : Plugin() {
440
440
  companion object {
441
441
  private const val DEFAULT_LIMIT = 100
442
442
  private val DEFAULT_PAST_DURATION: Duration = Duration.ofDays(1)
443
- private const val HEALTH_CONNECT_SETTINGS_ACTION = "androidx.health.ACTION_HEALTH_CONNECT_SETTINGS"
444
443
  }
445
444
  }
@@ -881,17 +881,17 @@ final class Health {
881
881
  return
882
882
  }
883
883
 
884
- let results = categorySamples.map { sample -> [String: Any] in
884
+ let results = categorySamples.compactMap { sample -> [String: Any]? in
885
885
  let sleepValue = sample.value
886
886
  let durationMinutes = sample.endDate.timeIntervalSince(sample.startDate) / 60.0
887
-
888
- var payload: [String: Any] = [
889
- "dataType": dataType.rawValue,
890
- "value": durationMinutes,
891
- "unit": dataType.unitIdentifier,
892
- "startDate": self.isoFormatter.string(from: sample.startDate),
893
- "endDate": self.isoFormatter.string(from: sample.endDate)
894
- ]
887
+ guard var payload = self.readSamplePayload(
888
+ dataType: dataType,
889
+ value: durationMinutes,
890
+ startDate: sample.startDate,
891
+ endDate: sample.endDate
892
+ ) else {
893
+ return nil
894
+ }
895
895
 
896
896
  // Map HKCategoryValueSleepAnalysis to sleep state
897
897
  let sleepState = self.sleepStateFromValue(sleepValue)
@@ -925,16 +925,16 @@ final class Health {
925
925
  return
926
926
  }
927
927
 
928
- let results = categorySamples.map { sample -> [String: Any] in
928
+ let results = categorySamples.compactMap { sample -> [String: Any]? in
929
929
  let durationMinutes = sample.endDate.timeIntervalSince(sample.startDate) / 60.0
930
-
931
- var payload: [String: Any] = [
932
- "dataType": dataType.rawValue,
933
- "value": durationMinutes,
934
- "unit": dataType.unitIdentifier,
935
- "startDate": self.isoFormatter.string(from: sample.startDate),
936
- "endDate": self.isoFormatter.string(from: sample.endDate)
937
- ]
930
+ guard var payload = self.readSamplePayload(
931
+ dataType: dataType,
932
+ value: durationMinutes,
933
+ startDate: sample.startDate,
934
+ endDate: sample.endDate
935
+ ) else {
936
+ return nil
937
+ }
938
938
 
939
939
  self.addSampleMetadata(sample, to: &payload)
940
940
 
@@ -972,16 +972,19 @@ final class Health {
972
972
 
973
973
  let systolicValue = systolicSample.quantity.doubleValue(for: HKUnit.millimeterOfMercury())
974
974
  let diastolicValue = diastolicSample.quantity.doubleValue(for: HKUnit.millimeterOfMercury())
975
-
976
- var payload: [String: Any] = [
977
- "dataType": dataType.rawValue,
978
- "value": systolicValue,
979
- "unit": dataType.unitIdentifier,
980
- "startDate": self.isoFormatter.string(from: correlation.startDate),
981
- "endDate": self.isoFormatter.string(from: correlation.endDate),
982
- "systolic": systolicValue,
983
- "diastolic": diastolicValue
984
- ]
975
+ guard systolicValue.isFinite,
976
+ diastolicValue.isFinite,
977
+ var payload = self.readSamplePayload(
978
+ dataType: dataType,
979
+ value: systolicValue,
980
+ startDate: correlation.startDate,
981
+ endDate: correlation.endDate
982
+ ) else {
983
+ return nil
984
+ }
985
+
986
+ payload["systolic"] = systolicValue
987
+ payload["diastolic"] = diastolicValue
985
988
 
986
989
  self.addSampleMetadata(correlation, to: &payload)
987
990
 
@@ -1008,15 +1011,16 @@ final class Health {
1008
1011
  return
1009
1012
  }
1010
1013
 
1011
- let results = quantitySamples.map { sample -> [String: Any] in
1014
+ let results = quantitySamples.compactMap { sample -> [String: Any]? in
1012
1015
  let value = sample.quantity.doubleValue(for: dataType.defaultUnit)
1013
- var payload: [String: Any] = [
1014
- "dataType": dataType.rawValue,
1015
- "value": value,
1016
- "unit": dataType.unitIdentifier,
1017
- "startDate": self.isoFormatter.string(from: sample.startDate),
1018
- "endDate": self.isoFormatter.string(from: sample.endDate)
1019
- ]
1016
+ guard var payload = self.readSamplePayload(
1017
+ dataType: dataType,
1018
+ value: value,
1019
+ startDate: sample.startDate,
1020
+ endDate: sample.endDate
1021
+ ) else {
1022
+ return nil
1023
+ }
1020
1024
 
1021
1025
  self.addSampleMetadata(sample, to: &payload)
1022
1026
 
@@ -1028,6 +1032,20 @@ final class Health {
1028
1032
 
1029
1033
  healthStore.execute(query)
1030
1034
  }
1035
+
1036
+ func readSamplePayload(dataType: HealthDataType, value: Double, startDate: Date, endDate: Date) -> [String: Any]? {
1037
+ guard value.isFinite else {
1038
+ return nil
1039
+ }
1040
+
1041
+ return [
1042
+ "dataType": dataType.rawValue,
1043
+ "value": value,
1044
+ "unit": dataType.unitIdentifier,
1045
+ "startDate": isoFormatter.string(from: startDate),
1046
+ "endDate": isoFormatter.string(from: endDate)
1047
+ ]
1048
+ }
1031
1049
 
1032
1050
  private func addSampleMetadata(_ sample: HKSample, to payload: inout [String: Any]) {
1033
1051
  let source = sample.sourceRevision.source
@@ -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.5.0"
6
+ private let pluginVersion: String = "8.5.2"
7
7
  public let identifier = "HealthPlugin"
8
8
  public let jsName = "Health"
9
9
  public let pluginMethods: [CAPPluginMethod] = [
@@ -2,14 +2,72 @@ import XCTest
2
2
  @testable import HealthPlugin
3
3
 
4
4
  class HealthTests: XCTestCase {
5
- func testEcho() {
6
- // This is an example of a functional test case for a plugin.
7
- // Use XCTAssert and related functions to verify your tests produce the correct results.
5
+ func testReadSamplePayloadIncludesFiniteValue() throws {
6
+ let implementation = Health()
7
+ let startDate = Date(timeIntervalSince1970: 0)
8
+ let endDate = Date(timeIntervalSince1970: 60)
9
+ let formatter = ISO8601DateFormatter()
10
+ formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
11
+
12
+ let payload = implementation.readSamplePayload(
13
+ dataType: .oxygenSaturation,
14
+ value: 0.96,
15
+ startDate: startDate,
16
+ endDate: endDate
17
+ )
18
+
19
+ XCTAssertEqual(payload?["dataType"] as? String, "oxygenSaturation")
20
+ XCTAssertEqual(payload?["value"] as? Double, 0.96)
21
+ XCTAssertEqual(payload?["unit"] as? String, "percent")
8
22
 
23
+ let startDateString = try XCTUnwrap(payload?["startDate"] as? String)
24
+ let endDateString = try XCTUnwrap(payload?["endDate"] as? String)
25
+ let parsedStartDate = try XCTUnwrap(formatter.date(from: startDateString))
26
+ let parsedEndDate = try XCTUnwrap(formatter.date(from: endDateString))
27
+
28
+ XCTAssertEqual(parsedStartDate.timeIntervalSince1970, startDate.timeIntervalSince1970, accuracy: 0.001)
29
+ XCTAssertEqual(parsedEndDate.timeIntervalSince1970, endDate.timeIntervalSince1970, accuracy: 0.001)
30
+ }
31
+
32
+ func testReadSamplePayloadRejectsNaNValue() {
9
33
  let implementation = Health()
10
- let value = "Hello, World!"
11
- let result = implementation.echo(value)
34
+ let startDate = Date(timeIntervalSince1970: 0)
35
+
36
+ let payload = implementation.readSamplePayload(
37
+ dataType: .oxygenSaturation,
38
+ value: .nan,
39
+ startDate: startDate,
40
+ endDate: startDate
41
+ )
42
+
43
+ XCTAssertNil(payload)
44
+ }
45
+
46
+ func testReadSamplePayloadRejectsInfiniteValue() {
47
+ let implementation = Health()
48
+ let startDate = Date(timeIntervalSince1970: 0)
49
+
50
+ let payload = implementation.readSamplePayload(
51
+ dataType: .bloodGlucose,
52
+ value: .infinity,
53
+ startDate: startDate,
54
+ endDate: startDate
55
+ )
56
+
57
+ XCTAssertNil(payload)
58
+ }
59
+
60
+ func testReadSamplePayloadRejectsNegativeInfiniteValue() {
61
+ let implementation = Health()
62
+ let startDate = Date(timeIntervalSince1970: 0)
63
+
64
+ let payload = implementation.readSamplePayload(
65
+ dataType: .bloodGlucose,
66
+ value: -.infinity,
67
+ startDate: startDate,
68
+ endDate: startDate
69
+ )
12
70
 
13
- XCTAssertEqual(value, result)
71
+ XCTAssertNil(payload)
14
72
  }
15
73
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-health",
3
- "version": "8.5.0",
3
+ "version": "8.5.2",
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",