Skip to content

Commit bde1576

Browse files
authored
Merge branch 'dev-watchM' into dev-watch
2 parents 27e9a06 + a3c23d2 commit bde1576

39 files changed

+1207
-166
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// GlucoseBackfillRequestUserInfo.swift
3+
// Loop
4+
//
5+
// Created by Bharat Mediratta on 6/21/18.
6+
// Copyright © 2018 LoopKit Authors. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
struct GlucoseBackfillRequestUserInfo {
12+
let version = 1
13+
let startDate: Date
14+
}
15+
16+
extension GlucoseBackfillRequestUserInfo: RawRepresentable {
17+
typealias RawValue = [String: Any]
18+
19+
static let name = "GlucoseBackfillRequestUserInfo"
20+
21+
init?(rawValue: RawValue) {
22+
guard
23+
rawValue["v"] as? Int == version,
24+
rawValue["name"] as? String == GlucoseBackfillRequestUserInfo.name,
25+
let startDate = rawValue["sd"] as? Date
26+
else {
27+
return nil
28+
}
29+
30+
self.startDate = startDate
31+
}
32+
33+
var rawValue: RawValue {
34+
return [
35+
"v": version,
36+
"name": GlucoseBackfillRequestUserInfo.name,
37+
"sd": startDate
38+
]
39+
}
40+
}

Common/Models/WatchContext.swift

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
import Foundation
1010
import HealthKit
1111

