@tryterra/react-native 0.0.0-stage → 2.2.1
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/LICENSE +21 -0
- package/README.md +142 -2
- package/TerraReactNative.podspec +48 -0
- package/android/build.gradle +87 -0
- package/android/src/bridgeCore/kotlin/README.md +1 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/BridgeBootstrap.kt +133 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/BridgeHost.kt +32 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/Conversions.kt +557 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/LauncherSlots.kt +41 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/ReadConversions.kt +250 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/Rejections.kt +150 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/StreamRegistry.kt +77 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridge.kt +86 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridgeOpsImpl.kt +300 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridgeStreamsImpl.kt +50 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TokenBroker.kt +198 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeErrors.kt +217 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeOps.kt +582 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeTypes.kt +1569 -0
- package/android/src/healthConnectOnly/kotlin/co/tryterra/sdk/reactnative/TerraStores.kt +11 -0
- package/android/src/main/AndroidManifest.xml +24 -0
- package/android/src/main/java/co/tryterra/sdk/reactnative/TerraBridgeModule.kt +96 -0
- package/android/src/main/java/co/tryterra/sdk/reactnative/TerraReactNativePackage.kt +26 -0
- package/android/src/main/java/co/tryterra/sdk/reactnative/TerraStartup.kt +46 -0
- package/android/src/samsung/kotlin/co/tryterra/sdk/reactnative/TerraStores.kt +13 -0
- package/docs/availability.md +396 -0
- package/frameworks/TerraSDK.xcframework/Info.plist +48 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Info.plist +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.abi.json +82672 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.package.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.swiftinterface +2163 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/PrivacyInfo.xcprivacy +96 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Info.plist +20 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/DWARF/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/TerraSDK.yml +6594 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Info.plist +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +82672 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.package.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +2163 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +82672 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.package.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +2163 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/PrivacyInfo.xcprivacy +96 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/_CodeSignature/CodeResources +223 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Info.plist +20 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/DWARF/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/TerraSDK.yml +6595 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/TerraSDK.yml +6513 -0
- package/ios/TerraBridgeCore/BridgeBootstrap.swift +89 -0
- package/ios/TerraBridgeCore/BridgeHost.swift +13 -0
- package/ios/TerraBridgeCore/Conversions+Reads.swift +259 -0
- package/ios/TerraBridgeCore/Conversions.swift +594 -0
- package/ios/TerraBridgeCore/Generated/BridgeErrors.swift +179 -0
- package/ios/TerraBridgeCore/Generated/BridgeOps.swift +967 -0
- package/ios/TerraBridgeCore/Generated/BridgeTypes.swift +2050 -0
- package/ios/TerraBridgeCore/Locked.swift +15 -0
- package/ios/TerraBridgeCore/README.md +1 -0
- package/ios/TerraBridgeCore/Rejections.swift +130 -0
- package/ios/TerraBridgeCore/RuntimeAttachment.swift +60 -0
- package/ios/TerraBridgeCore/StreamRegistry.swift +59 -0
- package/ios/TerraBridgeCore/TerraBridge.swift +122 -0
- package/ios/TerraBridgeCore/TerraBridgeOpsImpl.swift +318 -0
- package/ios/TerraBridgeCore/TerraBridgeStreamsImpl.swift +60 -0
- package/ios/TerraBridgeCore/TokenBroker.swift +147 -0
- package/ios/TerraBridgeModule.mm +79 -0
- package/ios/TerraBridgeModuleImpl.swift +49 -0
- package/ios/TerraReactNative.swift +19 -0
- package/lib/EndUser.d.ts +12 -0
- package/lib/EndUser.js +13 -0
- package/lib/NativeTerraBridge.d.ts +23 -0
- package/lib/NativeTerraBridge.js +13 -0
- package/lib/Terra.d.ts +223 -0
- package/lib/Terra.js +336 -0
- package/lib/TerraError.d.ts +42 -0
- package/lib/TerraError.js +95 -0
- package/lib/createTerra.d.ts +8 -0
- package/lib/createTerra.js +19 -0
- package/lib/generated/client.d.ts +128 -0
- package/lib/generated/client.js +256 -0
- package/lib/generated/codecs.d.ts +219 -0
- package/lib/generated/codecs.js +2066 -0
- package/lib/generated/errors.d.ts +13 -0
- package/lib/generated/errors.js +68 -0
- package/lib/generated/ops.d.ts +13 -0
- package/lib/generated/ops.js +161 -0
- package/lib/generated/streams.d.ts +23 -0
- package/lib/generated/streams.js +58 -0
- package/lib/generated/types.d.ts +794 -0
- package/lib/generated/types.js +224 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.js +55 -0
- package/package.json +71 -4
- package/src/EndUser.ts +15 -0
- package/src/NativeTerraBridge.ts +27 -0
- package/src/Terra.ts +592 -0
- package/src/TerraError.ts +116 -0
- package/src/createTerra.ts +18 -0
- package/src/generated/client.ts +315 -0
- package/src/generated/codecs.ts +1989 -0
- package/src/generated/errors.ts +113 -0
- package/src/generated/ops.ts +233 -0
- package/src/generated/streams.ts +74 -0
- package/src/generated/types.ts +1222 -0
- package/src/index.ts +54 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import TerraSDK
|
|
3
|
+
|
|
4
|
+
public enum BridgeBootstrap {
|
|
5
|
+
/// The Info.plist key carrying the developer id.
|
|
6
|
+
public static let devIDKey = "TerraDevID"
|
|
7
|
+
|
|
8
|
+
public struct Configuration: Sendable, Equatable {
|
|
9
|
+
public let devID: String
|
|
10
|
+
|
|
11
|
+
public init(devID: String) {
|
|
12
|
+
self.devID = devID
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// The configuration in `bundle`'s Info.plist, or nil when it names no dev id.
|
|
16
|
+
public init?(bundle: Bundle) {
|
|
17
|
+
guard let devID = (bundle.object(forInfoDictionaryKey: BridgeBootstrap.devIDKey) as? String)?
|
|
18
|
+
.trimmingCharacters(in: .whitespacesAndNewlines), !devID.isEmpty
|
|
19
|
+
else { return nil }
|
|
20
|
+
self.init(devID: devID)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private static let parked = Locked<TerraBridge?>(nil)
|
|
25
|
+
|
|
26
|
+
/// The bridge bootstrap parked, or nil when it has not run.
|
|
27
|
+
public static var current: TerraBridge? { parked.withLock { $0 } }
|
|
28
|
+
|
|
29
|
+
@discardableResult
|
|
30
|
+
public static func bootstrap(bundle: Bundle = .main) -> TerraBridge? {
|
|
31
|
+
guard let configuration = Configuration(bundle: bundle) else { return nil }
|
|
32
|
+
return bootstrap(configuration)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@discardableResult
|
|
36
|
+
public static func bootstrap(_ configuration: Configuration) -> TerraBridge {
|
|
37
|
+
bootstrap(configuration, register: registerBackgroundSync) { provider in
|
|
38
|
+
Terra(devID: configuration.devID, tokenProvider: provider)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static func bootstrap(
|
|
43
|
+
_ configuration: Configuration,
|
|
44
|
+
register: (Terra) -> Bool,
|
|
45
|
+
client: (_ tokenProvider: @escaping TerraBridge.TokenProvider) -> Terra
|
|
46
|
+
) -> TerraBridge {
|
|
47
|
+
parked.withLock { parked in
|
|
48
|
+
if let existing = parked { return existing }
|
|
49
|
+
let host = LaunchHost(devID: configuration.devID)
|
|
50
|
+
let bridge = TerraBridge(host: host, client: client)
|
|
51
|
+
host.registered.withLock { $0 = register(bridge.terra) }
|
|
52
|
+
parked = bridge
|
|
53
|
+
return bridge
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public static func attach(
|
|
58
|
+
missingLine: String,
|
|
59
|
+
emit: @escaping @Sendable (_ subscriptionId: String, _ message: String) -> Void
|
|
60
|
+
) throws(BridgeRejection) -> BridgeSession {
|
|
61
|
+
guard let bridge = current else {
|
|
62
|
+
throw BridgeRejection(payload: Rejections.payload(for: BridgeError.notBootstrapped(line: missingLine)))
|
|
63
|
+
}
|
|
64
|
+
return bridge.attach(emit: emit)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static func reset() {
|
|
68
|
+
parked.withLock { $0 = nil }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private static func registerBackgroundSync(_ terra: Terra) -> Bool {
|
|
72
|
+
#if os(iOS)
|
|
73
|
+
return BackgroundSync.register(terra: terra)
|
|
74
|
+
#else
|
|
75
|
+
return false
|
|
76
|
+
#endif
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
final class LaunchHost: BridgeHost {
|
|
81
|
+
let devID: String?
|
|
82
|
+
let registered = Locked(false)
|
|
83
|
+
|
|
84
|
+
init(devID: String) {
|
|
85
|
+
self.devID = devID
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func backgroundRegistered() async -> Bool { registered.withLock { $0 } }
|
|
89
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// The parts of an op that are not the SDK: the bootstrap's own record of what it set up.
|
|
4
|
+
///
|
|
5
|
+
/// A seam so that everything in front of it runs on a macOS host with no simulator. The production
|
|
6
|
+
/// conformance belongs to bootstrap (P5), which is the code that registered the task.
|
|
7
|
+
public protocol BridgeHost: Sendable {
|
|
8
|
+
/// The dev id the native bootstrap was configured with.
|
|
9
|
+
var devID: String? { get }
|
|
10
|
+
|
|
11
|
+
/// Whether bootstrap registered background sync at launch. False is a host setup bug.
|
|
12
|
+
func backgroundRegistered() async -> Bool
|
|
13
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import TerraSDK
|
|
3
|
+
|
|
4
|
+
extension Conversions {
|
|
5
|
+
|
|
6
|
+
static func dayTotalMetric(_ metric: TerraSDK.DayTotal.Metric) -> DayTotalMetric? {
|
|
7
|
+
switch metric {
|
|
8
|
+
case .distanceWalkingRunning: return .distanceWalkingRunning
|
|
9
|
+
case .distanceCycling: return .distanceCycling
|
|
10
|
+
case .distanceSwimming: return .distanceSwimming
|
|
11
|
+
case .distanceWheelchair: return .distanceWheelchair
|
|
12
|
+
case .activeEnergyBurned: return .activeEnergyBurned
|
|
13
|
+
case .basalEnergyBurned: return .basalEnergyBurned
|
|
14
|
+
case .flightsClimbed: return .flightsClimbed
|
|
15
|
+
case .appleExerciseTime: return .appleExerciseTime
|
|
16
|
+
case .steps, .swimmingStrokeCount, .appleMoveTime, .appleStandTime, .appleStandHours: return nil
|
|
17
|
+
@unknown default: return nil
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static func dayTotal(_ total: TerraSDK.DayTotal) -> DayTotal? {
|
|
22
|
+
dayTotalMetric(total.metric).map {
|
|
23
|
+
DayTotal(
|
|
24
|
+
metric: $0,
|
|
25
|
+
start: BridgeInstant.format(total.interval.start),
|
|
26
|
+
end: BridgeInstant.format(total.interval.end),
|
|
27
|
+
value: total.value,
|
|
28
|
+
unit: total.unit,
|
|
29
|
+
timeZone: total.timeZone?.identifier)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static func intradayMetric(_ kind: TerraSDK.IntradaySample.Kind) -> IntradayMetric? {
|
|
34
|
+
switch kind {
|
|
35
|
+
case .activeEnergy: return .activeEnergy
|
|
36
|
+
case .basalEnergy: return .basalEnergy
|
|
37
|
+
case .distance: return .distance
|
|
38
|
+
case .floorsClimbed: return .floorsClimbed
|
|
39
|
+
@unknown default: return nil
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static func intraday(_ sample: TerraSDK.IntradaySample) -> IntradaySample? {
|
|
44
|
+
intradayMetric(sample.kind).map {
|
|
45
|
+
IntradaySample(
|
|
46
|
+
id: sample.id.uuidString,
|
|
47
|
+
metric: $0,
|
|
48
|
+
start: BridgeInstant.format(sample.interval.start),
|
|
49
|
+
end: BridgeInstant.format(sample.interval.end),
|
|
50
|
+
value: sample.value,
|
|
51
|
+
source: sampleSource(sample.source),
|
|
52
|
+
userEntered: sample.userEntered,
|
|
53
|
+
timeZone: sample.timeZone?.identifier)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static func restingHeartRate(_ sample: TerraSDK.RestingHeartRateSample) -> RestingHeartRateSample {
|
|
58
|
+
RestingHeartRateSample(
|
|
59
|
+
id: sample.id.uuidString,
|
|
60
|
+
start: BridgeInstant.format(sample.interval.start),
|
|
61
|
+
end: BridgeInstant.format(sample.interval.end),
|
|
62
|
+
beatsPerMinute: sample.beatsPerMinute,
|
|
63
|
+
source: sampleSource(sample.source),
|
|
64
|
+
userEntered: sample.userEntered,
|
|
65
|
+
timeZone: sample.timeZone?.identifier)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static func bodyMetric(_ metric: TerraSDK.BodyMetric) -> BodyMetric? {
|
|
69
|
+
switch metric {
|
|
70
|
+
case .weight: return .weight
|
|
71
|
+
case .height: return .height
|
|
72
|
+
case .bodyFatPercentage: return .bodyFatPercentage
|
|
73
|
+
case .leanBodyMass: return .leanBodyMass
|
|
74
|
+
case .bmi: return .bmi
|
|
75
|
+
case .waistCircumference: return nil
|
|
76
|
+
@unknown default: return nil
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static func glucoseUnit(_ unit: TerraSDK.BloodGlucoseUnit) -> BloodGlucoseUnit {
|
|
81
|
+
switch unit {
|
|
82
|
+
case .milligramsPerDecilitre: return .milligramsPerDecilitre
|
|
83
|
+
case .millimolesPerLitre: return .millimolesPerLitre
|
|
84
|
+
@unknown default: return .milligramsPerDecilitre
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static func mealTime(_ time: TerraSDK.GlucoseMealTime) -> GlucoseMealTime {
|
|
89
|
+
switch time {
|
|
90
|
+
case .preprandial: return .preprandial
|
|
91
|
+
case .postprandial: return .postprandial
|
|
92
|
+
case .unknown: return .unknown
|
|
93
|
+
@unknown default: return .unknown
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static func specimen(_ specimen: TerraSDK.GlucoseSpecimen) -> GlucoseSpecimen {
|
|
98
|
+
switch specimen {
|
|
99
|
+
case .capillary: return .capillary
|
|
100
|
+
case .interstitial: return .interstitial
|
|
101
|
+
case .plasma: return .plasma
|
|
102
|
+
case .serum: return .serum
|
|
103
|
+
case .tears: return .tears
|
|
104
|
+
case .wholeBlood: return .wholeBlood
|
|
105
|
+
case .unknown: return .unknown
|
|
106
|
+
@unknown default: return .unknown
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static func temperatureMetric(_ metric: TerraSDK.BodyTemperatureMetric) -> BodyTemperatureMetric? {
|
|
111
|
+
switch metric {
|
|
112
|
+
case .body: return .body
|
|
113
|
+
case .basal: return .basal
|
|
114
|
+
case .wrist: return .wrist
|
|
115
|
+
case .skin: return .skin
|
|
116
|
+
@unknown default: return nil
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static func variabilityMetric(_ metric: TerraSDK.HeartRateVariabilityMetric) -> HeartRateVariabilityMetric? {
|
|
121
|
+
switch metric {
|
|
122
|
+
case .sdnn: return .sdnn
|
|
123
|
+
case .rmssd: return .rmssd
|
|
124
|
+
@unknown default: return nil
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static func testType(_ type: TerraSDK.VO2MaxTestType) -> VO2MaxTestType? {
|
|
129
|
+
switch type {
|
|
130
|
+
case .maxExercise: return .maxExercise
|
|
131
|
+
case .predictedSubMaxExercise: return .predictedSubMaxExercise
|
|
132
|
+
case .predictedNonExercise: return .predictedNonExercise
|
|
133
|
+
@unknown default: return nil
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static func bodyReadingKind(_ kind: TerraSDK.BodyReading.Kind) -> BodyReadingKind? {
|
|
138
|
+
switch kind {
|
|
139
|
+
case .measurement(let metric, let value):
|
|
140
|
+
return bodyMetric(metric).map { .measurement(metric: $0, value: value) }
|
|
141
|
+
case .bloodPressure(let systolic, let diastolic):
|
|
142
|
+
return .bloodPressure(systolic: systolic, diastolic: diastolic)
|
|
143
|
+
case .bloodGlucose(let value, let unit, let mealTime, let specimen):
|
|
144
|
+
return .bloodGlucose(
|
|
145
|
+
value: value, unit: glucoseUnit(unit), mealTime: mealTime.map(Self.mealTime),
|
|
146
|
+
specimen: specimen.map(Self.specimen))
|
|
147
|
+
case .oxygenSaturation(let fraction):
|
|
148
|
+
return .oxygenSaturation(fraction: fraction)
|
|
149
|
+
case .temperature(let metric, let celsius):
|
|
150
|
+
return temperatureMetric(metric).map { .temperature(metric: $0, celsius: celsius) }
|
|
151
|
+
case .heartRateVariability(let metric, let milliseconds):
|
|
152
|
+
return variabilityMetric(metric).map { .heartRateVariability(metric: $0, milliseconds: milliseconds) }
|
|
153
|
+
case .respiratoryRate(let breathsPerMinute):
|
|
154
|
+
return .respiratoryRate(breathsPerMinute: breathsPerMinute)
|
|
155
|
+
case .vo2Max(let value, let type):
|
|
156
|
+
return .vo2Max(millilitresPerKilogramMinute: value, testType: type.flatMap(testType))
|
|
157
|
+
case .insulinDelivery, .electrocardiogram, .heartbeatSeries:
|
|
158
|
+
return nil
|
|
159
|
+
@unknown default:
|
|
160
|
+
return nil
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static func bodyReading(_ reading: TerraSDK.BodyReading) -> BodyReading? {
|
|
165
|
+
bodyReadingKind(reading.kind).map {
|
|
166
|
+
BodyReading(
|
|
167
|
+
id: reading.id.uuidString,
|
|
168
|
+
kind: $0,
|
|
169
|
+
start: BridgeInstant.format(reading.interval.start),
|
|
170
|
+
end: BridgeInstant.format(reading.interval.end),
|
|
171
|
+
source: sampleSource(reading.source),
|
|
172
|
+
userEntered: reading.userEntered,
|
|
173
|
+
timeZone: reading.timeZone?.identifier)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static func route(_ route: TerraSDK.WorkoutRoute) -> WorkoutRoute {
|
|
178
|
+
WorkoutRoute(
|
|
179
|
+
id: route.id.uuidString,
|
|
180
|
+
workoutId: route.workoutId.uuidString,
|
|
181
|
+
start: BridgeInstant.format(route.interval.start),
|
|
182
|
+
end: BridgeInstant.format(route.interval.end),
|
|
183
|
+
points: route.points.map {
|
|
184
|
+
RoutePoint(time: BridgeInstant.format($0.time), latitude: $0.latitude, longitude: $0.longitude)
|
|
185
|
+
},
|
|
186
|
+
source: sampleSource(route.source),
|
|
187
|
+
timeZone: route.timeZone?.identifier)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static func intensityMetric(_ kind: TerraSDK.WorkoutIntensitySample.Kind) -> WorkoutIntensityMetric? {
|
|
191
|
+
switch kind {
|
|
192
|
+
case .speed: return .speed
|
|
193
|
+
case .power: return .power
|
|
194
|
+
case .cadence: return .cadence
|
|
195
|
+
@unknown default: return nil
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static func intensity(_ sample: TerraSDK.WorkoutIntensitySample) -> WorkoutIntensitySample? {
|
|
200
|
+
intensityMetric(sample.kind).map {
|
|
201
|
+
WorkoutIntensitySample(
|
|
202
|
+
id: sample.id.uuidString,
|
|
203
|
+
metric: $0,
|
|
204
|
+
workoutId: sample.workoutId.uuidString,
|
|
205
|
+
start: BridgeInstant.format(sample.interval.start),
|
|
206
|
+
end: BridgeInstant.format(sample.interval.end),
|
|
207
|
+
value: sample.value,
|
|
208
|
+
source: sampleSource(sample.source),
|
|
209
|
+
userEntered: sample.userEntered,
|
|
210
|
+
timeZone: sample.timeZone?.identifier)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
static func hydration(_ sample: TerraSDK.HydrationSample) -> HydrationSample {
|
|
215
|
+
HydrationSample(
|
|
216
|
+
id: sample.id.uuidString,
|
|
217
|
+
start: BridgeInstant.format(sample.interval.start),
|
|
218
|
+
end: BridgeInstant.format(sample.interval.end),
|
|
219
|
+
millilitres: sample.millilitres,
|
|
220
|
+
source: sampleSource(sample.source),
|
|
221
|
+
userEntered: sample.userEntered,
|
|
222
|
+
timeZone: sample.timeZone?.identifier)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static func availability(_ availability: TerraSDK.StoreAvailability) -> StoreAvailability {
|
|
226
|
+
switch availability {
|
|
227
|
+
case .available: return .available
|
|
228
|
+
case .unsupportedDevice: return .unsupportedDevice
|
|
229
|
+
@unknown default: return .unsupportedDevice
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static func eventKind(_ kind: TerraSDK.MenstrualEvent.Kind) -> MenstrualEventKind? {
|
|
234
|
+
switch kind {
|
|
235
|
+
case .intermenstrualBleeding: return .intermenstrualBleeding
|
|
236
|
+
case .ovulationTest: return .ovulationTest
|
|
237
|
+
case .cervicalMucus: return .cervicalMucus
|
|
238
|
+
case .sexualActivity, .pregnancyTest, .progesteroneTest, .pregnancy, .lactation, .contraceptive,
|
|
239
|
+
.persistentIntermenstrualBleeding, .infrequentCycles, .irregularCycles, .prolongedPeriods,
|
|
240
|
+
.bleedingDuringPregnancy, .bleedingAfterPregnancy:
|
|
241
|
+
return nil
|
|
242
|
+
@unknown default: return nil
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
static func menstrualEvent(_ event: TerraSDK.MenstrualEvent) -> MenstrualEvent? {
|
|
247
|
+
eventKind(event.kind).map {
|
|
248
|
+
MenstrualEvent(
|
|
249
|
+
id: event.id.uuidString,
|
|
250
|
+
kind: $0,
|
|
251
|
+
time: BridgeInstant.format(event.instant),
|
|
252
|
+
value: event.value,
|
|
253
|
+
storeIdentifier: event.storeIdentifier,
|
|
254
|
+
source: sampleSource(event.source),
|
|
255
|
+
userEntered: event.userEntered,
|
|
256
|
+
timeZone: event.timeZone?.identifier)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|