Skip to content

Commit 57445d6

Browse files
authored
Using the crown sequencer directly for carb/bolus input (#203)
Fixes #173
1 parent 0032c31 commit 57445d6

File tree

4 files changed

+86
-61
lines changed

4 files changed

+86
-61
lines changed

WatchApp Extension/Controllers/AddCarbsInterfaceController.swift

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,21 @@ import WatchConnectivity
1212

1313
final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClass {
1414

15-
private var carbValue: Int = 15
15+
fileprivate var carbValue: Int = 15 {
16+
didSet {
17+
guard carbValue >= 0 else {
18+
carbValue = 0
19+
return
20+
}
21+
22+
guard carbValue <= 100 else {
23+
carbValue = 100
24+
return
25+
}
26+
27+
valueLabel.setText(String(carbValue))
28+
}
29+
}
1630

1731
private var absorptionTime = AbsorptionTimeType.medium {
1832
didSet {
@@ -33,8 +47,6 @@ final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClas
3347

3448
@IBOutlet var valueLabel: WKInterfaceLabel!
3549

36-
@IBOutlet var valuePicker: WKInterfacePicker!
37-
3850
@IBOutlet var absorptionButtonA: WKInterfaceButton!
3951

4052
@IBOutlet var absorptionButtonB: WKInterfaceButton!
@@ -45,12 +57,7 @@ final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClas
4557
super.awake(withContext: context)
4658

4759
// Configure interface objects here.
48-
49-
let items = (0...100).map { _ in WKPickerItem() }
50-
51-
valuePicker.setItems(items)
52-
53-
valuePicker.setSelectedItemIndex(carbValue)
60+
crownSequencer.delegate = self
5461

5562
absorptionTime = .medium
5663
}
@@ -59,7 +66,7 @@ final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClas
5966
// This method is called when watch view controller is about to be visible to user
6067
super.willActivate()
6168

62-
valuePicker.focus()
69+
crownSequencer.focus()
6370
}
6471

6572
override func didDeactivate() {
@@ -69,17 +76,12 @@ final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClas
6976

7077
// MARK: - Actions
7178

72-
@IBAction func pickerValueUpdated(_ value: Int) {
73-
carbValue = value
74-
valueLabel.setText(String(value))
75-
}
76-
7779
@IBAction func decrement() {
78-
valuePicker.setSelectedItemIndex(carbValue - 5)
80+
carbValue -= 5
7981
}
8082

8183
@IBAction func increment() {
82-
valuePicker.setSelectedItemIndex(carbValue + 5)
84+
carbValue += 5
8385
}
8486

8587
@IBAction func setAbsorptionTimeFast() {
@@ -120,4 +122,19 @@ final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClas
120122
dismiss()
121123
}
122124

125+
// MARK: - Crown Sequencer
126+
127+
fileprivate var accumulatedRotation: Double = 0
128+
}
129+
130+
fileprivate let rotationsPerCarb: Double = 1/24
131+
132+
extension AddCarbsInterfaceController: WKCrownDelegate {
133+
func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
134+
accumulatedRotation += rotationalDelta
135+
136+
let remainder = accumulatedRotation.truncatingRemainder(dividingBy: rotationsPerCarb)
137+
carbValue += Int((accumulatedRotation - remainder).divided(by: rotationsPerCarb))
138+
accumulatedRotation = remainder
139+
}
123140
}

WatchApp Extension/Controllers/BolusInterfaceController.swift

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,20 @@ import WatchConnectivity
1313

1414
final class BolusInterfaceController: WKInterfaceController, IdentifiableClass {
1515

16-
private var bolusValue: Double = 0 {
16+
fileprivate var pickerValue: Int = 0 {
1717
didSet {
18+
guard pickerValue >= 0 else {
19+
pickerValue = 0
20+
return
21+
}
22+
23+
guard pickerValue <= maxPickerValue else {
24+
pickerValue = maxPickerValue
25+
return
26+
}
27+
28+
let bolusValue = bolusValueFromPickerValue(pickerValue)
29+
1830
switch bolusValue {
1931
case let x where x < 1:
2032
formatter.minimumFractionDigits = 3
@@ -58,55 +70,51 @@ final class BolusInterfaceController: WKInterfaceController, IdentifiableClass {
5870
return formatter
5971
}()
6072

73+
private var maxPickerValue = 0
74+
6175
/// 1.25
6276
@IBOutlet var valueLabel: WKInterfaceLabel!
6377

64-
@IBOutlet var valuePicker: WKInterfacePicker!
65-
6678
/// REC: 2.25 U
6779
@IBOutlet var recommendedValueLabel: WKInterfaceLabel!
6880

6981
override func awake(withContext context: Any?) {
7082
super.awake(withContext: context)
7183

72-
let maxPickerValue: Int
7384
var maxBolusValue: Double = 15
74-
let pickerValue: Int
85+
var pickerValue = 0
86+
87+
let info: BolusSuggestionUserInfo? = BolusSuggestionUserInfo(recommendedBolus: 3.5, maxBolus: 10)
7588

76-
if let context = context as? BolusSuggestionUserInfo {
77-
let recommendedBolus = context.recommendedBolus
89+
if let context = info {
90+
let recommendedBolus = 3.5
7891

7992
if let maxBolus = context.maxBolus {
8093
maxBolusValue = maxBolus
8194
} else if recommendedBolus > 0 {
8295
maxBolusValue = recommendedBolus
8396
}
8497

85-
maxPickerValue = pickerValueFromBolusValue(maxBolusValue)
8698
let recommendedPickerValue = pickerValueFromBolusValue(recommendedBolus)
8799
maxBolusValue = bolusValueFromPickerValue(maxPickerValue)
88100
pickerValue = Int(Double(recommendedPickerValue) * 0.75)
89-
bolusValue = bolusValueFromPickerValue(pickerValue)
90101

91102
if let valueString = formatter.string(from: NSNumber(value: recommendedBolus)) {
92103
recommendedValueLabel.setText(String(format: NSLocalizedString("Rec: %@ U", comment: "The label and value showing the recommended bolus"), valueString).localizedUppercase)
93104
}
94-
} else {
95-
maxPickerValue = pickerValueFromBolusValue(maxBolusValue)
96-
pickerValue = pickerValueFromBolusValue(bolusValue)
97-
bolusValue = 0
98105
}
99106

100-
let items = (0...maxPickerValue).map { _ in WKPickerItem() }
101-
valuePicker.setItems(items)
102-
valuePicker.setSelectedItemIndex(pickerValue)
107+
self.maxPickerValue = pickerValueFromBolusValue(maxBolusValue)
108+
self.pickerValue = pickerValue
109+
110+
crownSequencer.delegate = self
103111
}
104112

105113
override func willActivate() {
106114
// This method is called when watch view controller is about to be visible to user
107115
super.willActivate()
108116

109-
valuePicker.focus()
117+
crownSequencer.focus()
110118
}
111119

112120
override func didDeactivate() {
@@ -116,19 +124,17 @@ final class BolusInterfaceController: WKInterfaceController, IdentifiableClass {
116124

117125
// MARK: - Actions
118126

119-
@IBAction func pickerValueUpdated(_ value: Int) {
120-
bolusValue = bolusValueFromPickerValue(value)
121-
}
122-
123127
@IBAction func decrement() {
124-
valuePicker.setSelectedItemIndex(pickerValueFromBolusValue(bolusValue) - 10)
128+
pickerValue -= 10
125129
}
126130

127131
@IBAction func increment() {
128-
valuePicker.setSelectedItemIndex(pickerValueFromBolusValue(bolusValue) + 10)
132+
pickerValue += 10
129133
}
130134

131135
@IBAction func deliver() {
136+
let bolusValue = bolusValueFromPickerValue(pickerValue)
137+
132138
if bolusValue > 0 {
133139
let bolus = SetBolusUserInfo(value: bolusValue, startDate: Date())
134140

@@ -150,4 +156,19 @@ final class BolusInterfaceController: WKInterfaceController, IdentifiableClass {
150156
dismiss()
151157
}
152158

159+
// MARK: - Crown Sequencer
160+
161+
fileprivate var accumulatedRotation: Double = 0
162+
}
163+
164+
fileprivate let rotationsPerValue: Double = 1/24
165+
166+
extension BolusInterfaceController: WKCrownDelegate {
167+
func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
168+
accumulatedRotation += rotationalDelta
169+
170+
let remainder = accumulatedRotation.truncatingRemainder(dividingBy: rotationsPerValue)
171+
pickerValue += Int((accumulatedRotation - remainder).divided(by: rotationsPerValue))
172+
accumulatedRotation = remainder
173+
}
153174
}

WatchApp Extension/ExtensionDelegate.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,12 @@ final class ExtensionDelegate: NSObject, WKExtensionDelegate {
127127
for complication in server.activeComplications ?? [] {
128128
// In watchOS 2, we forced a timeline reload every 8 hours because attempting to extend it indefinitely seemed to lead to the complication "freezing".
129129
if UserDefaults.standard.complicationDataLastRefreshed.timeIntervalSinceNow < TimeInterval(hours: -8) {
130+
UserDefaults.standard.complicationDataLastRefreshed = Date()
130131
os_log("Reloading complication timeline")
131132
server.reloadTimeline(for: complication)
132133
} else {
133134
os_log("Extending complication timeline")
134-
// TODO: Switch this back to extendTimeline if things are working correctly.
135-
// Time Travel appears to be disabled by default in watchOS 3 anyway
136-
server.reloadTimeline(for: complication)
135+
server.extendTimeline(for: complication)
137136
}
138137
}
139138
}

WatchApp/Base.lproj/Interface.storyboard

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="rNf-Mh-tID">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="rNf-Mh-tID">
33
<dependencies>
44
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
55
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="11077"/>
@@ -12,16 +12,11 @@
1212
<items>
1313
<group width="1" height="1" alignment="left" layout="vertical" spacing="1" id="uPt-Z4-ngs">
1414
<items>
15-
<picker height="2" alignment="left" style="sequence" id="brP-46-ycV">
16-
<connections>
17-
<action selector="pickerValueUpdated:" destination="zh0-gB-D44" id="cSR-oa-odP"/>
18-
</connections>
19-
</picker>
2015
<group width="1" alignment="left" spacing="0.0" id="WLN-cX-0wl">
2116
<items>
2217
<group width="22" height="22" alignment="left" verticalAlignment="center" radius="11" id="J90-Xm-Znp">
2318
<items>
24-
<button width="22" height="22" alignment="left" verticalAlignment="center" title="" id="Dh9-HV-fXy">
19+
<button width="22" height="22" alignment="left" verticalAlignment="center" accessibilityLabel="Subtract" title="" id="Dh9-HV-fXy">
2520
<color key="titleColor" red="1" green="0.58431372550000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
2621
<color key="backgroundColor" red="1" green="0.58431372549019611" blue="0.0" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
2722
<fontDescription key="font" type="system" weight="semibold" pointSize="20"/>
@@ -37,7 +32,7 @@
3732
</label>
3833
<group width="22" height="22" alignment="right" verticalAlignment="center" radius="11" id="6ip-X6-F2J">
3934
<items>
40-
<button width="22" height="22" alignment="right" verticalAlignment="center" title="+" id="eu3-pj-GH3">
35+
<button width="22" height="22" alignment="right" verticalAlignment="center" accessibilityLabel="Add" title="+" id="eu3-pj-GH3">
4136
<color key="titleColor" red="1" green="0.58431372550000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
4237
<color key="backgroundColor" red="1" green="0.58431372550000005" blue="0.0" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
4338
<fontDescription key="font" type="system" weight="semibold" pointSize="20"/>
@@ -94,7 +89,6 @@
9489
<outlet property="absorptionButtonB" destination="0fo-Z3-hTi" id="bPH-HR-eTF"/>
9590
<outlet property="absorptionButtonC" destination="dPF-QZ-sh6" id="KfE-KO-HcS"/>
9691
<outlet property="valueLabel" destination="E5r-2c-UZm" id="oll-hK-YCN"/>
97-
<outlet property="valuePicker" destination="brP-46-ycV" id="9rB-uA-Dg4"/>
9892
</connections>
9993
</controller>
10094
</objects>
@@ -172,16 +166,11 @@
172166
<items>
173167
<group width="1" height="1" alignment="left" layout="vertical" spacing="1" id="PJO-Ol-ya8">
174168
<items>
175-
<picker height="2" alignment="left" style="sequence" id="d95-7v-5ZX">
176-
<connections>
177-
<action selector="pickerValueUpdated:" destination="zTm-yH-n4A" id="pa6-22-dFb"/>
178-
</connections>
179-
</picker>
180169
<group width="1" alignment="left" spacing="0.0" id="xP1-tZ-vSS">
181170
<items>
182171
<group width="22" height="22" alignment="left" verticalAlignment="center" radius="11" id="d24-et-2S4">
183172
<items>
184-
<button width="22" height="22" alignment="left" verticalAlignment="center" title="" id="hjF-xr-cwO">
173+
<button width="22" height="22" alignment="left" verticalAlignment="center" accessibilityLabel="Subtract" title="" id="hjF-xr-cwO">
185174
<color key="titleColor" red="1" green="0.58431372550000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
186175
<color key="backgroundColor" red="1" green="0.58431372550000005" blue="0.0" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
187176
<fontDescription key="font" type="system" weight="semibold" pointSize="20"/>
@@ -197,7 +186,7 @@
197186
</label>
198187
<group width="22" height="22" alignment="right" verticalAlignment="center" radius="11" id="JXe-b7-7Ef">
199188
<items>
200-
<button width="22" height="22" alignment="right" verticalAlignment="center" title="+" id="DZc-Gn-RLu">
189+
<button width="22" height="22" alignment="right" verticalAlignment="center" accessibilityLabel="Add" title="+" id="DZc-Gn-RLu">
201190
<color key="titleColor" red="1" green="0.58431372550000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
202191
<color key="backgroundColor" red="1" green="0.58431372550000005" blue="0.0" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
203192
<fontDescription key="font" type="system" weight="semibold" pointSize="20"/>
@@ -230,7 +219,6 @@
230219
<connections>
231220
<outlet property="recommendedValueLabel" destination="lDp-Dk-msn" id="B0r-C8-lMN"/>
232221
<outlet property="valueLabel" destination="mpK-zY-UvA" id="pM7-ih-eRu"/>
233-
<outlet property="valuePicker" destination="d95-7v-5ZX" id="AIU-bs-k8X"/>
234222
</connections>
235223
</controller>
236224
</objects>

0 commit comments

Comments
 (0)