12+
1213
final class WatchContext: NSObject, RawRepresentable {
1314
typealias RawValue = [String: Any]
1415

15-
private let version = 3
16+
private let version = 4
1617

1718
var preferredGlucoseUnit: HKUnit?
1819
var maxBolus: Double?
@@ -22,6 +23,8 @@ final class WatchContext: NSObject, RawRepresentable {
2223
var eventualGlucose: HKQuantity?
2324
var glucoseDate: Date?
2425

26+
var targetRanges: [WatchDatedRange]?
27+
var temporaryOverride: WatchDatedRange?
2528
var glucoseRangeScheduleOverride: GlucoseRangeScheduleOverrideUserInfo?
2629
var configuredOverrideContexts: [GlucoseRangeScheduleOverrideUserInfo.Context] = []
2730

@@ -41,6 +44,7 @@ final class WatchContext: NSObject, RawRepresentable {
4144
var reservoir: Double?
4245
var reservoirPercentage: Double?
4346
var batteryPercentage: Double?
47+
var predictedGlucose: WatchPredictedGlucose?
4448

4549
var cgm: CGM?
4650

@@ -56,16 +60,15 @@ final class WatchContext: NSObject, RawRepresentable {
5660
}
5761

5862
if let unitString = rawValue["gu"] as? String {
59-
let unit = HKUnit(from: unitString)
60-
preferredGlucoseUnit = unit
63+
preferredGlucoseUnit = HKUnit(from: unitString)
6164
}
62-
65+
let unit = preferredGlucoseUnit ?? .milligramsPerDeciliter
6366
if let glucoseValue = rawValue["gv"] as? Double {
64-
glucose = HKQuantity(unit: preferredGlucoseUnit ?? .milligramsPerDeciliter, doubleValue: glucoseValue)
67+
glucose = HKQuantity(unit: unit, doubleValue: glucoseValue)
6568
}
6669

6770
if let glucoseValue = rawValue["egv"] as? Double {
68-
eventualGlucose = HKQuantity(unit: preferredGlucoseUnit ?? .milligramsPerDeciliter, doubleValue: glucoseValue)
71+
eventualGlucose = HKQuantity(unit: unit, doubleValue: glucoseValue)
6972
}
7073

7174
glucoseTrendRawValue = rawValue["gt"] as? Int
@@ -93,6 +96,18 @@ final class WatchContext: NSObject, RawRepresentable {
9396
COB = rawValue["cob"] as? Double
9497
maxBolus = rawValue["mb"] as? Double
9598

99+
if let rawValue = rawValue["pg"] as? WatchPredictedGlucose.RawValue {
100+
predictedGlucose = WatchPredictedGlucose(rawValue: rawValue)
101+
}
102+
103+
if let rawValue = rawValue["tr"] as? [WatchDatedRange.RawValue] {
104+
targetRanges = rawValue.compactMap({return WatchDatedRange(rawValue: $0)})
105+
}
106+
107+
if let rawValue = rawValue["to"] as? WatchDatedRange.RawValue {
108+
temporaryOverride = WatchDatedRange(rawValue: rawValue)
109+
}
110+
96111
if let cgmRawValue = rawValue["cgm"] as? CGM.RawValue {
97112
cgm = CGM(rawValue: cgmRawValue)
98113
}
@@ -127,6 +142,11 @@ final class WatchContext: NSObject, RawRepresentable {
127142
raw["rbo"] = recommendedBolusDose
128143
raw["rp"] = reservoirPercentage
129144

145+
raw["pg"] = predictedGlucose?.rawValue
146+
147+
raw["tr"] = targetRanges?.map { $0.rawValue }
148+
raw["to"] = temporaryOverride?.rawValue
149+
130150
return raw
131151
}
132152
}

Common/Models/WatchDatedRange.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// WatchDatedRange.swift
3+
// WatchApp Extension
4+
//
5+
// Created by Bharat Mediratta on 6/26/18.
6+
// Copyright © 2018 LoopKit Authors. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
12+
struct WatchDatedRange {
13+
public let startDate: Date
14+
public let endDate: Date
15+
public let minValue: Double
16+
public let maxValue: Double
17+
18+
public init(startDate: Date, endDate: Date, minValue: Double, maxValue: Double) {
19+
self.startDate = startDate
20+
self.endDate = endDate
21+
self.minValue = minValue
22+
self.maxValue = maxValue
23+
}
24+
}
25+
26+
27+
extension WatchDatedRange: RawRepresentable {
28+
typealias RawValue = [String: Any]
29+
30+
var rawValue: RawValue {
31+
return [
32+
"sd": startDate,
33+
"ed": endDate,
34+
"mi": minValue,
35+
"ma": maxValue
36+
]
37+
}
38+
39+
init?(rawValue: RawValue) {
40+
guard
41+
let startDate = rawValue["sd"] as? Date,
42+
let endDate = rawValue["ed"] as? Date,
43+
let minValue = rawValue["mi"] as? Double,
44+
let maxValue = rawValue["ma"] as? Double
45+
else {
46+
return nil
47+
}
48+
49+
self.startDate = startDate
50+
self.endDate = endDate
51+
self.minValue = minValue
52+
self.maxValue = maxValue
53+
}
54+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// WatchHistoricalGlucose.swift
3+
// Loop
4+
//
5+
// Created by Bharat Mediratta on 6/22/18.
6+
// Copyright © 2018 LoopKit Authors. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import HealthKit
11+
import LoopKit
12+
13+
14+
struct WatchHistoricalGlucose {
15+
let samples: [NewGlucoseSample]
16+
17+
init(with samples: [StoredGlucoseSample]) {
18+
self.samples = samples.map {
19+
NewGlucoseSample(date: $0.startDate, quantity: $0.quantity, isDisplayOnly: false, syncIdentifier: $0.syncIdentifier)
20+
}
21+
}
22+
}
23+
24+
25+
extension WatchHistoricalGlucose: RawRepresentable {
26+
typealias RawValue = [String: Any]
27+
28+
var rawValue: RawValue {
29+
return [
30+
"d": samples.map { $0.date },
31+
"v": samples.map { Int16($0.quantity.doubleValue(for: .milligramsPerDeciliter)) },
32+
"id": samples.map { $0.syncIdentifier }
33+
]
34+
}
35+
36+
init?(rawValue: RawValue) {
37+
guard
38+
let dates = rawValue["d"] as? [Date],
39+
let values = rawValue["v"] as? [Int16],
40+
let syncIdentifiers = rawValue["id"] as? [String],
41+
dates.count == values.count,
42+
dates.count == syncIdentifiers.count
43+
else {
44+
return nil
45+
}
46+
47+
self.samples = (0..<dates.count).map {
48+
NewGlucoseSample(date: dates[$0], quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(values[$0])), isDisplayOnly: false, syncIdentifier: syncIdentifiers[$0])
49+
}
50+
}
51+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// WatchPredictedGlucose.swift
3+
// WatchApp Extension
4+
//
5+
// Created by Bharat Mediratta on 6/26/18.
6+
// Copyright © 2018 LoopKit Authors. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import LoopKit
11+
import HealthKit
12+
13+
14+
struct WatchPredictedGlucose {
15+
let values: [GlucoseValue]
16+
17+
init?(values: [GlucoseValue]) {
18+
guard values.count > 1 else {
19+
return nil
20+
}
21+
self.values = values
22+
}
23+
}
24+
25+
26+
extension WatchPredictedGlucose: RawRepresentable {
27+
typealias RawValue = [String: Any]
28+
29+
var rawValue: RawValue {
30+
31+
return [
32+
"v": values.map { Int16($0.quantity.doubleValue(for: .milligramsPerDeciliter)) },
33+
"d": values[0].startDate,
34+
"i": values[1].startDate.timeIntervalSince(values[0].startDate)
35+
]
36+
}
37+
38+
init?(rawValue: RawValue) {
39+
guard
40+
let values = rawValue["v"] as? [Int16],
41+
let firstDate = rawValue["d"] as? Date,
42+
let interval = rawValue["i"] as? TimeInterval
43+
else {
44+
return nil
45+
}
46+
47+
self.values = values.enumerated().map { tuple in
48+
PredictedGlucoseValue(startDate: firstDate + Double(tuple.0) * interval,
49+
quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(tuple.1)))
50+
}
51+
}
52+
}

Loop Status Extension/Base.lproj/MainInterface.storyboard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="64E-I5-5c4">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="64E-I5-5c4">
33
<device id="retina5_5" orientation="portrait">
44
<adaptation id="fullscreen"/>
55
</device>
66
<dependencies>
77
<deployment identifier="iOS"/>
8-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
99
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
1010
</dependencies>
1111
<scenes>

0 commit comments

Comments
 (0)