diff --git a/Loop Status Extension/HKUnit.swift b/Loop Status Extension/HKUnit.swift
index 726614c457..ffa2e62951 100644
--- a/Loop Status Extension/HKUnit.swift
+++ b/Loop Status Extension/HKUnit.swift
@@ -8,10 +8,11 @@
import HealthKit
+// Code in this extension is duplicated from:
+// https://github.com/LoopKit/LoopKit/blob/master/LoopKit/HKUnit.swift
+// to avoid pulling in the LoopKit extension since it's not extension-API safe.
public extension HKUnit {
// A formatting helper for determining the preferred decimal style for a given unit
- // This is similar to the LoopKit HKUnit extension, but copied here so that we can
- // avoid a dependency on LoopKit from the Loop Status Extension.
var preferredMinimumFractionDigits: Int {
if self.unitString == "mg/dL" {
return 0
@@ -19,4 +20,18 @@ public extension HKUnit {
return 1
}
}
+
+ static func millimolesPerLiterUnit() -> HKUnit {
+ return HKUnit.moleUnit(with: .milli, molarMass: HKUnitMolarMassBloodGlucose).unitDivided(by: HKUnit.liter())
+ }
+
+ // A glucose-centric presentation helper for the localized unit string
+ var glucoseUnitDisplayString: String {
+ if self == HKUnit.millimolesPerLiterUnit() {
+ return NSLocalizedString("mmol/L", comment: "The unit display string for millimoles of glucose per liter")
+ } else {
+ return String(describing: self)
+ }
+ }
+
}
diff --git a/Loop Status Extension/Info.plist b/Loop Status Extension/Info.plist
index 457555e233..ab9e66d865 100644
--- a/Loop Status Extension/Info.plist
+++ b/Loop Status Extension/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
XPC!
CFBundleShortVersionString
- 1.1.2
+ 1.2.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
MainAppBundleIdentifier
diff --git a/Loop Status Extension/StatusExtensionContext.swift b/Loop Status Extension/StatusExtensionContext.swift
index bbe312e46a..d733fae7f8 100644
--- a/Loop Status Extension/StatusExtensionContext.swift
+++ b/Loop Status Extension/StatusExtensionContext.swift
@@ -40,11 +40,11 @@ struct GlucoseContext {
let sensor: SensorDisplayable?
}
-final class StatusExtensionContext: NSObject, RawRepresentable {
+final class StatusExtensionContext: RawRepresentable {
typealias RawValue = [String: Any]
private let version = 1
- var preferredUnitDisplayString: String?
+ var preferredUnitString: String?
var latestGlucose: GlucoseContext?
var reservoir: ReservoirContext?
var loop: LoopContext?
@@ -52,15 +52,12 @@ final class StatusExtensionContext: NSObject, RawRepresentable {
var batteryPercentage: Double?
var eventualGlucose: Double?
- override init() {
- super.init()
- }
+ init() { }
required init?(rawValue: RawValue) {
- super.init()
let raw = rawValue
- if let preferredString = raw["preferredUnitDisplayString"] as? String,
+ if let preferredString = raw["preferredUnitString"] as? String,
let latestValue = raw["latestGlucose_value"] as? Double,
let startDate = raw["latestGlucose_startDate"] as? Date {
@@ -81,7 +78,7 @@ final class StatusExtensionContext: NSObject, RawRepresentable {
isLocal: local)
}
- preferredUnitDisplayString = preferredString
+ preferredUnitString = preferredString
latestGlucose = GlucoseContext(
quantity: latestValue,
startDate: startDate,
@@ -115,10 +112,10 @@ final class StatusExtensionContext: NSObject, RawRepresentable {
"version": version
]
- raw["preferredUnitDisplayString"] = preferredUnitDisplayString
+ raw["preferredUnitString"] = preferredUnitString
- if let glucose = latestGlucose,
- preferredUnitDisplayString != nil {
+ if preferredUnitString != nil,
+ let glucose = latestGlucose {
raw["latestGlucose_value"] = glucose.quantity
raw["latestGlucose_startDate"] = glucose.startDate
}
@@ -161,3 +158,10 @@ final class StatusExtensionContext: NSObject, RawRepresentable {
return raw
}
}
+
+
+extension StatusExtensionContext: CustomDebugStringConvertible {
+ var debugDescription: String {
+ return String(reflecting: rawValue)
+ }
+}
diff --git a/Loop Status Extension/StatusViewController.swift b/Loop Status Extension/StatusViewController.swift
index f8a7505b62..0de511aa87 100644
--- a/Loop Status Extension/StatusViewController.swift
+++ b/Loop Status Extension/StatusViewController.swift
@@ -43,7 +43,7 @@ class StatusViewController: UIViewController, NCWidgetProviding {
// the wrong units and that could be very harmful. So unless there's a preferred
// unit, assume that none of the rest of the data is reliable.
guard
- let preferredUnitDisplayString = context.preferredUnitDisplayString
+ let preferredUnitString = context.preferredUnitString
else {
completionHandler(NCUpdateResult.failed)
return
@@ -52,7 +52,7 @@ class StatusViewController: UIViewController, NCWidgetProviding {
if let glucose = context.latestGlucose {
glucoseHUD.set(glucoseQuantity: glucose.quantity,
at: glucose.startDate,
- unitDisplayString: preferredUnitDisplayString,
+ unitString: preferredUnitString,
from: glucose.sensor)
}
@@ -74,14 +74,16 @@ class StatusViewController: UIViewController, NCWidgetProviding {
loopCompletionHUD.lastLoopCompleted = loop.lastCompleted
}
- if let eventualGlucose = context.eventualGlucose {
- let quantity = HKQuantity(unit: HKUnit(from: preferredUnitDisplayString),
- doubleValue: eventualGlucose.rounded())
+ let preferredUnit = HKUnit(from: preferredUnitString)
+ let formatter = NumberFormatter.glucoseFormatter(for: preferredUnit)
+ if let eventualGlucose = context.eventualGlucose,
+ let eventualGlucoseNumberString = formatter.string(from: NSNumber(value: eventualGlucose)) {
subtitleLabel.text = String(
format: NSLocalizedString(
- "Eventually %@",
- comment: "The subtitle format describing eventual glucose. (1: localized glucose value description)"),
- String(describing: quantity))
+ "Eventually %1$@ %2$@",
+ comment: "The subtitle format describing eventual glucose. (1: localized glucose value description) (2: localized glucose units description)"),
+ eventualGlucoseNumberString,
+ preferredUnit.glucoseUnitDisplayString)
subtitleLabel.alpha = 1
} else {
subtitleLabel.alpha = 0
diff --git a/Loop.xcconfig b/Loop.xcconfig
index 3b48714f3c..d092e89a38 100644
--- a/Loop.xcconfig
+++ b/Loop.xcconfig
@@ -8,4 +8,4 @@
// Change this on first setup to your own unique organization identifier in
// reverse-domain name syntax.
-MAIN_APP_BUNDLE_IDENTIFIER = com.loudnate
+MAIN_APP_BUNDLE_IDENTIFIER = com.loopkit
diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj
index 11ac9d2c75..e8525bd86f 100644
--- a/Loop.xcodeproj/project.pbxproj
+++ b/Loop.xcodeproj/project.pbxproj
@@ -1387,8 +1387,7 @@
4F70C1E31DE8DCA7006380B7 /* Base */,
);
name = MainInterface.storyboard;
- path = "Loop Status Extension";
- sourceTree = "";
+ sourceTree = "";
};
C1C73EF91DE3D0230022FC89 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift
index 1db7f0c5d6..495ef0333e 100644
--- a/Loop/Managers/DeviceDataManager.swift
+++ b/Loop/Managers/DeviceDataManager.swift
@@ -975,11 +975,11 @@ final class DeviceDataManager: CarbStoreDelegate, CarbStoreSyncDelegate, DoseSto
// MARK: - WatchKit
- private(set) var watchManager: WatchDataManager!
+ fileprivate var watchManager: WatchDataManager!
// MARK: - Status Extension
- private(set) var statusExtensionManager: StatusExtensionDataManager!
+ fileprivate var statusExtensionManager: StatusExtensionDataManager!
// MARK: - Initialization
@@ -1075,7 +1075,11 @@ extension DeviceDataManager: CustomDebugStringConvertible {
"workoutModeEnabled: \(workoutModeEnabled)",
"maximumBasalRatePerHour: \(maximumBasalRatePerHour)",
"maximumBolus: \(maximumBolus)",
- String(reflecting: rileyLinkManager)
+ String(reflecting: rileyLinkManager),
+ String(reflecting: statusExtensionManager!),
+ "",
+ "## NSUserDefaults",
+ String(reflecting: UserDefaults.standard.dictionaryRepresentation())
].joined(separator: "\n")
}
}
diff --git a/Loop/Managers/StatusExtensionDataManager.swift b/Loop/Managers/StatusExtensionDataManager.swift
index e0aef3324e..3bd89be2d5 100644
--- a/Loop/Managers/StatusExtensionDataManager.swift
+++ b/Loop/Managers/StatusExtensionDataManager.swift
@@ -20,13 +20,17 @@ final class StatusExtensionDataManager {
NotificationCenter.default.addObserver(self, selector: #selector(update(_:)), name: .LoopDataUpdated, object: deviceDataManager.loopManager)
}
+ fileprivate var defaults: UserDefaults? {
+ return UserDefaults(suiteName: Bundle.main.appGroupSuiteName)
+ }
+
@objc private func update(_ notification: Notification) {
self.dataManager.glucoseStore?.preferredUnit() { (unit, error) in
if error == nil, let unit = unit {
self.createContext(unit) { (context) in
if let context = context {
- UserDefaults(suiteName: Bundle.main.appGroupSuiteName)?.statusExtensionContext = context
+ self.defaults?.statusExtensionContext = context
}
}
}
@@ -57,10 +61,11 @@ final class StatusExtensionDataManager {
context.batteryPercentage = 0.25
context.reservoir = ReservoirContext(startDate: Date(), unitVolume: 42.5, capacity: 200)
context.netBasal = NetBasalContext(rate: 2.1, percentage: 0.6, startDate: Date() - TimeInterval(250))
- context.eventualGlucose = 119.123
+ context.eventualGlucose = HKQuantity(unit: HKUnit.milligramsPerDeciliterUnit(), doubleValue: 119.123)
+ .doubleValue(for: preferredUnit)
#endif
- context.preferredUnitDisplayString = preferredUnit.glucoseUnitDisplayString
+ context.preferredUnitString = preferredUnit.unitString
context.loop = LoopContext(
dosingEnabled: dataManager.loopManager.dosingEnabled,
lastCompleted: lastLoopCompleted)
@@ -98,3 +103,13 @@ final class StatusExtensionDataManager {
}
}
}
+
+
+extension StatusExtensionDataManager: CustomDebugStringConvertible {
+ var debugDescription: String {
+ return [
+ "## StatusExtensionDataManager",
+ "statusExtensionContext: \(String(reflecting: defaults?.statusExtensionContext))"
+ ].joined(separator: "\n")
+ }
+}
diff --git a/Loop/View Controllers/StatusTableViewController.swift b/Loop/View Controllers/StatusTableViewController.swift
index 7bdca3bc6b..ec995ffb83 100644
--- a/Loop/View Controllers/StatusTableViewController.swift
+++ b/Loop/View Controllers/StatusTableViewController.swift
@@ -269,7 +269,7 @@ final class StatusTableViewController: UITableViewController, UIGestureRecognize
if let glucose = self.dataManager.glucoseStore?.latestGlucose {
self.glucoseHUD.set(glucoseQuantity: glucose.quantity.doubleValue(for: self.charts.glucoseUnit),
at: glucose.startDate,
- unitDisplayString: self.charts.glucoseUnit.glucoseUnitDisplayString,
+ unitString: self.charts.glucoseUnit.unitString,
from: self.dataManager.sensorInfo)
}
diff --git a/Loop/Views/GlucoseHUDView.swift b/Loop/Views/GlucoseHUDView.swift
index a5d1247959..43910dbe60 100644
--- a/Loop/Views/GlucoseHUDView.swift
+++ b/Loop/Views/GlucoseHUDView.swift
@@ -64,19 +64,20 @@ final class GlucoseHUDView: HUDView {
}
}
- func set(glucoseQuantity: Double, at glucoseStartDate: Date, unitDisplayString: String, from sensor: SensorDisplayable?) {
+ func set(glucoseQuantity: Double, at glucoseStartDate: Date, unitString: String, from sensor: SensorDisplayable?) {
var accessibilityStrings = [String]()
let time = timeFormatter.string(from: glucoseStartDate)
caption?.text = time
+ let unit = HKUnit(from: unitString)
- let numberFormatter = NumberFormatter.glucoseFormatter(for: HKUnit(from: unitDisplayString))
+ let numberFormatter = NumberFormatter.glucoseFormatter(for: unit)
if let valueString = numberFormatter.string(from: NSNumber(value: glucoseQuantity)) {
glucoseLabel.text = valueString
accessibilityStrings.append(String(format: NSLocalizedString("%1$@ at %2$@", comment: "Accessbility format value describing glucose: (1: glucose number)(2: glucose time)"), valueString, time))
}
- var unitStrings = [unitDisplayString]
+ var unitStrings = [unit.glucoseUnitDisplayString]
if let trend = sensor?.trendType {
unitStrings.append(trend.symbol)