diff --git a/Common/LocalizedString.swift b/Common/LocalizedString.swift
index 72a61df82..e0376951c 100644
--- a/Common/LocalizedString.swift
+++ b/Common/LocalizedString.swift
@@ -12,6 +12,10 @@ private class FrameworkBundle {
static let main = Bundle(for: FrameworkBundle.self)
}
-func LocalizedString(_ key: String, tableName: String? = nil, value: String = "", comment: String) -> String {
- return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment)
+func LocalizedString(_ key: String, tableName: String? = nil, value: String? = nil, comment: String) -> String {
+ if let value = value {
+ return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment)
+ } else {
+ return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, comment: comment)
+ }
}
diff --git a/Common/TimeInterval.swift b/Common/TimeInterval.swift
index 5a8046a6c..03ea59869 100644
--- a/Common/TimeInterval.swift
+++ b/Common/TimeInterval.swift
@@ -10,6 +10,11 @@ import Foundation
extension TimeInterval {
+
+ static func days(_ days: Double) -> TimeInterval {
+ return self.init(days: days)
+ }
+
static func hours(_ hours: Double) -> TimeInterval {
return self.init(hours: hours)
}
@@ -30,13 +35,17 @@ extension TimeInterval {
return self.init(milliseconds / 1000)
}
- init(minutes: Double) {
- self.init(minutes * 60)
+ init(days: Double) {
+ self.init(hours: days * 24)
}
-
+
init(hours: Double) {
self.init(minutes: hours * 60)
}
+
+ init(minutes: Double) {
+ self.init(minutes * 60)
+ }
init(seconds: Double) {
self.init(seconds)
diff --git a/Crypto/Info.plist b/Crypto/Info.plist
index 21e7e6da6..5baf5d16b 100644
--- a/Crypto/Info.plist
+++ b/Crypto/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/MinimedKit/Info.plist b/MinimedKit/Info.plist
index 0de69c100..241ef8699 100644
--- a/MinimedKit/Info.plist
+++ b/MinimedKit/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
diff --git a/MinimedKit/Messages/PumpErrorMessageBody.swift b/MinimedKit/Messages/PumpErrorMessageBody.swift
index ea91b3ee6..ffff07b05 100644
--- a/MinimedKit/Messages/PumpErrorMessageBody.swift
+++ b/MinimedKit/Messages/PumpErrorMessageBody.swift
@@ -13,6 +13,7 @@ public enum PumpErrorCode: UInt8, CustomStringConvertible {
case commandRefused = 0x08
case maxSettingExceeded = 0x09
case bolusInProgress = 0x0c
+ case pageDoesNotExist = 0x0d
public var description: String {
switch self {
@@ -22,6 +23,8 @@ public enum PumpErrorCode: UInt8, CustomStringConvertible {
return LocalizedString("Max setting exceeded", comment: "Pump error code describing max setting exceeded")
case .bolusInProgress:
return LocalizedString("Bolus in progress", comment: "Pump error code when bolus is in progress")
+ case .pageDoesNotExist:
+ return LocalizedString("History page does not exist", comment: "Pump error code when invalid history page is requested")
}
}
diff --git a/MinimedKit/PumpManager/MinimedPumpManager.swift b/MinimedKit/PumpManager/MinimedPumpManager.swift
index 0d377625b..cb1750d1d 100644
--- a/MinimedKit/PumpManager/MinimedPumpManager.swift
+++ b/MinimedKit/PumpManager/MinimedPumpManager.swift
@@ -15,42 +15,51 @@ import os.log
public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
public static let managerIdentifier: String = "Minimed500"
- public init(state: MinimedPumpManagerState, rileyLinkManager: RileyLinkDeviceManager?) {
+ public init(state: MinimedPumpManagerState, rileyLinkDeviceProvider: RileyLinkDeviceProvider, rileyLinkConnectionManager: RileyLinkConnectionManager? = nil, pumpOps: PumpOps? = nil) {
self.state = state
- super.init(rileyLinkPumpManagerState: state.rileyLinkPumpManagerState, rileyLinkManager: rileyLinkManager)
+ super.init(rileyLinkDeviceProvider: rileyLinkDeviceProvider, rileyLinkConnectionManager: rileyLinkConnectionManager)
// Pump communication
let idleListeningEnabled = state.pumpModel.hasMySentry
- self.pumpOps = PumpOps(pumpSettings: state.pumpSettings, pumpState: state.pumpState, delegate: self)
+ self.pumpOps = pumpOps ?? PumpOps(pumpSettings: state.pumpSettings, pumpState: state.pumpState, delegate: self)
- self.rileyLinkManager.idleListeningState = idleListeningEnabled ? MinimedPumpManagerState.idleListeningEnabledDefaults : .disabled
+ self.rileyLinkDeviceProvider.idleListeningState = idleListeningEnabled ? MinimedPumpManagerState.idleListeningEnabledDefaults : .disabled
}
public required convenience init?(rawState: PumpManager.RawStateValue) {
- guard let state = MinimedPumpManagerState(rawValue: rawState) else {
+ guard let state = MinimedPumpManagerState(rawValue: rawState),
+ let connectionManagerState = state.rileyLinkConnectionManagerState else
+ {
return nil
}
-
- self.init(state: state, rileyLinkManager: nil)
+
+ let rileyLinkConnectionManager = RileyLinkConnectionManager(state: connectionManagerState)
+
+ self.init(state: state, rileyLinkDeviceProvider: rileyLinkConnectionManager.deviceProvider, rileyLinkConnectionManager: rileyLinkConnectionManager)
+
+ rileyLinkConnectionManager.delegate = self
}
public var rawState: PumpManager.RawStateValue {
return state.rawValue
}
- override public var rileyLinkPumpManagerState: RileyLinkPumpManagerState {
- didSet {
- state.rileyLinkPumpManagerState = rileyLinkPumpManagerState
- }
- }
-
// TODO: apply lock
public private(set) var state: MinimedPumpManagerState {
didSet {
pumpManagerDelegate?.pumpManagerDidUpdateState(self)
}
}
+
+ override public var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState? {
+ get {
+ return state.rileyLinkConnectionManagerState
+ }
+ set {
+ state.rileyLinkConnectionManagerState = newValue
+ }
+ }
public weak var cgmManagerDelegate: CGMManagerDelegate?
@@ -106,7 +115,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
/// characteristic which can cause the app to wake. For most users, the G5 Transmitter and
/// G4 Receiver are reliable as hearbeats, but users who find their resources extremely constrained
/// due to greedy apps or older devices may choose to always enable the timer by always setting `true`
- self.rileyLinkManager.timerTickEnabled = self.isPumpDataStale || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true)
+ self.rileyLinkDeviceProvider.timerTickEnabled = self.isPumpDataStale || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true)
}
}
@@ -204,14 +213,14 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
}
} catch let error {
self.log.error("Device %{public}@ auto-tune failed with error: %{public}@", device.name ?? "", String(describing: error))
- self.rileyLinkManager.deprioritize(device)
+ self.rileyLinkDeviceProvider.deprioritize(device, completion: nil)
if let error = error as? LocalizedError {
self.pumpManagerDelegate?.pumpManager(self, didError: PumpManagerError.communication(MinimedPumpManagerError.tuneFailed(error)))
}
}
}
} else {
- rileyLinkManager.deprioritize(device)
+ rileyLinkDeviceProvider.deprioritize(device, completion: nil)
}
}
@@ -343,7 +352,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
/// - completion: A closure called once upon completion
/// - error: An error describing why the fetch and/or store failed
private func fetchPumpHistory(_ completion: @escaping (_ error: Error?) -> Void) {
- rileyLinkManager.getDevices { (devices) in
+ rileyLinkDeviceProvider.getDevices { (devices) in
guard let device = devices.firstConnected else {
completion(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))
return
@@ -376,7 +385,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
/// TODO: Isolate to queue
private var isPumpDataStale: Bool {
// How long should we wait before we poll for new pump data?
- let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4)
+ let pumpStatusAgeTolerance = rileyLinkDeviceProvider.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4)
return isReservoirDataOlderThan(timeIntervalSinceNow: -pumpStatusAgeTolerance)
}
@@ -400,7 +409,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
*/
/// TODO: Isolate to queue
public func assertCurrentPumpData() {
- rileyLinkManager.assertIdleListening(forcingRestart: true)
+ rileyLinkDeviceProvider.assertIdleListening(forcingRestart: true)
guard isPumpDataStale else {
return
@@ -408,7 +417,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
self.log.debug("Pump data is stale, fetching.")
- rileyLinkManager.getDevices { (devices) in
+ rileyLinkDeviceProvider.getDevices { (devices) in
guard let device = devices.firstConnected else {
let error = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)
self.log.error("No devices found while fetching pump data")
@@ -492,7 +501,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
// If we don't have recent pump data, or the pump was recently rewound, read new pump data before bolusing.
let shouldReadReservoir = isReservoirDataOlderThan(timeIntervalSinceNow: .minutes(-6))
- pumpOps.runSession(withName: "Bolus", using: rileyLinkManager.firstConnectedDevice) { (session) in
+ pumpOps.runSession(withName: "Bolus", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
completion(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))
return
@@ -536,7 +545,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager {
}
public func enactTempBasal(unitsPerHour: Double, for duration: TimeInterval, completion: @escaping (PumpManagerResult) -> Void) {
- pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkManager.firstConnectedDevice) { (session) in
+ pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)))
return
@@ -646,7 +655,7 @@ extension MinimedPumpManager: CGMManager {
}
public func fetchNewDataIfNeeded(_ completion: @escaping (CGMResult) -> Void) {
- rileyLinkManager.getDevices { (devices) in
+ rileyLinkDeviceProvider.getDevices { (devices) in
guard let device = devices.firstConnected else {
completion(.error(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)))
return
@@ -685,3 +694,4 @@ extension MinimedPumpManager: CGMManager {
}
}
}
+
diff --git a/MinimedKit/PumpManager/MinimedPumpManagerState.swift b/MinimedKit/PumpManager/MinimedPumpManagerState.swift
index fb8b6d00d..3446cd8b3 100644
--- a/MinimedKit/PumpManager/MinimedPumpManagerState.swift
+++ b/MinimedKit/PumpManager/MinimedPumpManagerState.swift
@@ -13,7 +13,7 @@ import RileyLinkBLEKit
public struct MinimedPumpManagerState: RawRepresentable, Equatable {
public typealias RawValue = PumpManager.RawStateValue
- public static let version = 1
+ public static let version = 2
public var batteryChemistry: BatteryChemistryType
@@ -52,30 +52,30 @@ public struct MinimedPumpManagerState: RawRepresentable, Equatable {
}
}
- public var rileyLinkPumpManagerState: RileyLinkPumpManagerState
+ public var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState?
public var timeZone: TimeZone
- public init(batteryChemistry: BatteryChemistryType = .alkaline, preferredInsulinDataSource: InsulinDataSource = .pumpHistory, pumpColor: PumpColor, pumpID: String, pumpModel: PumpModel, pumpRegion: PumpRegion, rileyLinkPumpManagerState: RileyLinkPumpManagerState, timeZone: TimeZone) {
+ public init(batteryChemistry: BatteryChemistryType = .alkaline, preferredInsulinDataSource: InsulinDataSource = .pumpHistory, pumpColor: PumpColor, pumpID: String, pumpModel: PumpModel, pumpRegion: PumpRegion, rileyLinkConnectionManagerState: RileyLinkConnectionManagerState?, timeZone: TimeZone) {
self.batteryChemistry = batteryChemistry
self.preferredInsulinDataSource = preferredInsulinDataSource
self.pumpColor = pumpColor
self.pumpID = pumpID
self.pumpModel = pumpModel
self.pumpRegion = pumpRegion
- self.rileyLinkPumpManagerState = rileyLinkPumpManagerState
+ self.rileyLinkConnectionManagerState = rileyLinkConnectionManagerState
self.timeZone = timeZone
}
public init?(rawValue: RawValue) {
guard
+ let version = rawValue["version"] as? Int,
let batteryChemistryRaw = rawValue["batteryChemistry"] as? BatteryChemistryType.RawValue,
let insulinDataSourceRaw = rawValue["insulinDataSource"] as? InsulinDataSource.RawValue,
let pumpColorRaw = rawValue["pumpColor"] as? PumpColor.RawValue,
let pumpID = rawValue["pumpID"] as? String,
let pumpModelNumber = rawValue["pumpModel"] as? PumpModel.RawValue,
let pumpRegionRaw = rawValue["pumpRegion"] as? PumpRegion.RawValue,
- let rileyLinkPumpManagerStateRaw = rawValue["rileyLinkPumpManagerState"] as? RileyLinkPumpManagerState.RawValue,
let timeZoneSeconds = rawValue["timeZone"] as? Int,
let batteryChemistry = BatteryChemistryType(rawValue: batteryChemistryRaw),
@@ -83,12 +83,27 @@ public struct MinimedPumpManagerState: RawRepresentable, Equatable {
let pumpColor = PumpColor(rawValue: pumpColorRaw),
let pumpModel = PumpModel(rawValue: pumpModelNumber),
let pumpRegion = PumpRegion(rawValue: pumpRegionRaw),
- let rileyLinkPumpManagerState = RileyLinkPumpManagerState(rawValue: rileyLinkPumpManagerStateRaw),
let timeZone = TimeZone(secondsFromGMT: timeZoneSeconds)
else {
return nil
}
-
+
+ var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState? = nil
+
+ // Migrate
+ if version == 1
+ {
+ if let oldRileyLinkPumpManagerStateRaw = rawValue["rileyLinkPumpManagerState"] as? [String : Any],
+ let connectedPeripheralIDs = oldRileyLinkPumpManagerStateRaw["connectedPeripheralIDs"] as? [String]
+ {
+ rileyLinkConnectionManagerState = RileyLinkConnectionManagerState(autoConnectIDs: Set(connectedPeripheralIDs))
+ }
+ } else {
+ if let rawState = rawValue["rileyLinkConnectionManagerState"] as? RileyLinkConnectionManagerState.RawValue {
+ rileyLinkConnectionManagerState = RileyLinkConnectionManagerState(rawValue: rawState)
+ }
+ }
+
self.init(
batteryChemistry: batteryChemistry,
preferredInsulinDataSource: insulinDataSource,
@@ -96,24 +111,28 @@ public struct MinimedPumpManagerState: RawRepresentable, Equatable {
pumpID: pumpID,
pumpModel: pumpModel,
pumpRegion: pumpRegion,
- rileyLinkPumpManagerState: rileyLinkPumpManagerState,
+ rileyLinkConnectionManagerState: rileyLinkConnectionManagerState,
timeZone: timeZone
)
}
public var rawValue: RawValue {
- return [
+ var value: [String : Any] = [
"batteryChemistry": batteryChemistry.rawValue,
"insulinDataSource": preferredInsulinDataSource.rawValue,
"pumpColor": pumpColor.rawValue,
"pumpID": pumpID,
"pumpModel": pumpModel.rawValue,
"pumpRegion": pumpRegion.rawValue,
- "rileyLinkPumpManagerState": rileyLinkPumpManagerState.rawValue,
"timeZone": timeZone.secondsFromGMT(),
"version": MinimedPumpManagerState.version,
- ]
+ ]
+
+ if let rileyLinkConnectionManagerState = rileyLinkConnectionManagerState {
+ value["rileyLinkConnectionManagerState"] = rileyLinkConnectionManagerState.rawValue
+ }
+ return value
}
}
@@ -134,7 +153,7 @@ extension MinimedPumpManagerState: CustomDebugStringConvertible {
"pumpModel: \(pumpModel.rawValue)",
"pumpRegion: \(pumpRegion)",
"timeZone: \(timeZone)",
- String(reflecting: rileyLinkPumpManagerState),
+ String(reflecting: rileyLinkConnectionManagerState),
].joined(separator: "\n")
}
}
diff --git a/MinimedKitTests/Info.plist b/MinimedKitTests/Info.plist
index 5a6398fbf..9b0436e59 100644
--- a/MinimedKitTests/Info.plist
+++ b/MinimedKitTests/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
diff --git a/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard b/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard
index 7719d3ed5..7acfa46f5 100644
--- a/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard
+++ b/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard
@@ -185,6 +185,7 @@
+
@@ -573,6 +574,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -581,5 +598,6 @@
+
diff --git a/MinimedKitUI/CommandResponseViewController.swift b/MinimedKitUI/CommandResponseViewController.swift
index 5c2352f46..91c7c69a1 100644
--- a/MinimedKitUI/CommandResponseViewController.swift
+++ b/MinimedKitUI/CommandResponseViewController.swift
@@ -38,9 +38,9 @@ extension CommandResponseViewController {
}
}
- static func changeTime(ops: PumpOps?, rileyLinkManager: RileyLinkDeviceManager) -> T {
+ static func changeTime(ops: PumpOps?, rileyLinkDeviceProvider: RileyLinkDeviceProvider) -> T {
return T { (completionHandler) -> String in
- ops?.runSession(withName: "Set time", using: rileyLinkManager.firstConnectedDevice) { (session) in
+ ops?.runSession(withName: "Set time", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
let response: String
do {
guard let session = session else {
diff --git a/MinimedKitUI/Info.plist b/MinimedKitUI/Info.plist
index f936f8d95..f841d8f2c 100644
--- a/MinimedKitUI/Info.plist
+++ b/MinimedKitUI/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/MinimedKitUI/MinimedPumpManager+UI.swift b/MinimedKitUI/MinimedPumpManager+UI.swift
index da9ccb9f5..36485b663 100644
--- a/MinimedKitUI/MinimedPumpManager+UI.swift
+++ b/MinimedKitUI/MinimedPumpManager+UI.swift
@@ -29,7 +29,7 @@ extension MinimedPumpManager: PumpManagerUI {
// MARK: - DeliveryLimitSettingsTableViewControllerSyncSource
extension MinimedPumpManager {
public func syncDeliveryLimitSettings(for viewController: DeliveryLimitSettingsTableViewController, completion: @escaping (DeliveryLimitSettingsResult) -> Void) {
- pumpOps.runSession(withName: "Save Settings", using: rileyLinkManager.firstConnectedDevice) { (session) in
+ pumpOps.runSession(withName: "Save Settings", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)))
return
@@ -70,7 +70,7 @@ extension MinimedPumpManager {
// MARK: - SingleValueScheduleTableViewControllerSyncSource
extension MinimedPumpManager {
public func syncScheduleValues(for viewController: SingleValueScheduleTableViewController, completion: @escaping (RepeatingScheduleValueResult) -> Void) {
- pumpOps.runSession(withName: "Save Basal Profile", using: rileyLinkManager.firstConnectedDevice) { (session) in
+ pumpOps.runSession(withName: "Save Basal Profile", using: rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)))
return
diff --git a/MinimedKitUI/MinimedPumpSettingsViewController.swift b/MinimedKitUI/MinimedPumpSettingsViewController.swift
index f895ccd70..1cc8a6ff7 100644
--- a/MinimedKitUI/MinimedPumpSettingsViewController.swift
+++ b/MinimedKitUI/MinimedPumpSettingsViewController.swift
@@ -194,7 +194,7 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController {
case .settings:
switch SettingsRow(rawValue: indexPath.row)! {
case .timeZoneOffset:
- let vc = CommandResponseViewController.changeTime(ops: pumpManager.pumpOps, rileyLinkManager: pumpManager.rileyLinkManager)
+ let vc = CommandResponseViewController.changeTime(ops: pumpManager.pumpOps, rileyLinkDeviceProvider: pumpManager.rileyLinkDeviceProvider)
vc.title = sender?.textLabel?.text
show(vc, sender: indexPath)
diff --git a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift
index 1365708c2..2aaa39d50 100644
--- a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift
+++ b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift
@@ -50,6 +50,16 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController {
cellForRow(.version)?.detailTextLabel?.text = firmwareVersion
}
}
+
+ private var uptime: TimeInterval? {
+ didSet {
+ guard isViewLoaded else {
+ return
+ }
+
+ cellForRow(.uptime)?.setDetailAge(uptime)
+ }
+ }
private var lastIdle: Date? {
didSet {
@@ -99,6 +109,17 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController {
@objc func updateRSSI() {
device.readRSSI()
}
+
+ func updateUptime() {
+ device.runSession(withName: "Get stats for uptime") { (session) in
+ do {
+ let statistics = try session.getRileyLinkStatistics()
+ DispatchQueue.main.async {
+ self.uptime = statistics.uptime
+ }
+ } catch { }
+ }
+ }
private func updateDeviceStatus() {
device.getStatus { (status) in
@@ -165,6 +186,8 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController {
appeared = true
updateRSSI()
+
+ updateUptime()
}
public override func viewWillDisappear(_ animated: Bool) {
@@ -216,6 +239,7 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController {
case version
case rssi
case connection
+ case uptime
case idleStatus
}
@@ -289,8 +313,10 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController {
cell.detailTextLabel?.text = device.peripheralState.description
case .rssi:
cell.textLabel?.text = LocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)")
-
cell.setDetailRSSI(bleRSSI, formatter: integerFormatter)
+ case .uptime:
+ cell.textLabel?.text = NSLocalizedString("Uptime", comment: "The title of the cell showing uptime")
+ cell.setDetailAge(uptime)
case .idleStatus:
cell.textLabel?.text = LocalizedString("On Idle", comment: "The title of the cell showing the last idle")
cell.setDetailDate(lastIdle, formatter: dateFormatter)
@@ -482,6 +508,18 @@ extension RileyLinkMinimedDeviceTableViewController: TextFieldTableViewControlle
}
}
+private extension TimeInterval {
+ func format(using units: NSCalendar.Unit) -> String? {
+ let formatter = DateComponentsFormatter()
+ formatter.allowedUnits = units
+ formatter.unitsStyle = .full
+ formatter.zeroFormattingBehavior = .dropLeading
+ formatter.maximumUnitCount = 2
+
+ return formatter.string(from: self)
+ }
+}
+
private extension UITableViewCell {
func setDetailDate(_ date: Date?, formatter: DateFormatter) {
@@ -496,6 +534,14 @@ private extension UITableViewCell {
detailTextLabel?.text = formatter.decibleString(from: decibles) ?? "-"
}
+ func setDetailAge(_ age: TimeInterval?) {
+ if let age = age {
+ detailTextLabel?.text = age.format(using: [.day, .hour, .minute])
+ } else {
+ detailTextLabel?.text = ""
+ }
+ }
+
func setAwakeUntil(_ awakeUntil: Date?, formatter: DateFormatter) {
switch awakeUntil {
case let until? where until.timeIntervalSinceNow < 0:
diff --git a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift
index 142186749..f2b26129f 100644
--- a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift
+++ b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift
@@ -85,7 +85,7 @@ class MinimedPumpIDSetupViewController: SetupTableViewController {
pumpID: pumpID,
pumpModel: pumpModel,
pumpRegion: pumpRegion,
- rileyLinkPumpManagerState: self.rileyLinkPumpManager.rileyLinkPumpManagerState,
+ rileyLinkConnectionManagerState: rileyLinkPumpManager.rileyLinkConnectionManagerState,
timeZone: timeZone
)
}
@@ -96,7 +96,11 @@ class MinimedPumpIDSetupViewController: SetupTableViewController {
return nil
}
- return MinimedPumpManager(state: pumpManagerState, rileyLinkManager: rileyLinkPumpManager.rileyLinkManager)
+ return MinimedPumpManager(
+ state: pumpManagerState,
+ rileyLinkDeviceProvider: rileyLinkPumpManager.rileyLinkDeviceProvider,
+ rileyLinkConnectionManager: rileyLinkPumpManager.rileyLinkConnectionManager,
+ pumpOps: self.pumpOps)
}
// MARK: -
@@ -179,7 +183,6 @@ class MinimedPumpIDSetupViewController: SetupTableViewController {
footerView.primaryButton.setConnectTitle()
lastError = nil
case .completed:
- pumpOps = nil
pumpIDTextField.isEnabled = true
activityIndicator.state = .completed
footerView.primaryButton.isEnabled = true
@@ -233,7 +236,7 @@ class MinimedPumpIDSetupViewController: SetupTableViewController {
let pumpOps = PumpOps(pumpSettings: settings, pumpState: pumpState, delegate: self)
self.pumpOps = pumpOps
- pumpOps.runSession(withName: "Pump ID Setup", using: rileyLinkPumpManager.rileyLinkManager.firstConnectedDevice, { (session) in
+ pumpOps.runSession(withName: "Pump ID Setup", using: rileyLinkPumpManager.rileyLinkDeviceProvider.firstConnectedDevice, { (session) in
guard let session = session else {
DispatchQueue.main.async {
self.lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)
diff --git a/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift
index a95c1875c..92d79b601 100644
--- a/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift
+++ b/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift
@@ -25,6 +25,11 @@ public class MinimedPumpManagerSetupViewController: RileyLinkManagerSetupViewCon
view.backgroundColor = .white
navigationBar.shadowImage = UIImage()
+
+ if let pumpIDSetupVC = topViewController as? MinimedPumpIDSetupViewController, let rileyLinkPumpManager = rileyLinkPumpManager {
+ pumpIDSetupVC.rileyLinkPumpManager = rileyLinkPumpManager
+ }
+
}
private(set) var pumpManager: MinimedPumpManager?
diff --git a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift
index 52cdb68e6..b083c0134 100644
--- a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift
+++ b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift
@@ -84,7 +84,7 @@ class MinimedPumpSentrySetupViewController: SetupTableViewController {
continueState = .listening
- pumpManager.pumpOps.runSession(withName: "MySentry Pairing", using: pumpManager.rileyLinkManager.firstConnectedDevice) { (session) in
+ pumpManager.pumpOps.runSession(withName: "MySentry Pairing", using: pumpManager.rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
guard let session = session else {
DispatchQueue.main.async {
self.continueState = .notStarted
diff --git a/NightscoutUploadKit/Info.plist b/NightscoutUploadKit/Info.plist
index 0de69c100..241ef8699 100644
--- a/NightscoutUploadKit/Info.plist
+++ b/NightscoutUploadKit/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
diff --git a/NightscoutUploadKitTests/Info.plist b/NightscoutUploadKitTests/Info.plist
index f437a4c22..9c8492d9c 100644
--- a/NightscoutUploadKitTests/Info.plist
+++ b/NightscoutUploadKitTests/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj
index e87f1e28d..948a7b4cc 100644
--- a/RileyLink.xcodeproj/project.pbxproj
+++ b/RileyLink.xcodeproj/project.pbxproj
@@ -61,7 +61,6 @@
43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */; };
434AB0C71CBCB76400422F4A /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; };
434FF1DC1CF268BD000DB779 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; };
- 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */; };
4352A71220DEC68100CAC200 /* RileyLinkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; };
4352A71520DEC72500CAC200 /* PumpMessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC21E6873A10070EFBD /* PumpMessageSender.swift */; };
4352A71620DEC78B00CAC200 /* PumpSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C71FB937E500D916E6 /* PumpSettings.swift */; };
@@ -99,7 +98,6 @@
4352A75120DEDE9B00CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; };
435535D61FB6D98400CE5A23 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D51FB6D98400CE5A23 /* UserDefaults.swift */; };
435D26B020DA08CE00891C17 /* RileyLinkPumpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */; };
- 435D26B220DA091C00891C17 /* RileyLinkPumpManagerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */; };
435D26B420DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B320DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift */; };
435D26B620DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B520DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift */; };
435D26B920DC83F300891C17 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B720DC83E400891C17 /* Locked.swift */; };
@@ -211,7 +209,6 @@
43EBE4531EAD23CE0073A0B5 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; };
43EBE4541EAD23EC0073A0B5 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; };
43EBE4551EAD24410073A0B5 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; };
- 43EC9DCB1B786C6200DB0D18 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */; };
43F348061D596270009933DC /* HKUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F348051D596270009933DC /* HKUnit.swift */; };
43FF221C1CB9B9DE00024F30 /* NSDateComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43FF221B1CB9B9DE00024F30 /* NSDateComponents.swift */; };
492526711E4521FB00ACBA5F /* NoteNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 492526701E4521FB00ACBA5F /* NoteNightscoutTreatment.swift */; };
@@ -273,10 +270,6 @@
7D23674D21252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; };
7D23675021252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674E21252A5E0028B67D /* InfoPlist.strings */; };
7D23675321252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; };
- 7D23676121252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674821252A5E0028B67D /* InfoPlist.strings */; };
- 7D23676721252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674521252A5E0028B67D /* InfoPlist.strings */; };
- 7D23676921252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; };
- 7D23676B21252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; };
7D23679421252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679221252EBC0028B67D /* Localizable.strings */; };
7D23679721252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679521252EBC0028B67D /* Localizable.strings */; };
7D70766D1FE092D4004AC8EA /* LoopKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70766F1FE092D4004AC8EA /* LoopKit.strings */; };
@@ -300,26 +293,27 @@
C12198AD1C8F332500BC374C /* TimestampedPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12198AC1C8F332500BC374C /* TimestampedPumpEvent.swift */; };
C12198B31C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12198B21C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift */; };
C125728B211F7E6C0061BA2F /* UnknownPumpEvent57.swift in Sources */ = {isa = PBXBuildFile; fileRef = C125728A211F7E6C0061BA2F /* UnknownPumpEvent57.swift */; };
+ C125728C2121D4D60061BA2F /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */; };
+ C125728D2121D56D0061BA2F /* CaseCountable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C659181E16BA9D0025CC58 /* CaseCountable.swift */; };
+ C125728F2121DB7C0061BA2F /* PumpManagerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C125728E2121DB7C0061BA2F /* PumpManagerState.swift */; };
+ C12572922121EEEE0061BA2F /* SettingsImageTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12572912121EEEE0061BA2F /* SettingsImageTableViewCell.swift */; };
+ C125729421220FEC0061BA2F /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C125729321220FEC0061BA2F /* MainStoryboard.storyboard */; };
+ C12572982125FA390061BA2F /* RileyLinkConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12572972125FA390061BA2F /* RileyLinkConnectionManager.swift */; };
C12616441B685F0A001FAD87 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12616431B685F0A001FAD87 /* CoreData.framework */; };
C1271B071A9A34E900B7C949 /* Log.m in Sources */ = {isa = PBXBuildFile; fileRef = C1271B061A9A34E900B7C949 /* Log.m */; };
C1274F771D8232580002912B /* DailyTotal515PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F761D8232580002912B /* DailyTotal515PumpEvent.swift */; };
C1274F791D823A550002912B /* ChangeMeterIDPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F781D823A550002912B /* ChangeMeterIDPumpEvent.swift */; };
- C1274F7F1D82411C0002912B /* AuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F7B1D82411C0002912B /* AuthenticationViewController.swift */; };
- C1274F801D82411C0002912B /* RileyLinkListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F7C1D82411C0002912B /* RileyLinkListTableViewController.swift */; };
- C1274F811D82411C0002912B /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F7D1D82411C0002912B /* SettingsTableViewController.swift */; };
- C1274F841D82420F0002912B /* RadioSelectionTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F831D82420F0002912B /* RadioSelectionTableViewController.swift */; };
+ C1274F801D82411C0002912B /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F7C1D82411C0002912B /* MainViewController.swift */; };
C1274F861D8242BE0002912B /* PumpRegion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1274F851D8242BE0002912B /* PumpRegion.swift */; };
C12EA23B198B436800309FA4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23A198B436800309FA4 /* Foundation.framework */; };
C12EA23D198B436800309FA4 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23C198B436800309FA4 /* CoreGraphics.framework */; };
C12EA23F198B436800309FA4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23E198B436800309FA4 /* UIKit.framework */; };
C12EA245198B436800309FA4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C12EA243198B436800309FA4 /* InfoPlist.strings */; };
- C12EA24D198B436800309FA4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C12EA24C198B436800309FA4 /* Images.xcassets */; };
C12EA254198B436800309FA4 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA253198B436800309FA4 /* XCTest.framework */; };
C12EA255198B436800309FA4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23A198B436800309FA4 /* Foundation.framework */; };
C12EA256198B436900309FA4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23E198B436800309FA4 /* UIKit.framework */; };
C12EA25E198B436900309FA4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C12EA25C198B436900309FA4 /* InfoPlist.strings */; };
C12EA260198B436900309FA4 /* RileyLinkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C12EA25F198B436900309FA4 /* RileyLinkTests.m */; };
- C12EA26A198B442100309FA4 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C12EA269198B442100309FA4 /* Storyboard.storyboard */; };
C1330F431DBDA46400569064 /* ChangeSensorAlarmSilenceConfigPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1330F421DBDA46400569064 /* ChangeSensorAlarmSilenceConfigPumpEvent.swift */; };
C133CF931D5943780034B82D /* PredictedBG.swift in Sources */ = {isa = PBXBuildFile; fileRef = C133CF921D5943780034B82D /* PredictedBG.swift */; };
C13D155A1DAACE8400ADC044 /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13D15591DAACE8400ADC044 /* Either.swift */; };
@@ -331,13 +325,8 @@
C14FFC4A1D3AF1AC0049CF85 /* JournalEntryInsulinMarkerPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC491D3AF1AC0049CF85 /* JournalEntryInsulinMarkerPumpEvent.swift */; };
C14FFC501D3D6DEF0049CF85 /* ServiceAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC4E1D3D6DEF0049CF85 /* ServiceAuthentication.swift */; };
C14FFC511D3D6DEF0049CF85 /* ServiceCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC4F1D3D6DEF0049CF85 /* ServiceCredential.swift */; };
- C14FFC531D3D70170049CF85 /* ValidatingIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC521D3D70170049CF85 /* ValidatingIndicatorView.swift */; };
C14FFC551D3D72A50049CF85 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC541D3D72A50049CF85 /* UIViewController.swift */; };
- C14FFC581D3D72D30049CF85 /* AuthenticationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC561D3D72D30049CF85 /* AuthenticationTableViewCell.swift */; };
- C14FFC591D3D72D30049CF85 /* AuthenticationTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C14FFC571D3D72D30049CF85 /* AuthenticationTableViewCell.xib */; };
C14FFC5B1D3D74F90049CF85 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC5A1D3D74F90049CF85 /* NibLoadable.swift */; };
- C14FFC5E1D3D75200049CF85 /* ButtonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC5C1D3D75200049CF85 /* ButtonTableViewCell.swift */; };
- C14FFC5F1D3D75200049CF85 /* ButtonTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C14FFC5D1D3D75200049CF85 /* ButtonTableViewCell.xib */; };
C14FFC611D3D75470049CF85 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC601D3D75470049CF85 /* UIColor.swift */; };
C14FFC631D3D7CE20049CF85 /* NightscoutService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC621D3D7CE20049CF85 /* NightscoutService.swift */; };
C14FFC651D3D7E250049CF85 /* RemoteDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC641D3D7E250049CF85 /* RemoteDataManager.swift */; };
@@ -346,7 +335,6 @@
C15AF2AD1D74929D0031FC9D /* ChangeBolusWizardSetupPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15AF2AC1D74929D0031FC9D /* ChangeBolusWizardSetupPumpEvent.swift */; };
C15AF2AF1D7498930031FC9D /* RestoreMystery54PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15AF2AE1D7498930031FC9D /* RestoreMystery54PumpEvent.swift */; };
C15AF2B11D7498DD0031FC9D /* RestoreMystery55PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15AF2B01D7498DD0031FC9D /* RestoreMystery55PumpEvent.swift */; };
- C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */; };
C16A08311D389205001A200C /* JournalEntryMealMarkerPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16A08301D389205001A200C /* JournalEntryMealMarkerPumpEvent.swift */; };
C1711A561C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A551C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift */; };
C1711A5A1C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A591C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift */; };
@@ -476,6 +464,8 @@
C1FDFCA91D964A3E00ADBC31 /* BolusReminderPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1FDFCA81D964A3E00ADBC31 /* BolusReminderPumpEvent.swift */; };
C1FFAF4D212944F600C50C1D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1FFAF4B212944F600C50C1D /* Localizable.strings */; };
C1FFAF64212B126E00C50C1D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1FFAF62212B126E00C50C1D /* InfoPlist.strings */; };
+ C1FFAF6F212CB4F100C50C1D /* RileyLinkConnectionManagerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1FFAF6E212CB4F100C50C1D /* RileyLinkConnectionManagerState.swift */; };
+ C1FFAF72212FAAEF00C50C1D /* RileyLink.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C1FFAF71212FAAEF00C50C1D /* RileyLink.xcassets */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -705,7 +695,6 @@
434AB0921CBA0DF600422F4A /* PumpOps.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpOps.swift; sourceTree = ""; };
434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PumpOpsSession.swift; path = ../../RileyLinkKit/PumpOpsSession.swift; sourceTree = ""; };
434AB0941CBA0DF600422F4A /* PumpState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpState.swift; sourceTree = ""; };
- 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; };
4352A72520DEC9B700CAC200 /* MinimedKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MinimedKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4352A72720DEC9B700CAC200 /* MinimedKitUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinimedKitUI.h; sourceTree = ""; };
4352A72820DEC9B700CAC200 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
@@ -716,7 +705,6 @@
435535D51FB6D98400CE5A23 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = ""; };
435535DB1FB8B37E00CE5A23 /* PumpMessage+PumpOpsSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PumpMessage+PumpOpsSession.swift"; sourceTree = ""; };
435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkPumpManager.swift; sourceTree = ""; };
- 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkPumpManagerState.swift; sourceTree = ""; };
435D26B320DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDevicesHeaderView.swift; sourceTree = ""; };
435D26B520DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkDevicesTableViewDataSource.swift; sourceTree = ""; };
435D26B720DC83E400891C17 /* Locked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Locked.swift; sourceTree = ""; };
@@ -801,7 +789,6 @@
43DFB61220D37800008A7BAE /* ChangeMaxBasalRateMessageBodyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeMaxBasalRateMessageBodyTests.swift; sourceTree = ""; };
43DFB61420D3791A008A7BAE /* ChangeMaxBasalRateMessageBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeMaxBasalRateMessageBody.swift; sourceTree = ""; };
43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeInterval.swift; sourceTree = ""; };
- 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; };
43F348051D596270009933DC /* HKUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HKUnit.swift; sourceTree = ""; };
43FB610A20DDF55E002B996B /* LoopKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopKitUI.framework; path = Carthage/Build/iOS/LoopKitUI.framework; sourceTree = ""; };
43FB610B20DDF55F002B996B /* LoopKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopKit.framework; path = Carthage/Build/iOS/LoopKit.framework; sourceTree = ""; };
@@ -1027,18 +1014,16 @@
C12198AC1C8F332500BC374C /* TimestampedPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = TimestampedPumpEvent.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C12198B21C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BolusWizardEstimatePumpEvent.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C125728A211F7E6C0061BA2F /* UnknownPumpEvent57.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnknownPumpEvent57.swift; sourceTree = ""; };
+ C125728E2121DB7C0061BA2F /* PumpManagerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpManagerState.swift; sourceTree = ""; };
+ C12572912121EEEE0061BA2F /* SettingsImageTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsImageTableViewCell.swift; sourceTree = ""; };
+ C125729321220FEC0061BA2F /* MainStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = ""; };
+ C12572972125FA390061BA2F /* RileyLinkConnectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkConnectionManager.swift; sourceTree = ""; };
C12616431B685F0A001FAD87 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
- C126164A1B685F93001FAD87 /* RileyLink.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = RileyLink.xcdatamodel; sourceTree = ""; };
- C12616521B6892DB001FAD87 /* RileyLinkRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RileyLinkRecord.h; sourceTree = ""; };
- C12616531B6892DB001FAD87 /* RileyLinkRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RileyLinkRecord.m; sourceTree = ""; };
C1271B061A9A34E900B7C949 /* Log.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Log.m; sourceTree = ""; };
C1271B081A9A350400B7C949 /* Log.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = ""; };
C1274F761D8232580002912B /* DailyTotal515PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DailyTotal515PumpEvent.swift; sourceTree = ""; };
C1274F781D823A550002912B /* ChangeMeterIDPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeMeterIDPumpEvent.swift; sourceTree = ""; };
- C1274F7B1D82411C0002912B /* AuthenticationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationViewController.swift; sourceTree = ""; };
- C1274F7C1D82411C0002912B /* RileyLinkListTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkListTableViewController.swift; sourceTree = ""; };
- C1274F7D1D82411C0002912B /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = ""; };
- C1274F831D82420F0002912B /* RadioSelectionTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioSelectionTableViewController.swift; sourceTree = ""; };
+ C1274F7C1D82411C0002912B /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; };
C1274F851D8242BE0002912B /* PumpRegion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpRegion.swift; sourceTree = ""; };
C12EA237198B436800309FA4 /* RileyLink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RileyLink.app; sourceTree = BUILT_PRODUCTS_DIR; };
C12EA23A198B436800309FA4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@@ -1046,13 +1031,11 @@
C12EA23E198B436800309FA4 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
C12EA242198B436800309FA4 /* RileyLink-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RileyLink-Info.plist"; sourceTree = ""; };
C12EA244198B436800309FA4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
- C12EA24C198B436800309FA4 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
C12EA252198B436800309FA4 /* RileyLinkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RileyLinkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C12EA253198B436800309FA4 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
C12EA25B198B436900309FA4 /* RileyLinkTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RileyLinkTests-Info.plist"; sourceTree = ""; };
C12EA25D198B436900309FA4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
C12EA25F198B436900309FA4 /* RileyLinkTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RileyLinkTests.m; sourceTree = ""; };
- C12EA269198B442100309FA4 /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; };
C1330F421DBDA46400569064 /* ChangeSensorAlarmSilenceConfigPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeSensorAlarmSilenceConfigPumpEvent.swift; sourceTree = ""; };
C133CF921D5943780034B82D /* PredictedBG.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictedBG.swift; sourceTree = ""; };
C13D15591DAACE8400ADC044 /* Either.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Either.swift; sourceTree = ""; };
@@ -1065,13 +1048,8 @@
C14FFC491D3AF1AC0049CF85 /* JournalEntryInsulinMarkerPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JournalEntryInsulinMarkerPumpEvent.swift; sourceTree = ""; };
C14FFC4E1D3D6DEF0049CF85 /* ServiceAuthentication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceAuthentication.swift; sourceTree = ""; };
C14FFC4F1D3D6DEF0049CF85 /* ServiceCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceCredential.swift; sourceTree = ""; };
- C14FFC521D3D70170049CF85 /* ValidatingIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidatingIndicatorView.swift; sourceTree = ""; };
C14FFC541D3D72A50049CF85 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; };
- C14FFC561D3D72D30049CF85 /* AuthenticationTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationTableViewCell.swift; sourceTree = ""; };
- C14FFC571D3D72D30049CF85 /* AuthenticationTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AuthenticationTableViewCell.xib; sourceTree = ""; };
C14FFC5A1D3D74F90049CF85 /* NibLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLoadable.swift; sourceTree = ""; };
- C14FFC5C1D3D75200049CF85 /* ButtonTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonTableViewCell.swift; sourceTree = ""; };
- C14FFC5D1D3D75200049CF85 /* ButtonTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ButtonTableViewCell.xib; sourceTree = ""; };
C14FFC601D3D75470049CF85 /* UIColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; };
C14FFC621D3D7CE20049CF85 /* NightscoutService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutService.swift; sourceTree = ""; };
C14FFC641D3D7E250049CF85 /* RemoteDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoteDataManager.swift; sourceTree = ""; };
@@ -1080,7 +1058,6 @@
C15AF2AC1D74929D0031FC9D /* ChangeBolusWizardSetupPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeBolusWizardSetupPumpEvent.swift; sourceTree = ""; };
C15AF2AE1D7498930031FC9D /* RestoreMystery54PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoreMystery54PumpEvent.swift; sourceTree = ""; };
C15AF2B01D7498DD0031FC9D /* RestoreMystery55PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoreMystery55PumpEvent.swift; sourceTree = ""; };
- C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchTableViewCell.swift; sourceTree = ""; };
C16A08301D389205001A200C /* JournalEntryMealMarkerPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JournalEntryMealMarkerPumpEvent.swift; sourceTree = ""; };
C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBPeripheralState.swift; sourceTree = ""; };
C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandResponseViewController.swift; sourceTree = ""; };
@@ -1235,6 +1212,8 @@
C1FFAF6B212B128800C50C1D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; };
C1FFAF6C212B128A00C50C1D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; };
C1FFAF6D212B128C00C50C1D /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; };
+ C1FFAF6E212CB4F100C50C1D /* RileyLinkConnectionManagerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkConnectionManagerState.swift; sourceTree = ""; };
+ C1FFAF71212FAAEF00C50C1D /* RileyLink.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = RileyLink.xcassets; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1402,6 +1381,8 @@
431CE79B1F9B21BA00255374 /* RileyLinkDevice.swift */,
433ABFFB2016FDF700E6C1FF /* RileyLinkDeviceError.swift */,
431CE7901F985D8D00255374 /* RileyLinkDeviceManager.swift */,
+ C12572972125FA390061BA2F /* RileyLinkConnectionManager.swift */,
+ C1FFAF6E212CB4F100C50C1D /* RileyLinkConnectionManagerState.swift */,
);
path = RileyLinkBLEKit;
sourceTree = "";
@@ -1498,7 +1479,6 @@
43323EA91FA81C1B003FB0FA /* RileyLinkDevice.swift */,
4352A74020DED23000CAC200 /* RileyLinkDeviceManager.swift */,
435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */,
- 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */,
);
path = RileyLinkKit;
sourceTree = "";
@@ -1720,37 +1700,18 @@
path = Messages;
sourceTree = "";
};
- C12616391B67CB9C001FAD87 /* Views */ = {
+ C12572902121EEDE0061BA2F /* Views */ = {
isa = PBXGroup;
children = (
- C14FFC561D3D72D30049CF85 /* AuthenticationTableViewCell.swift */,
- C14FFC571D3D72D30049CF85 /* AuthenticationTableViewCell.xib */,
- C14FFC521D3D70170049CF85 /* ValidatingIndicatorView.swift */,
- C14FFC5C1D3D75200049CF85 /* ButtonTableViewCell.swift */,
- C14FFC5D1D3D75200049CF85 /* ButtonTableViewCell.xib */,
- 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */,
- C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */,
+ C12572912121EEEE0061BA2F /* SettingsImageTableViewCell.swift */,
);
path = Views;
sourceTree = "";
};
- C12616451B685F35001FAD87 /* CoreData */ = {
- isa = PBXGroup;
- children = (
- C12616521B6892DB001FAD87 /* RileyLinkRecord.h */,
- C12616531B6892DB001FAD87 /* RileyLinkRecord.m */,
- C12616491B685F93001FAD87 /* RileyLink.xcdatamodeld */,
- );
- name = CoreData;
- sourceTree = "";
- };
C1274F7A1D8240D00002912B /* View Controllers */ = {
isa = PBXGroup;
children = (
- C1274F831D82420F0002912B /* RadioSelectionTableViewController.swift */,
- C1274F7B1D82411C0002912B /* AuthenticationViewController.swift */,
- C1274F7C1D82411C0002912B /* RileyLinkListTableViewController.swift */,
- C1274F7D1D82411C0002912B /* SettingsTableViewController.swift */,
+ C1274F7C1D82411C0002912B /* MainViewController.swift */,
);
path = "View Controllers";
sourceTree = "";
@@ -1816,21 +1777,19 @@
C12EA240198B436800309FA4 /* RileyLink */ = {
isa = PBXGroup;
children = (
+ C1FFAF71212FAAEF00C50C1D /* RileyLink.xcassets */,
+ C12572902121EEDE0061BA2F /* Views */,
C1274F7A1D8240D00002912B /* View Controllers */,
C14FFC4D1D3D6D8E0049CF85 /* Models */,
C1B383341CD1BA6700CE7782 /* Managers */,
C1AA398B1AB67F6A00BC9E33 /* Extensions */,
- C12616451B685F35001FAD87 /* CoreData */,
C12EA241198B436800309FA4 /* Supporting Files */,
- C12616391B67CB9C001FAD87 /* Views */,
43462E8A1CCB06F500F958A8 /* AppDelegate.swift */,
+ C125729321220FEC0061BA2F /* MainStoryboard.storyboard */,
C1EF58861B3F93FE001C8C80 /* Config.h */,
C1EF58871B3F93FE001C8C80 /* Config.m */,
- C12EA24C198B436800309FA4 /* Images.xcassets */,
- 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */,
C1271B081A9A350400B7C949 /* Log.h */,
C1271B061A9A34E900B7C949 /* Log.m */,
- C12EA269198B442100309FA4 /* Storyboard.storyboard */,
);
path = RileyLink;
sourceTree = "";
@@ -2036,6 +1995,7 @@
C14FFC681D3D7E560049CF85 /* KeychainManager+RileyLink.swift */,
C14FFC641D3D7E250049CF85 /* RemoteDataManager.swift */,
C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */,
+ C125728E2121DB7C0061BA2F /* PumpManagerState.swift */,
);
name = Managers;
sourceTree = "";
@@ -2541,7 +2501,6 @@
buildActionMask = 2147483647;
files = (
7D23674A21252A5E0028B67D /* InfoPlist.strings in Resources */,
- 7D23676121252A9D0028B67D /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2568,7 +2527,6 @@
buildActionMask = 2147483647;
files = (
7D23674721252A5E0028B67D /* InfoPlist.strings in Resources */,
- 7D23676721252A9D0028B67D /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2605,7 +2563,6 @@
buildActionMask = 2147483647;
files = (
7D23674D21252A5E0028B67D /* InfoPlist.strings in Resources */,
- 7D23676921252A9D0028B67D /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2613,14 +2570,11 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 43EC9DCB1B786C6200DB0D18 /* LaunchScreen.xib in Resources */,
- C14FFC5F1D3D75200049CF85 /* ButtonTableViewCell.xib in Resources */,
+ C125729421220FEC0061BA2F /* MainStoryboard.storyboard in Resources */,
+ C1FFAF72212FAAEF00C50C1D /* RileyLink.xcassets in Resources */,
7D70766D1FE092D4004AC8EA /* LoopKit.strings in Resources */,
C12EA245198B436800309FA4 /* InfoPlist.strings in Resources */,
- C12EA24D198B436800309FA4 /* Images.xcassets in Resources */,
7D7076951FE09311004AC8EA /* Localizable.strings in Resources */,
- C12EA26A198B442100309FA4 /* Storyboard.storyboard in Resources */,
- C14FFC591D3D72D30049CF85 /* AuthenticationTableViewCell.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2645,7 +2599,6 @@
buildActionMask = 2147483647;
files = (
7D23675321252A5E0028B67D /* InfoPlist.strings in Resources */,
- 7D23676B21252A9D0028B67D /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2693,11 +2646,13 @@
files = (
7D2366F5212527DA0028B67D /* LocalizedString.swift in Sources */,
43BA719D2026C9B00058961E /* ResponseBuffer.swift in Sources */,
+ C1FFAF6F212CB4F100C50C1D /* RileyLinkConnectionManagerState.swift in Sources */,
431CE78F1F985B6E00255374 /* CBPeripheral.swift in Sources */,
431CE79F1F9C670600255374 /* TimeInterval.swift in Sources */,
433ABFFC2016FDF700E6C1FF /* RileyLinkDeviceError.swift in Sources */,
43BA719B202591A70058961E /* Response.swift in Sources */,
43D5E7881FAEDAC4004ACDB7 /* PeripheralManagerError.swift in Sources */,
+ C12572982125FA390061BA2F /* RileyLinkConnectionManager.swift in Sources */,
431CE79C1F9B21BA00255374 /* RileyLinkDevice.swift in Sources */,
431CE7A71F9D98F700255374 /* CommandSession.swift in Sources */,
431CE7A31F9D737F00255374 /* Command.swift in Sources */,
@@ -2759,7 +2714,6 @@
43EBE4531EAD23CE0073A0B5 /* TimeInterval.swift in Sources */,
434AB0C71CBCB76400422F4A /* Data.swift in Sources */,
4352A74120DED23100CAC200 /* RileyLinkDeviceManager.swift in Sources */,
- 435D26B220DA091C00891C17 /* RileyLinkPumpManagerState.swift in Sources */,
431CE7961F9B0F0200255374 /* OSLog.swift in Sources */,
437F54071FBD52120070FF2C /* DeviceState.swift in Sources */,
435D26B020DA08CE00891C17 /* RileyLinkPumpManager.swift in Sources */,
@@ -3058,35 +3012,31 @@
buildActionMask = 2147483647;
files = (
435535D61FB6D98400CE5A23 /* UserDefaults.swift in Sources */,
- C14FFC5E1D3D75200049CF85 /* ButtonTableViewCell.swift in Sources */,
43EBE4551EAD24410073A0B5 /* TimeInterval.swift in Sources */,
C14FFC691D3D7E560049CF85 /* KeychainManager+RileyLink.swift in Sources */,
437F540A1FBFDAA60070FF2C /* Data.swift in Sources */,
C14FFC511D3D6DEF0049CF85 /* ServiceCredential.swift in Sources */,
C14FFC5B1D3D74F90049CF85 /* NibLoadable.swift in Sources */,
+ C12572922121EEEE0061BA2F /* SettingsImageTableViewCell.swift in Sources */,
+ C125728D2121D56D0061BA2F /* CaseCountable.swift in Sources */,
C14FFC611D3D75470049CF85 /* UIColor.swift in Sources */,
- C1274F811D82411C0002912B /* SettingsTableViewController.swift in Sources */,
43323EA71FA81A0F003FB0FA /* NumberFormatter.swift in Sources */,
C14FFC671D3D7E390049CF85 /* KeychainManager.swift in Sources */,
C14FFC501D3D6DEF0049CF85 /* ServiceAuthentication.swift in Sources */,
- C1274F7F1D82411C0002912B /* AuthenticationViewController.swift in Sources */,
43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */,
- C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */,
+ C125728C2121D4D60061BA2F /* UITableViewCell.swift in Sources */,
C14FFC551D3D72A50049CF85 /* UIViewController.swift in Sources */,
- 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */,
7D2366F0212527DA0028B67D /* LocalizedString.swift in Sources */,
C14FFC651D3D7E250049CF85 /* RemoteDataManager.swift in Sources */,
C17884611D519F1E00405663 /* BatteryIndicator.swift in Sources */,
437462391FA9287A00643383 /* RileyLinkDevice.swift in Sources */,
- C1274F801D82411C0002912B /* RileyLinkListTableViewController.swift in Sources */,
- C1274F841D82420F0002912B /* RadioSelectionTableViewController.swift in Sources */,
+ C1274F801D82411C0002912B /* MainViewController.swift in Sources */,
431CE7981F9B0F0200255374 /* OSLog.swift in Sources */,
C1EF58881B3F93FE001C8C80 /* Config.m in Sources */,
- C14FFC581D3D72D30049CF85 /* AuthenticationTableViewCell.swift in Sources */,
+ C125728F2121DB7C0061BA2F /* PumpManagerState.swift in Sources */,
C14FFC631D3D7CE20049CF85 /* NightscoutService.swift in Sources */,
C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */,
C1271B071A9A34E900B7C949 /* Log.m in Sources */,
- C14FFC531D3D70170049CF85 /* ValidatingIndicatorView.swift in Sources */,
434FF1DC1CF268BD000DB779 /* IdentifiableClass.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -3595,7 +3545,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = RileyLinkBLEKit/Info.plist;
@@ -3631,7 +3581,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = RileyLinkBLEKit/Info.plist;
@@ -3708,14 +3658,14 @@
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3747,7 +3697,7 @@
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
@@ -3755,7 +3705,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3784,11 +3734,11 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
@@ -3821,11 +3771,11 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
@@ -3905,12 +3855,12 @@
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Crypto/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -3936,12 +3886,12 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Crypto/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -3971,7 +3921,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4010,7 +3960,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4054,12 +4004,12 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
@@ -4091,11 +4041,11 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
@@ -4198,7 +4148,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -4265,7 +4215,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -4298,6 +4248,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -4323,6 +4274,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -4389,11 +4341,11 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
@@ -4419,11 +4371,11 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 39;
+ CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 39;
+ DYLIB_CURRENT_VERSION = 40;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
@@ -4623,19 +4575,6 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
-
-/* Begin XCVersionGroup section */
- C12616491B685F93001FAD87 /* RileyLink.xcdatamodeld */ = {
- isa = XCVersionGroup;
- children = (
- C126164A1B685F93001FAD87 /* RileyLink.xcdatamodel */,
- );
- currentVersion = C126164A1B685F93001FAD87 /* RileyLink.xcdatamodel */;
- path = RileyLink.xcdatamodeld;
- sourceTree = "";
- versionGroupType = wrapper.xcdatamodel;
- };
-/* End XCVersionGroup section */
};
rootObject = C12EA22F198B436800309FA4 /* Project object */;
}
diff --git a/RileyLink/AppDelegate.swift b/RileyLink/AppDelegate.swift
index 10985f27c..4802ab935 100644
--- a/RileyLink/AppDelegate.swift
+++ b/RileyLink/AppDelegate.swift
@@ -10,24 +10,19 @@ import UIKit
import CoreData
import RileyLinkKit
+
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
+ private(set) lazy var deviceDataManager = DeviceDataManager()
+
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
- let logFileURL = applicationDocumentsDirectory().appendingPathComponent("logfile.txt")
- do {
- try FileManager.default.removeItem(at: logFileURL)
- } catch let error {
- NSLog("Could not remove file at path: \(logFileURL): \(error)")
- }
-
- // Just instantiate the DeviceDataManager
- let delayTime = DispatchTime.now() + .seconds(1)
- DispatchQueue.main.asyncAfter(deadline: delayTime) {
- _ = DeviceDataManager.sharedManager
+ if let navController = self.window?.rootViewController as? UINavigationController {
+ let mainViewController = MainViewController(deviceDataManager: deviceDataManager)
+ navController.pushViewController(mainViewController, animated: false)
}
return true
@@ -64,7 +59,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
completionHandler(false)
- }
+ }
}
diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift
index 8b7413411..f72d5ddff 100644
--- a/RileyLink/DeviceDataManager.swift
+++ b/RileyLink/DeviceDataManager.swift
@@ -13,393 +13,95 @@ import RileyLinkBLEKit
import MinimedKit
import MinimedKitUI
import NightscoutUploadKit
+import LoopKit
+import LoopKitUI
+import os.log
class DeviceDataManager {
- let rileyLinkManager: RileyLinkDeviceManager
+ let rileyLinkConnectionManager: RileyLinkConnectionManager
- /// Manages remote data
- let remoteDataManager = RemoteDataManager()
-
- private var connectedPeripheralIDs: Set = Config.sharedInstance().autoConnectIds as! Set {
- didSet {
- Config.sharedInstance().autoConnectIds = connectedPeripheralIDs
- }
- }
-
- var deviceStates: [UUID: DeviceState] = [:]
-
- private(set) var pumpOps: PumpOps? {
+ var pumpManager: PumpManagerUI? {
didSet {
- if pumpOps == nil {
- UserDefaults.standard.pumpState = nil
- }
+ pumpManager?.pumpManagerDelegate = self
+ UserDefaults.standard.pumpManagerRawValue = pumpManager?.rawValue
}
}
+
- private(set) var pumpSettings: PumpSettings? {
- get {
- return UserDefaults.standard.pumpSettings
+ public let log = OSLog(category: "DeviceDataManager")
+
+ init() {
+
+ if let connectionManagerState = UserDefaults.standard.rileyLinkConnectionManagerState {
+ rileyLinkConnectionManager = RileyLinkConnectionManager(state: connectionManagerState)
+ } else {
+ rileyLinkConnectionManager = RileyLinkConnectionManager(autoConnectIDs: [])
}
- set {
- if let settings = newValue {
- pumpOps = PumpOps(pumpSettings: settings, pumpState: nil, delegate: self)
- } else {
- pumpOps = nil
- }
+ rileyLinkConnectionManager.delegate = self
+ rileyLinkConnectionManager.setScanningEnabled(true)
- UserDefaults.standard.pumpSettings = newValue
+ if let pumpManagerRawValue = UserDefaults.standard.pumpManagerRawValue {
+ pumpManager = PumpManagerFromRawValue(pumpManagerRawValue, rileyLinkDeviceProvider: rileyLinkConnectionManager.deviceProvider) as? PumpManagerUI
+ pumpManager?.pumpManagerDelegate = self
}
}
+}
- func setPumpID(_ pumpID: String?) {
- var newValue = pumpID
-
- if newValue?.count != 6 {
- newValue = nil
- }
-
- if let newValue = newValue {
- if pumpSettings != nil {
- pumpSettings?.pumpID = newValue
- } else {
- pumpSettings = PumpSettings(pumpID: newValue)
- }
- }
- }
+extension DeviceDataManager: RileyLinkConnectionManagerDelegate {
+ func rileyLinkConnectionManager(_ rileyLinkConnectionManager: RileyLinkConnectionManager, didChange state: RileyLinkConnectionManagerState)
+ {
+ UserDefaults.standard.rileyLinkConnectionManagerState = state
+ }
+}
- func setPumpRegion(_ pumpRegion: PumpRegion) {
- pumpSettings?.pumpRegion = pumpRegion
+extension DeviceDataManager: PumpManagerDelegate {
+ func pumpManager(_ pumpManager: PumpManager, didAdjustPumpClockBy adjustment: TimeInterval) {
+ log.debug("didAdjustPumpClockBy %@", adjustment)
}
- var pumpState: PumpState? {
- return UserDefaults.standard.pumpState
- }
-
- // MARK: - Operation helpers
-
- var latestPumpStatusDate: Date?
-
- var latestPumpStatusFromMySentry: MySentryPumpStatusMessageBody? {
- didSet {
- if let update = latestPumpStatusFromMySentry, let timeZone = pumpState?.timeZone {
- var pumpClock = update.pumpDateComponents
- pumpClock.timeZone = timeZone
- latestPumpStatusDate = pumpClock.date
- }
- }
+ func pumpManagerDidUpdatePumpBatteryChargeRemaining(_ pumpManager: PumpManager, oldValue: Double?) {
}
-
-
- var latestPolledPumpStatus: MinimedKit.PumpStatus? {
- didSet {
- if let update = latestPolledPumpStatus {
- latestPumpStatusDate = update.clock.date
- }
- }
- }
-
- var lastHistoryAttempt: Date? = nil
- var lastGlucoseEntry: Date = Date(timeIntervalSinceNow: TimeInterval(hours: -24))
-
- /**
- Called when a new idle message is received by the RileyLink.
-
- Only MySentryPumpStatus messages are handled.
-
- - parameter note: The notification object
- */
- @objc private func receivedRileyLinkPacketNotification(_ note: Notification) {
- guard
- let device = note.object as? RileyLinkDevice,
- let packet = note.userInfo?[RileyLinkDevice.notificationPacketKey] as? RFPacket,
- let decoded = MinimedPacket(encodedData: packet.data),
- let message = PumpMessage(rxData: decoded.data),
- let address = pumpSettings?.pumpID,
- message.address.hexadecimalString == address
- else {
- return
- }
-
- switch message.packetType {
- case .mySentry:
- switch message.messageBody {
- case let body as MySentryPumpStatusMessageBody:
- pumpStatusUpdateReceived(body, fromDevice: device)
- default:
- break
- }
- default:
- break
- }
+ func pumpManagerDidUpdateState(_ pumpManager: PumpManager) {
+ UserDefaults.standard.pumpManagerRawValue = pumpManager.rawValue
}
- @objc private func receivedRileyLinkTimerTickNotification(_ note: Notification) {
- if Config.sharedInstance().uploadEnabled {
- rileyLinkManager.getDevices { (devices) in
- if let device = devices.firstConnected {
- self.assertCurrentPumpData(from: device)
- }
- }
- }
- }
-
- @objc private func deviceStateDidChange(_ note: Notification) {
- guard
- let device = note.object as? RileyLinkDevice,
- let deviceState = note.userInfo?[RileyLinkDevice.notificationDeviceStateKey] as? DeviceState
- else {
- return
- }
-
- deviceStates[device.peripheralIdentifier] = deviceState
+ func pumpManagerBLEHeartbeatDidFire(_ pumpManager: PumpManager) {
}
- func connectToRileyLink(_ device: RileyLinkDevice) {
- connectedPeripheralIDs.insert(device.peripheralIdentifier.uuidString)
-
- rileyLinkManager.connect(device)
+ func pumpManagerShouldProvideBLEHeartbeat(_ pumpManager: PumpManager) -> Bool {
+ return true
}
- func disconnectFromRileyLink(_ device: RileyLinkDevice) {
- connectedPeripheralIDs.remove(device.peripheralIdentifier.uuidString)
-
- rileyLinkManager.disconnect(device)
+ func pumpManager(_ pumpManager: PumpManager, didUpdateStatus status: PumpManagerStatus) {
}
- private func pumpStatusUpdateReceived(_ status: MySentryPumpStatusMessageBody, fromDevice device: RileyLinkDevice) {
-
- var pumpDateComponents = status.pumpDateComponents
- var glucoseDateComponents = status.glucoseDateComponents
-
- pumpDateComponents.timeZone = pumpState?.timeZone
- glucoseDateComponents?.timeZone = pumpState?.timeZone
-
- // Avoid duplicates
- if status != latestPumpStatusFromMySentry {
- latestPumpStatusFromMySentry = status
-
- // Sentry packets are sent in groups of 3, 5s apart. Wait 11s to avoid conflicting comms.
- let delay = DispatchTime.now() + .seconds(11)
- DispatchQueue.main.asyncAfter(deadline: delay) {
- self.getPumpHistory(device)
- }
-
- if status.batteryRemainingPercent == 0 {
- //NotificationManager.sendPumpBatteryLowNotification()
- }
-
- guard Config.sharedInstance().uploadEnabled, let pumpID = pumpSettings?.pumpID else {
- return
- }
-
- // Gather PumpStatus from MySentry packet
- let pumpStatus: NightscoutUploadKit.PumpStatus?
- if let pumpDate = pumpDateComponents.date {
-
- let batteryStatus = BatteryStatus(percent: status.batteryRemainingPercent)
- let iobStatus = IOBStatus(timestamp: pumpDate, iob: status.iob)
-
- pumpStatus = NightscoutUploadKit.PumpStatus(clock: pumpDate, pumpID: pumpID, iob: iobStatus, battery: batteryStatus, reservoir: status.reservoirRemainingUnits)
- } else {
- pumpStatus = nil
- print("Could not interpret pump clock: \(pumpDateComponents)")
- }
-
- // Trigger device status upload, even if something is wrong with pumpStatus
- self.uploadDeviceStatus(pumpStatus)
-
- // Send SGVs
- remoteDataManager.nightscoutUploader?.uploadSGVFromMySentryPumpStatus(status, device: device.deviceURI)
- }
+ func pumpManagerWillDeactivate(_ pumpManager: PumpManager) {
+ self.pumpManager = nil
}
- private func uploadDeviceStatus(_ pumpStatus: NightscoutUploadKit.PumpStatus? /*, loopStatus: LoopStatus */) {
-
- guard let uploader = remoteDataManager.nightscoutUploader else {
- return
- }
-
- // Gather UploaderStatus
- let uploaderDevice = UIDevice.current
- let uploaderStatus = UploaderStatus(name: uploaderDevice.name, timestamp: Date(), battery: uploaderDevice.batteryLevel)
-
- // Build DeviceStatus
- let deviceStatus = DeviceStatus(device: "rileylink://" + uploaderDevice.name, timestamp: Date(), pumpStatus: pumpStatus, uploaderStatus: uploaderStatus)
-
- uploader.uploadDeviceStatus(deviceStatus)
+ func pumpManager(_ pumpManager: PumpManager, didUpdatePumpRecordsBasalProfileStartEvents pumpRecordsBasalProfileStartEvents: Bool) {
}
- /**
- Ensures pump data is current by either waking and polling, or ensuring we're listening to sentry packets.
- */
- private func assertCurrentPumpData(from device: RileyLinkDevice) {
- device.assertIdleListening()
-
- // How long should we wait before we poll for new pump data?
- let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 11) : TimeInterval(minutes: 4)
-
- // If we don't yet have pump status, or it's old, poll for it.
- if latestPumpStatusDate == nil || latestPumpStatusDate!.timeIntervalSinceNow <= -pumpStatusAgeTolerance {
-
- guard let pumpOps = pumpOps else {
- self.troubleshootPumpCommsWithDevice(device)
- return
- }
-
- pumpOps.runSession(withName: "Read pump status", using: device) { (session) in
- do {
- let status = try session.getCurrentPumpStatus()
- DispatchQueue.main.async {
- self.latestPolledPumpStatus = status
- let battery = BatteryStatus(voltage: status.batteryVolts.converted(to: .volts).value, status: BatteryIndicator(batteryStatus: status.batteryStatus))
- guard let date = status.clock.date else {
- print("Could not interpret clock")
- return
- }
- let nsPumpStatus = NightscoutUploadKit.PumpStatus(clock: date, pumpID: status.pumpID, iob: nil, battery: battery, suspended: status.suspended, bolusing: status.bolusing, reservoir: status.reservoir)
- self.uploadDeviceStatus(nsPumpStatus)
- }
- } catch {
- DispatchQueue.main.async {
- self.troubleshootPumpCommsWithDevice(device)
- }
- }
- }
- }
-
- if lastHistoryAttempt == nil || lastHistoryAttempt!.timeIntervalSinceNow < TimeInterval(minutes: -5) {
- getPumpHistory(device)
- }
- }
-
- /**
- Attempts to fix an extended communication failure between a RileyLink device and the pump
-
- - parameter device: The RileyLink device
- */
- private func troubleshootPumpCommsWithDevice(_ device: RileyLinkDevice) {
-
- // How long we should wait before we re-tune the RileyLink
- let tuneTolerance = TimeInterval(minutes: 14)
-
- guard let pumpOps = pumpOps else {
- return
- }
-
- let deviceState = deviceStates[device.peripheralIdentifier, default: DeviceState()]
- let lastTuned = deviceState.lastTuned ?? .distantPast
-
- if lastTuned.timeIntervalSinceNow <= -tuneTolerance {
- pumpOps.runSession(withName: "Tune pump", using: device) { (session) in
- do {
- let scanResult = try session.tuneRadio(current: deviceState.lastValidFrequency)
- print("Device auto-tuned to \(scanResult.bestFrequency)")
-
- DispatchQueue.main.async {
- self.deviceStates[device.peripheralIdentifier] = DeviceState(lastTuned: Date(), lastValidFrequency: scanResult.bestFrequency)
- }
- } catch let error {
- print("Device auto-tune failed with error: \(error)")
- }
- }
- }
+ func pumpManager(_ pumpManager: PumpManager, didError error: PumpManagerError) {
+ log.error("pumpManager didError %@", String(describing: error))
}
- private func getPumpHistory(_ device: RileyLinkDevice) {
- lastHistoryAttempt = Date()
-
- guard let pumpOps = pumpOps else {
- print("Missing pumpOps; is your pumpId configured?")
- return
- }
-
- let oneDayAgo = Date(timeIntervalSinceNow: TimeInterval(hours: -24))
-
- pumpOps.runSession(withName: "Get pump history", using: device) { (session) in
- do {
- let (events, pumpModel) = try session.getHistoryEvents(since: oneDayAgo)
- NSLog("fetchHistory succeeded.")
- DispatchQueue.main.async {
- self.handleNewHistoryEvents(events, pumpModel: pumpModel, device: device)
- }
- } catch let error {
- NSLog("History fetch failed: %@", String(describing: error))
- }
-
- if Config.sharedInstance().fetchCGMEnabled, self.lastGlucoseEntry.timeIntervalSinceNow < TimeInterval(minutes: -5) {
- self.getPumpGlucoseHistory(device)
- }
- }
+ func pumpManager(_ pumpManager: PumpManager, didReadPumpEvents events: [NewPumpEvent], completion: @escaping (_ error: Error?) -> Void) {
}
- private func handleNewHistoryEvents(_ events: [TimestampedHistoryEvent], pumpModel: PumpModel, device: RileyLinkDevice) {
- // TODO: get insulin doses from history
- if Config.sharedInstance().uploadEnabled {
- remoteDataManager.nightscoutUploader?.processPumpEvents(events, source: device.deviceURI, pumpModel: pumpModel)
- }
+ func pumpManager(_ pumpManager: PumpManager, didReadReservoirValue units: Double, at date: Date, completion: @escaping (_ result: PumpManagerResult<(newValue: ReservoirValue, lastValue: ReservoirValue?, areStoredValuesContinuous: Bool)>) -> Void) {
}
- private func getPumpGlucoseHistory(_ device: RileyLinkDevice) {
- guard let pumpOps = pumpOps else {
- print("Missing pumpOps; is your pumpId configured?")
- return
- }
-
- pumpOps.runSession(withName: "Get glucose history", using: device) { (session) in
- do {
- let events = try session.getGlucoseHistoryEvents(since: self.lastGlucoseEntry)
- NSLog("fetchGlucoseHistory succeeded.")
- if let latestEntryDate: Date = self.handleNewGlucoseHistoryEvents(events, device: device) {
- self.lastGlucoseEntry = latestEntryDate
- }
- } catch let error {
- NSLog("Glucose History fetch failed: %@", String(describing: error))
- }
- }
+ func pumpManagerRecommendsLoop(_ pumpManager: PumpManager) {
}
- private func handleNewGlucoseHistoryEvents(_ events: [TimestampedGlucoseEvent], device: RileyLinkDevice) -> Date? {
- if Config.sharedInstance().uploadEnabled {
- return remoteDataManager.nightscoutUploader?.processGlucoseEvents(events, source: device.deviceURI)
- }
- return nil
+ func startDateToFilterNewPumpEvents(for manager: PumpManager) -> Date {
+ return Date().addingTimeInterval(.hours(-2))
}
- // MARK: - Initialization
-
- static let sharedManager = DeviceDataManager()
-
- init() {
- rileyLinkManager = RileyLinkDeviceManager(autoConnectIDs: connectedPeripheralIDs)
-
- var idleListeningEnabled = true
-
- if let pumpSettings = UserDefaults.standard.pumpSettings {
- idleListeningEnabled = self.pumpState?.pumpModel?.hasMySentry ?? true
-
- self.pumpOps = PumpOps(pumpSettings: pumpSettings, pumpState: self.pumpState, delegate: self)
- }
-
- rileyLinkManager.idleListeningState = idleListeningEnabled ? .enabledWithDefaults : .disabled
-
- UIDevice.current.isBatteryMonitoringEnabled = true
-
- // Device observers
- NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkPacketNotification(_:)), name: .DevicePacketReceived, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkTimerTickNotification(_:)), name: .DeviceTimerDidTick, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(deviceStateDidChange(_:)), name: .DeviceStateDidChange, object: nil)
- }
-}
-
-
-extension DeviceDataManager: PumpOpsDelegate {
- func pumpOps(_ pumpOps: PumpOps, didChange state: PumpState) {
- if let sentrySupported = state.pumpModel?.hasMySentry {
- rileyLinkManager.idleListeningState = sentrySupported ? .enabledWithDefaults : .disabled
- }
-
- UserDefaults.standard.pumpState = state
+ func startDateToFilterNewReservoirEvents(for manager: PumpManager) -> Date {
+ return Date().addingTimeInterval(.minutes(-15))
}
}
diff --git a/RileyLink/Extensions/UserDefaults.swift b/RileyLink/Extensions/UserDefaults.swift
index 844793675..dee16412a 100644
--- a/RileyLink/Extensions/UserDefaults.swift
+++ b/RileyLink/Extensions/UserDefaults.swift
@@ -6,39 +6,37 @@
//
import Foundation
-import MinimedKit
-
+import LoopKit
+import RileyLinkKit
+import RileyLinkBLEKit
extension UserDefaults {
private enum Key: String {
- case pumpSettings = "com.rileylink.pumpSettings"
- case pumpState = "com.rileylink.pumpState"
+ case pumpManagerRawValue = "com.rileylink.PumpManagerRawValue"
+ case rileyLinkConnectionManagerState = "com.rileylink.RileyLinkConnectionManagerState"
}
-
- var pumpSettings: PumpSettings? {
+
+ var pumpManagerRawValue: PumpManager.RawStateValue? {
get {
- guard let raw = dictionary(forKey: Key.pumpSettings.rawValue) else {
- return nil
- }
-
- return PumpSettings(rawValue: raw)
+ return dictionary(forKey: Key.pumpManagerRawValue.rawValue)
}
set {
- set(newValue?.rawValue
- , forKey: Key.pumpSettings.rawValue)
+ set(newValue, forKey: Key.pumpManagerRawValue.rawValue)
}
}
-
- var pumpState: PumpState? {
+
+ var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState? {
get {
- guard let raw = dictionary(forKey: Key.pumpState.rawValue) else {
+ guard let rawValue = dictionary(forKey: Key.rileyLinkConnectionManagerState.rawValue) else
+ {
return nil
}
-
- return PumpState(rawValue: raw)
+ return RileyLinkConnectionManagerState(rawValue: rawValue)
}
set {
- set(newValue?.rawValue, forKey: Key.pumpState.rawValue)
+ set(newValue?.rawValue, forKey: Key.rileyLinkConnectionManagerState.rawValue)
}
}
+
}
+
diff --git a/RileyLink/Images.xcassets/icon-settings.imageset/Contents.json b/RileyLink/Images.xcassets/icon-settings.imageset/Contents.json
deleted file mode 100644
index a683f09c8..000000000
--- a/RileyLink/Images.xcassets/icon-settings.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "settings.png",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "settings@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "filename" : "settings@3x.png",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/RileyLink/Images.xcassets/icon-settings.imageset/settings.png b/RileyLink/Images.xcassets/icon-settings.imageset/settings.png
deleted file mode 100644
index e4a03e849..000000000
Binary files a/RileyLink/Images.xcassets/icon-settings.imageset/settings.png and /dev/null differ
diff --git a/RileyLink/Images.xcassets/icon-settings.imageset/settings@2x.png b/RileyLink/Images.xcassets/icon-settings.imageset/settings@2x.png
deleted file mode 100644
index 128cb8ef5..000000000
Binary files a/RileyLink/Images.xcassets/icon-settings.imageset/settings@2x.png and /dev/null differ
diff --git a/RileyLink/Images.xcassets/icon-settings.imageset/settings@3x.png b/RileyLink/Images.xcassets/icon-settings.imageset/settings@3x.png
deleted file mode 100644
index d010f71d7..000000000
Binary files a/RileyLink/Images.xcassets/icon-settings.imageset/settings@3x.png and /dev/null differ
diff --git a/RileyLink/LaunchScreen.xib b/RileyLink/LaunchScreen.xib
deleted file mode 100644
index 77207a771..000000000
--- a/RileyLink/LaunchScreen.xib
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/RileyLink/MainStoryboard.storyboard b/RileyLink/MainStoryboard.storyboard
new file mode 100644
index 000000000..fae14a8ab
--- /dev/null
+++ b/RileyLink/MainStoryboard.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RileyLink/PumpManagerState.swift b/RileyLink/PumpManagerState.swift
new file mode 100644
index 000000000..dfe5ded89
--- /dev/null
+++ b/RileyLink/PumpManagerState.swift
@@ -0,0 +1,43 @@
+//
+// PumpManagerState.swift
+// Loop
+//
+// Copyright © 2018 LoopKit Authors. All rights reserved.
+//
+
+import Foundation
+import LoopKit
+import MinimedKit
+import RileyLinkBLEKit
+
+
+let allPumpManagers: [String: PumpManager.Type] = [
+ MinimedPumpManager.managerIdentifier: MinimedPumpManager.self
+]
+
+func PumpManagerFromRawValue(_ rawValue: [String: Any], rileyLinkDeviceProvider: RileyLinkDeviceProvider) -> PumpManager? {
+ guard let managerIdentifier = rawValue["managerIdentifier"] as? String,
+ let rawState = rawValue["state"] as? PumpManager.RawStateValue
+ else {
+ return nil
+ }
+
+ switch (managerIdentifier) {
+ case MinimedPumpManager.managerIdentifier:
+ guard let state = MinimedPumpManagerState(rawValue: rawState) else {
+ return nil
+ }
+ return MinimedPumpManager(state: state, rileyLinkDeviceProvider: rileyLinkDeviceProvider)
+ default:
+ return nil
+ }
+}
+
+extension PumpManager {
+ var rawValue: [String: Any] {
+ return [
+ "managerIdentifier": type(of: self).managerIdentifier,
+ "state": self.rawState
+ ]
+ }
+}
diff --git a/RileyLink/RileyLink-Info.plist b/RileyLink/RileyLink-Info.plist
index 3991a00ee..e843d670a 100644
--- a/RileyLink/RileyLink-Info.plist
+++ b/RileyLink/RileyLink-Info.plist
@@ -19,7 +19,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
@@ -40,9 +40,9 @@
UIFileSharingEnabled
UILaunchStoryboardName
- LaunchScreen
+ MainStoryboard
UIMainStoryboardFile
- Storyboard
+ MainStoryboard
UIRequiredDeviceCapabilities
bluetooth-le
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Contents.json b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Contents.json
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Contents.json
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-60@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-60@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-72.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-72.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-72.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-72.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-72@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-72@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-72@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-76.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-76.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-76.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-76.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-76@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-76@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-40.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-40.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-40.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-40.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-50.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-50.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-50.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small@3x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-Small@3x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon-ipadpro.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-ipadpro.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon-ipadpro.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon-ipadpro.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/Icon@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/Icon@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/Icon@2x.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/iTunesArtwork@2x-1.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/iTunesArtwork@2x-1.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/iTunesArtwork@2x-1.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/iTunesArtwork@2x-1.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/iTunesArtwork@2x-2.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/iTunesArtwork@2x-2.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/iTunesArtwork@2x-2.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/iTunesArtwork@2x-2.png
diff --git a/RileyLink/Images.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png b/RileyLink/RileyLink.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png
similarity index 100%
rename from RileyLink/Images.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png
rename to RileyLink/RileyLink.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png
diff --git a/RileyLink/Images.xcassets/Contents.json b/RileyLink/RileyLink.xcassets/Contents.json
similarity index 100%
rename from RileyLink/Images.xcassets/Contents.json
rename to RileyLink/RileyLink.xcassets/Contents.json
diff --git a/RileyLink/RileyLink.xcassets/LaunchImage.launchimage/Contents.json b/RileyLink/RileyLink.xcassets/LaunchImage.launchimage/Contents.json
new file mode 100644
index 000000000..5a2966687
--- /dev/null
+++ b/RileyLink/RileyLink.xcassets/LaunchImage.launchimage/Contents.json
@@ -0,0 +1,49 @@
+{
+ "images" : [
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "minimum-system-version" : "7.0",
+ "extent" : "full-screen",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "minimum-system-version" : "7.0",
+ "extent" : "full-screen",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "minimum-system-version" : "7.0",
+ "extent" : "full-screen",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "minimum-system-version" : "7.0",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "minimum-system-version" : "7.0",
+ "subtype" : "retina4",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "minimum-system-version" : "7.0",
+ "extent" : "full-screen",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/RileyLink/RileyLink.xcassets/RileyLink Tint.colorset/Contents.json b/RileyLink/RileyLink.xcassets/RileyLink Tint.colorset/Contents.json
new file mode 100644
index 000000000..bb0dcbefa
--- /dev/null
+++ b/RileyLink/RileyLink.xcassets/RileyLink Tint.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0.345",
+ "alpha" : "1.000",
+ "blue" : "0.839",
+ "green" : "0.337"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/RileyLink/RileyLink.xcassets/RileyLink.imageset/Contents.json b/RileyLink/RileyLink.xcassets/RileyLink.imageset/Contents.json
new file mode 100644
index 000000000..cfe31b855
--- /dev/null
+++ b/RileyLink/RileyLink.xcassets/RileyLink.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "RileyLink.pdf"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
\ No newline at end of file
diff --git a/RileyLink/RileyLink.xcassets/RileyLink.imageset/RileyLink.pdf b/RileyLink/RileyLink.xcassets/RileyLink.imageset/RileyLink.pdf
new file mode 100644
index 000000000..69cc898de
Binary files /dev/null and b/RileyLink/RileyLink.xcassets/RileyLink.imageset/RileyLink.pdf differ
diff --git a/RileyLink/RileyLinkRecord.h b/RileyLink/RileyLinkRecord.h
deleted file mode 100644
index defb93a72..000000000
--- a/RileyLink/RileyLinkRecord.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// RileyLinkRecord.h
-// RileyLink
-//
-// Created by Pete Schwamb on 7/28/15.
-// Copyright (c) 2015 Pete Schwamb. All rights reserved.
-//
-
-#import
-#import
-
-
-@interface RileyLinkRecord : NSManagedObject
-
-@property (nonatomic, retain) NSNumber * autoConnect;
-@property (nonatomic, retain) NSString * name;
-@property (nonatomic, retain) NSString * peripheralId;
-@property (nonatomic, retain) NSDate * firstSeenAt;
-
-@end
diff --git a/RileyLink/RileyLinkRecord.m b/RileyLink/RileyLinkRecord.m
deleted file mode 100644
index eaaf67311..000000000
--- a/RileyLink/RileyLinkRecord.m
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// RileyLinkRecord.m
-// RileyLink
-//
-// Created by Pete Schwamb on 7/28/15.
-// Copyright (c) 2015 Pete Schwamb. All rights reserved.
-//
-
-#import "RileyLinkRecord.h"
-
-
-@implementation RileyLinkRecord
-
-@dynamic autoConnect;
-@dynamic name;
-@dynamic peripheralId;
-@dynamic firstSeenAt;
-
-@end
diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard
deleted file mode 100644
index 3b7ef7574..000000000
--- a/RileyLink/Storyboard.storyboard
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/RileyLink/View Controllers/AuthenticationViewController.swift b/RileyLink/View Controllers/AuthenticationViewController.swift
deleted file mode 100644
index f73604b93..000000000
--- a/RileyLink/View Controllers/AuthenticationViewController.swift
+++ /dev/null
@@ -1,213 +0,0 @@
-//
-// AuthenticationViewController.swift
-// Loop
-//
-// Created by Nate Racklyeft on 7/2/16.
-// Copyright © 2016 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-
-
-class AuthenticationViewController: UITableViewController, IdentifiableClass, UITextFieldDelegate {
-
- typealias AuthenticationObserver = (_ authentication: T) -> Void
-
- var authenticationObserver: AuthenticationObserver?
-
- var authentication: T
-
- private var state: AuthenticationState = .empty {
- didSet {
- switch (oldValue, state) {
- case let (x, y) where x == y:
- break
- case (_, .verifying):
- let titleView = ValidatingIndicatorView(frame: CGRect.zero)
- UIView.animate(withDuration: 0.25, animations: {
- self.navigationItem.hidesBackButton = true
- self.navigationItem.titleView = titleView
- })
-
- tableView.reloadSections(IndexSet(integersIn: 0...1), with: .automatic)
- authentication.verify { [weak self] (success, error) in
- guard let strongSelf = self else {
- return
- }
-
- DispatchQueue.main.async {
- UIView.animate(withDuration: 0.25, animations: {
- strongSelf.navigationItem.titleView = nil
- strongSelf.navigationItem.hidesBackButton = false
- })
-
- if success {
- strongSelf.state = .authorized
- } else {
- if let error = error {
- strongSelf.presentAlertControllerWithError(error)
- }
-
- strongSelf.state = .unauthorized
- }
- }
- }
- case (_, .authorized), (_, .unauthorized):
- authenticationObserver?(authentication)
- tableView.reloadSections(IndexSet(integersIn: 0...1), with: .automatic)
- default:
- break
- }
- }
- }
-
- init(authentication: T) {
- self.authentication = authentication
-
- state = authentication.isAuthorized ? .authorized : .unauthorized
-
- super.init(style: .grouped)
-
- title = authentication.title
- }
-
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- tableView.register(AuthenticationTableViewCell.nib(), forCellReuseIdentifier: AuthenticationTableViewCell.className)
- tableView.register(ButtonTableViewCell.nib(), forCellReuseIdentifier: ButtonTableViewCell.className)
- }
-
- // MARK: - Table view data source
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return Section.count
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- switch Section(rawValue: section)! {
- case .credentials:
- switch state {
- case .authorized:
- return authentication.credentials.filter({ !$0.isSecret }).count
- default:
- return authentication.credentials.count
- }
- case .button:
- return 1
- }
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- switch Section(rawValue: indexPath.section)! {
- case .button:
- let cell = tableView.dequeueReusableCell(withIdentifier: ButtonTableViewCell.className, for: indexPath) as! ButtonTableViewCell
-
- switch state {
- case .authorized:
- cell.button.setTitle(LocalizedString("Delete Account", comment: "The title of the button to remove the credentials for a service"), for: UIControlState())
- cell.button.setTitleColor(UIColor.deleteColor, for: UIControlState())
- case .empty, .unauthorized, .verifying:
- cell.button.setTitle(LocalizedString("Add Account", comment: "The title of the button to add the credentials for a service"), for: UIControlState())
- cell.button.setTitleColor(nil, for: UIControlState())
- }
-
- if case .verifying = state {
- cell.button.isEnabled = false
- } else {
- cell.button.isEnabled = true
- }
-
- cell.button.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)
-
- return cell
- case .credentials:
- let cell = tableView.dequeueReusableCell(withIdentifier: AuthenticationTableViewCell.className, for: indexPath) as! AuthenticationTableViewCell
-
- let credential = authentication.credentials[indexPath.row]
-
- cell.titleLabel.text = credential.title
- cell.textField.tag = indexPath.row
- cell.textField.keyboardType = credential.keyboardType
- cell.textField.isSecureTextEntry = credential.isSecret
- cell.textField.returnKeyType = (indexPath.row < authentication.credentials.count - 1) ? .next : .done
- cell.textField.text = credential.value
- cell.textField.placeholder = credential.placeholder ?? LocalizedString("Required", comment: "The default placeholder string for a credential")
-
- cell.textField.delegate = self
-
- switch state {
- case .authorized, .verifying, .empty:
- cell.textField.isEnabled = false
- case .unauthorized:
- cell.textField.isEnabled = true
- }
-
- return cell
- }
- }
-
- private func validate() {
- state = .verifying
- }
-
- // MARK: - Actions
-
- @objc private func buttonPressed(_: AnyObject) {
- tableView.endEditing(false)
-
- switch state {
- case .authorized:
- authentication.reset()
- state = .unauthorized
- case .unauthorized:
- validate()
- default:
- break
- }
-
- }
-
- // MARK: - UITextFieldDelegate
-
- func textFieldDidEndEditing(_ textField: UITextField) {
- authentication.credentials[textField.tag].value = textField.text
- }
-
- func textFieldShouldReturn(_ textField: UITextField) -> Bool {
- if textField.returnKeyType == .done {
- textField.resignFirstResponder()
- } else {
- let point = tableView.convert(textField.frame.origin, from: textField.superview)
- if let indexPath = tableView.indexPathForRow(at: point),
- let cell = tableView.cellForRow(at: IndexPath(row: indexPath.row + 1, section: indexPath.section)) as? AuthenticationTableViewCell
- {
- cell.textField.becomeFirstResponder()
-
- validate()
- }
- }
-
- return true
- }
-}
-
-
-private enum Section: Int {
- case credentials
- case button
-
- static let count = 2
-}
-
-
-enum AuthenticationState {
- case empty
- case authorized
- case verifying
- case unauthorized
-}
diff --git a/RileyLink/View Controllers/MainViewController.swift b/RileyLink/View Controllers/MainViewController.swift
new file mode 100644
index 000000000..eadab0bcc
--- /dev/null
+++ b/RileyLink/View Controllers/MainViewController.swift
@@ -0,0 +1,195 @@
+//
+// MainViewController.swift
+// RileyLink
+//
+// Created by Pete Schwamb on 5/11/16.
+// Copyright © 2016 Pete Schwamb. All rights reserved.
+//
+import UIKit
+import MinimedKit
+import MinimedKitUI
+import RileyLinkBLEKit
+import RileyLinkKit
+import RileyLinkKitUI
+import LoopKit
+import LoopKitUI
+
+class MainViewController: RileyLinkSettingsViewController {
+
+ let deviceDataManager: DeviceDataManager
+
+ init(deviceDataManager: DeviceDataManager) {
+ self.deviceDataManager = deviceDataManager
+ let rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkDeviceProvider: deviceDataManager.rileyLinkConnectionManager.deviceProvider, rileyLinkConnectionManager: deviceDataManager.rileyLinkConnectionManager)
+
+ super.init(rileyLinkPumpManager: rileyLinkPumpManager, devicesSectionIndex: Section.rileyLinks.rawValue, style: .grouped)
+
+ self.title = NSLocalizedString("RileyLink Testing", comment: "Title for RileyLink Testing main view controller")
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ tableView.backgroundColor = UIColor.white
+ tableView.separatorStyle = .none
+ tableView.rowHeight = UITableViewAutomaticDimension
+ tableView.estimatedRowHeight = 44
+
+ tableView.sectionHeaderHeight = UITableViewAutomaticDimension
+ tableView.estimatedSectionHeaderHeight = 55
+
+ tableView.register(TextButtonTableViewCell.self, forCellReuseIdentifier: TextButtonTableViewCell.className)
+ tableView.register(SettingsImageTableViewCell.self, forCellReuseIdentifier: SettingsImageTableViewCell.className)
+
+ let rlImage = UIImage(named: "RileyLink", in: Bundle.main, compatibleWith: tableView.traitCollection)
+ let imageView = UIImageView(image: rlImage)
+ imageView.tintColor = UIColor.white
+ imageView.contentMode = .center
+ imageView.frame.size.height += 30 // feels right
+ imageView.backgroundColor = UIColor(named: "RileyLink Tint", in: Bundle.main, compatibleWith: tableView.traitCollection)
+ tableView.tableHeaderView = imageView
+
+ tableView.register(RileyLinkDeviceTableViewCell.self, forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className)
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ // Manually invoke the delegate for rows deselecting on appear
+ for indexPath in tableView.indexPathsForSelectedRows ?? [] {
+ _ = tableView(tableView, willDeselectRowAt: indexPath)
+ }
+
+ super.viewWillAppear(animated)
+ }
+
+ fileprivate enum Section: Int, CaseCountable {
+ case rileyLinks = 0
+ case pump
+ }
+
+ fileprivate enum PumpActionRow: Int, CaseCountable {
+ case addMinimedPump = 0
+ }
+
+ weak var rileyLinkManager: RileyLinkDeviceManager!
+
+ // MARK: Data Source
+
+ override func numberOfSections(in tableView: UITableView) -> Int {
+ return Section.count
+ }
+
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ switch Section(rawValue: section)! {
+ case .rileyLinks:
+ return super.tableView(tableView, numberOfRowsInSection: section)
+ case .pump:
+ if let _ = deviceDataManager.pumpManager {
+ return 1
+ } else {
+ return PumpActionRow.count
+ }
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell: UITableViewCell
+
+ switch(Section(rawValue: indexPath.section)!) {
+ case .rileyLinks:
+ return super.tableView(tableView, cellForRowAt: indexPath)
+ case .pump:
+ if let pumpManager = deviceDataManager.pumpManager {
+ cell = tableView.dequeueReusableCell(withIdentifier: SettingsImageTableViewCell.className, for: indexPath)
+ cell.imageView?.image = pumpManager.smallImage
+ cell.textLabel?.text = pumpManager.localizedTitle
+ cell.detailTextLabel?.text = nil
+ cell.accessoryType = .disclosureIndicator
+ } else {
+ switch(PumpActionRow(rawValue: indexPath.row)!) {
+ case .addMinimedPump:
+ cell = tableView.dequeueReusableCell(withIdentifier: TextButtonTableViewCell.className, for: indexPath)
+ cell.textLabel?.text = NSLocalizedString("Add Minimed Pump", comment: "Title text for button to set up a new minimed pump")
+ }
+ }
+ }
+ return cell
+ }
+
+ public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+ switch Section(rawValue: section)! {
+ case .rileyLinks:
+ return super.tableView(tableView, titleForHeaderInSection: section)
+ case .pump:
+ return NSLocalizedString("Pumps", comment: "Title text for section listing configured pumps")
+ }
+ }
+
+ public override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
+ switch Section(rawValue: section)! {
+ case .rileyLinks:
+ return super.tableView(tableView, viewForHeaderInSection: section)
+ case .pump:
+ return nil
+ }
+ }
+
+ public override func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
+ return devicesDataSource.tableView(tableView, estimatedHeightForHeaderInSection: section)
+ }
+
+ // MARK: - UITableViewDelegate
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let sender = tableView.cellForRow(at: indexPath)
+
+ switch Section(rawValue: indexPath.section)! {
+ case .rileyLinks:
+ let device = devicesDataSource.devices[indexPath.row]
+ let vc = RileyLinkDeviceTableViewController(device: device)
+ show(vc, sender: indexPath)
+ case .pump:
+ if let pumpManager = deviceDataManager.pumpManager {
+ let settings = pumpManager.settingsViewController()
+ show(settings, sender: sender)
+ } else {
+ var setupViewController: PumpManagerSetupViewController & UIViewController
+ switch PumpActionRow(rawValue: indexPath.row)! {
+ case .addMinimedPump:
+ setupViewController = UIStoryboard(name: "MinimedPumpManager", bundle: Bundle(for: MinimedPumpManagerSetupViewController.self)).instantiateViewController(withIdentifier: "DevelopmentPumpSetup") as! MinimedPumpManagerSetupViewController
+ }
+ if let rileyLinkManagerViewController = setupViewController as? RileyLinkManagerSetupViewController {
+ rileyLinkManagerViewController.rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkDeviceProvider: deviceDataManager.rileyLinkConnectionManager.deviceProvider)
+ }
+ setupViewController.setupDelegate = self
+ present(setupViewController, animated: true, completion: nil)
+ }
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
+ switch Section(rawValue: indexPath.section)! {
+ case .rileyLinks:
+ break
+ case .pump:
+ tableView.reloadSections(IndexSet([Section.pump.rawValue]), with: .none)
+ }
+
+ return indexPath
+ }
+}
+
+extension MainViewController: PumpManagerSetupViewControllerDelegate {
+ func pumpManagerSetupViewController(_ pumpManagerSetupViewController: PumpManagerSetupViewController, didSetUpPumpManager pumpManager: PumpManagerUI) {
+ deviceDataManager.pumpManager = pumpManager
+ show(pumpManager.settingsViewController(), sender: nil)
+ tableView.reloadSections(IndexSet([Section.pump.rawValue]), with: .none)
+ dismiss(animated: true, completion: nil)
+ }
+
+ func pumpManagerSetupViewControllerDidCancel(_ pumpManagerSetupViewController: PumpManagerSetupViewController) {
+ dismiss(animated: true, completion: nil)
+ }
+}
diff --git a/RileyLink/View Controllers/RadioSelectionTableViewController.swift b/RileyLink/View Controllers/RadioSelectionTableViewController.swift
deleted file mode 100644
index bd179917e..000000000
--- a/RileyLink/View Controllers/RadioSelectionTableViewController.swift
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// RadioSelectionTableViewController.swift
-// Loop
-//
-// Created by Nate Racklyeft on 8/26/16.
-// Copyright © 2016 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-import MinimedKit
-
-
-protocol RadioSelectionTableViewControllerDelegate: class {
- func radioSelectionTableViewControllerDidChangeSelectedIndex(_ controller: RadioSelectionTableViewController)
-}
-
-
-class RadioSelectionTableViewController: UITableViewController, IdentifiableClass {
-
- var options = [String]()
-
- var selectedIndex: Int? {
- didSet {
- if let oldValue = oldValue , oldValue != selectedIndex {
- tableView.cellForRow(at: IndexPath(row: oldValue, section: 0))?.accessoryType = .none
- }
-
- if let selectedIndex = selectedIndex , oldValue != selectedIndex {
- tableView.cellForRow(at: IndexPath(row: selectedIndex, section: 0))?.accessoryType = .checkmark
-
- delegate?.radioSelectionTableViewControllerDidChangeSelectedIndex(self)
- }
- }
- }
-
- var contextHelp: String?
-
- weak var delegate: RadioSelectionTableViewControllerDelegate?
-
- convenience init() {
- self.init(style: .grouped)
- }
-
- // MARK: - Table view data source
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return 1
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return options.count
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
-
- cell.textLabel?.text = options[indexPath.row]
- cell.accessoryType = selectedIndex == indexPath.row ? .checkmark : .none
-
- return cell
- }
-
- override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
- return contextHelp
- }
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- selectedIndex = indexPath.row
-
- tableView.deselectRow(at: indexPath, animated: true)
- }
-}
-
-
-extension RadioSelectionTableViewController {
- typealias T = RadioSelectionTableViewController
-
- static func pumpRegion(_ value: PumpRegion?) -> T {
- let vc = T()
-
- vc.selectedIndex = value?.rawValue
- vc.options = (0..<2).compactMap({ PumpRegion(rawValue: $0) }).map { String(describing: $0) }
- vc.contextHelp = LocalizedString("Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is NorthAmerica. If your model has an \"WW\" in it, then the region is WorldWide.", comment: "Instructions on selecting the pump region")
- return vc
- }
-}
diff --git a/RileyLink/View Controllers/RileyLinkListTableViewController.swift b/RileyLink/View Controllers/RileyLinkListTableViewController.swift
deleted file mode 100644
index c014ba92f..000000000
--- a/RileyLink/View Controllers/RileyLinkListTableViewController.swift
+++ /dev/null
@@ -1,172 +0,0 @@
-//
-// RileyLinkListTableViewController.swift
-// RileyLink
-//
-// Created by Pete Schwamb on 5/11/16.
-// Copyright © 2016 Pete Schwamb. All rights reserved.
-//
-
-import UIKit
-import MinimedKitUI
-import RileyLinkBLEKit
-import RileyLinkKit
-import RileyLinkKitUI
-
-
-class RileyLinkListTableViewController: UITableViewController {
-
- private lazy var numberFormatter = NumberFormatter()
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- tableView.register(RileyLinkDeviceTableViewCell.self, forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className)
-
- // Register for manager notifications
- NotificationCenter.default.addObserver(self, selector: #selector(reloadDevices), name: .ManagerDevicesDidChange, object: dataManager.rileyLinkManager)
-
- // Register for device notifications
- for name in [.DeviceConnectionStateDidChange, .DeviceRSSIDidChange, .DeviceNameDidChange] as [Notification.Name] {
- NotificationCenter.default.addObserver(self, selector: #selector(deviceDidUpdate(_:)), name: name, object: nil)
- }
-
- reloadDevices()
- }
-
- @objc private func reloadDevices() {
- self.dataManager.rileyLinkManager.getDevices { (devices) in
- DispatchQueue.main.async {
- self.devices = devices
- }
- }
- }
-
- @objc private func deviceDidUpdate(_ note: Notification) {
- DispatchQueue.main.async {
- if let device = note.object as? RileyLinkDevice, let index = self.devices.index(where: { $0 === device }) {
- if let rssi = note.userInfo?[RileyLinkDevice.notificationRSSIKey] as? Int {
- self.deviceRSSI[device.peripheralIdentifier] = rssi
- }
-
- if let cell = self.tableView.cellForRow(at: IndexPath(row: index, section: 0)) as? RileyLinkDeviceTableViewCell {
- cell.configureCellWithName(device.name,
- signal: self.numberFormatter.decibleString(from: self.deviceRSSI[device.peripheralIdentifier]),
- peripheralState: device.peripheralState
- )
- }
- }
- }
- }
-
- private var dataManager: DeviceDataManager {
- return DeviceDataManager.sharedManager
- }
-
- private var devices: [RileyLinkDevice] = [] {
- didSet {
- // Assume only appends are possible when count changes for algorithmic simplicity
- guard oldValue.count < devices.count else {
- tableView.reloadSections(IndexSet(integer: 0), with: .fade)
- return
- }
-
- tableView.beginUpdates()
-
- let insertedPaths = (oldValue.count.. IndexPath in
- return IndexPath(row: index, section: 0)
- }
- tableView.insertRows(at: insertedPaths, with: .automatic)
-
- tableView.endUpdates()
- }
- }
-
- private var deviceRSSI: [UUID: Int] = [:]
-
- var rssiFetchTimer: Timer? {
- willSet {
- rssiFetchTimer?.invalidate()
- }
- }
-
- @objc func updateRSSI() {
- for device in devices {
- device.readRSSI()
- }
- }
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
-
- dataManager.rileyLinkManager.setScanningEnabled(true)
-
- rssiFetchTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateRSSI), userInfo: nil, repeats: true)
-
- updateRSSI()
- }
-
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
-
- dataManager.rileyLinkManager.setScanningEnabled(false)
-
- rssiFetchTimer = nil
- }
-
- // MARK: Table view data source
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return 1
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return devices.count
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell: UITableViewCell
-
- let deviceCell = tableView.dequeueReusableCell(withIdentifier: RileyLinkDeviceTableViewCell.className) as! RileyLinkDeviceTableViewCell
-
- let device = devices[indexPath.row]
-
- deviceCell.configureCellWithName(
- device.name,
- signal: numberFormatter.decibleString(from: deviceRSSI[device.peripheralIdentifier]),
- peripheralState: device.peripheralState
- )
-
- deviceCell.connectSwitch?.addTarget(self, action: #selector(changeDeviceConnection(_:)), for: .valueChanged)
-
- cell = deviceCell
- return cell
- }
-
- @objc func changeDeviceConnection(_ connectSwitch: UISwitch) {
- let switchOrigin = connectSwitch.convert(CGPoint.zero, to: tableView)
-
- if let indexPath = tableView.indexPathForRow(at: switchOrigin) {
- let device = devices[indexPath.row]
-
- if connectSwitch.isOn {
- dataManager.connectToRileyLink(device)
- } else {
- dataManager.disconnectFromRileyLink(device)
- }
- }
- }
-
- // MARK: - UITableViewDelegate
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- guard let pumpOps = dataManager.pumpOps else {
- return
- }
- let device = devices[indexPath.row]
- let vc = RileyLinkMinimedDeviceTableViewController(
- device: device,
- deviceState: dataManager.deviceStates[device.peripheralIdentifier, default: DeviceState()],
- pumpOps: pumpOps)
- show(vc, sender: indexPath)
- }
-}
diff --git a/RileyLink/View Controllers/SettingsTableViewController.swift b/RileyLink/View Controllers/SettingsTableViewController.swift
deleted file mode 100644
index 0815b6283..000000000
--- a/RileyLink/View Controllers/SettingsTableViewController.swift
+++ /dev/null
@@ -1,242 +0,0 @@
-//
-// SettingsTableViewController.swift
-// RileyLink
-//
-// Created by Nathan Racklyeft on 8/29/15.
-// Copyright © 2015 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-import LoopKitUI
-import MinimedKit
-import RileyLinkKit
-import RileyLinkKitUI
-
-private let ConfigCellIdentifier = "ConfigTableViewCell"
-
-private let TapToSetString = LocalizedString("Tap to set", comment: "The empty-state text for a configuration value")
-
-
-extension TextFieldTableViewController: IdentifiableClass { }
-
-
-class SettingsTableViewController: UITableViewController, TextFieldTableViewControllerDelegate {
-
- fileprivate enum Section: Int {
- case about = 0
- case upload
- case configuration
-
- static let count = 3
- }
-
- fileprivate enum AboutRow: Int {
- case version = 0
-
- static let count = 1
- }
-
- fileprivate enum UploadRow: Int {
- case upload = 0
-
- static let count = 1
- }
-
- fileprivate enum ConfigurationRow: Int {
- case pumpID = 0
- case pumpRegion
- case nightscout
- case fetchCGM
- static let count = 4
- }
-
- fileprivate var dataManager: DeviceDataManager {
- return DeviceDataManager.sharedManager
- }
-
- // MARK: - UITableViewDataSource
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return Section.count
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- switch Section(rawValue: section)! {
- case .about:
- return AboutRow.count
- case .upload:
- return UploadRow.count
- case .configuration:
- return ConfigurationRow.count
- }
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell: UITableViewCell
-
- switch Section(rawValue: indexPath.section)! {
- case .about:
- switch AboutRow(rawValue: indexPath.row)! {
- case .version:
- let versionCell = UITableViewCell(style: .default, reuseIdentifier: "Version")
- versionCell.selectionStyle = .none
- let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")!
- versionCell.textLabel?.text = "RileyLink iOS v\(version)"
-
- return versionCell
- }
- case .upload:
- switch UploadRow(rawValue: indexPath.row)! {
- case .upload:
- let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell
-
- switchCell.`switch`?.isOn = Config.sharedInstance().uploadEnabled
- switchCell.titleLabel.text = LocalizedString("Upload To Nightscout", comment: "The title text for the nightscout upload enabled switch cell")
- switchCell.`switch`?.addTarget(self, action: #selector(uploadEnabledChanged(_:)), for: .valueChanged)
-
- return switchCell
- }
- case .configuration:
-
- switch ConfigurationRow(rawValue: indexPath.row)! {
- case .pumpID:
- let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)
- configCell.textLabel?.text = LocalizedString("Pump ID", comment: "The title text for the pump ID config value")
- configCell.detailTextLabel?.text = dataManager.pumpSettings?.pumpID ?? TapToSetString
- cell = configCell
- case .pumpRegion:
- let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)
- configCell.textLabel?.text = LocalizedString("Pump Region", comment: "The title text for the pump Region config value")
-
- if let pumpRegion = dataManager.pumpSettings?.pumpRegion {
- configCell.detailTextLabel?.text = String(describing: pumpRegion)
- } else {
- configCell.detailTextLabel?.text = nil
- }
-
- cell = configCell
- case .nightscout:
- let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath)
- let nightscoutService = dataManager.remoteDataManager.nightscoutService
-
- configCell.textLabel?.text = nightscoutService.title
- configCell.detailTextLabel?.text = nightscoutService.siteURL?.absoluteString ?? TapToSetString
- cell = configCell
- case .fetchCGM:
- let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell
-
- switchCell.`switch`?.isOn = Config.sharedInstance().fetchCGMEnabled
- switchCell.titleLabel.text = LocalizedString("Fetch CGM", comment: "The title text for the pull cgm Data cell")
- switchCell.`switch`?.addTarget(self, action: #selector(fetchCGMEnabledChanged(_:)), for: .valueChanged)
- cell = switchCell
- }
- }
- return cell
- }
-
- override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
- switch Section(rawValue: section)! {
- case .about:
- return LocalizedString("About", comment: "The title of the about section")
- case .upload:
- return nil
- case .configuration:
- return LocalizedString("Configuration", comment: "The title of the configuration section in settings")
- }
- }
-
- // MARK: - UITableViewDelegate
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- switch Section(rawValue: indexPath.section)! {
- case .configuration:
- let sender = tableView.cellForRow(at: indexPath)
-
- switch ConfigurationRow(rawValue: indexPath.row)! {
- case .pumpID:
- let vc = TextFieldTableViewController()
-
- vc.placeholder = LocalizedString("Enter the 6-digit pump ID", comment: "The placeholder text instructing users how to enter a pump ID")
- vc.value = dataManager.pumpSettings?.pumpID
-
- if let cell = tableView.cellForRow(at: indexPath) {
- vc.title = cell.textLabel?.text
- }
- vc.indexPath = indexPath
- vc.delegate = self
-
- show(vc, sender: indexPath)
- case .pumpRegion:
- let vc = RadioSelectionTableViewController.pumpRegion(dataManager.pumpSettings?.pumpRegion)
- vc.title = sender?.textLabel?.text
- vc.delegate = self
-
- show(vc, sender: sender)
- case .nightscout:
- let service = dataManager.remoteDataManager.nightscoutService
- let vc = AuthenticationViewController(authentication: service)
- vc.authenticationObserver = { [weak self] (service) in
- self?.dataManager.remoteDataManager.nightscoutService = service
-
- self?.tableView.reloadRows(at: [indexPath], with: .none)
- }
-
- show(vc, sender: indexPath)
- default:
- break
- }
- case .upload, .about:
- break
- }
- }
-
- override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
- switch Section(rawValue: section)! {
- case .upload, .configuration, .about:
- return nil
- }
- }
-
- // MARK: - Uploader management
-
- @objc func uploadEnabledChanged(_ sender: UISwitch) {
- Config.sharedInstance().uploadEnabled = sender.isOn
- }
-
- // MARK: - CGM Page Fetching Management
-
- @objc func fetchCGMEnabledChanged(_ sender: UISwitch) {
- Config.sharedInstance().fetchCGMEnabled = sender.isOn
- }
-
- // MARK: - TextFieldTableViewControllerDelegate
-
- func textFieldTableViewControllerDidEndEditing(_ controller: TextFieldTableViewController) {
- if let indexPath = controller.indexPath {
- switch ConfigurationRow(rawValue: indexPath.row)! {
- case .pumpID:
- dataManager.setPumpID(controller.value)
- default:
- break
- }
- }
-
- tableView.reloadData()
- }
-
- func textFieldTableViewControllerDidReturn(_ controller: TextFieldTableViewController) {
-
- }
-}
-
-
-extension SettingsTableViewController: RadioSelectionTableViewControllerDelegate {
- func radioSelectionTableViewControllerDidChangeSelectedIndex(_ controller: RadioSelectionTableViewController) {
- if let selectedIndex = controller.selectedIndex, let pumpRegion = PumpRegion(rawValue: selectedIndex) {
- dataManager.setPumpRegion(pumpRegion)
-
- tableView.reloadRows(at: [IndexPath(row: ConfigurationRow.pumpRegion.rawValue, section: Section.configuration.rawValue)], with: .none)
- }
- }
-}
-
diff --git a/RileyLink/Views/AuthenticationTableViewCell.swift b/RileyLink/Views/AuthenticationTableViewCell.swift
deleted file mode 100644
index bd57c1b1b..000000000
--- a/RileyLink/Views/AuthenticationTableViewCell.swift
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// AuthenticationTableViewCell.swift
-// Loop
-//
-// Created by Nate Racklyeft on 7/2/16.
-// Copyright © 2016 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-
-class AuthenticationTableViewCell: UITableViewCell, NibLoadable {
-
- @IBOutlet weak var titleLabel: UILabel!
-
- @IBOutlet weak var textField: UITextField!
-
- override func setSelected(_ selected: Bool, animated: Bool) {
- super.setSelected(selected, animated: animated)
-
- if selected {
- textField.becomeFirstResponder()
- }
- }
-
- override func prepareForReuse() {
- super.prepareForReuse()
-
- textField.delegate = nil
- }
-
-}
diff --git a/RileyLink/Views/AuthenticationTableViewCell.xib b/RileyLink/Views/AuthenticationTableViewCell.xib
deleted file mode 100644
index 8114146a9..000000000
--- a/RileyLink/Views/AuthenticationTableViewCell.xib
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/RileyLink/Views/ButtonTableViewCell.swift b/RileyLink/Views/ButtonTableViewCell.swift
deleted file mode 100644
index 46b975630..000000000
--- a/RileyLink/Views/ButtonTableViewCell.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// ButtonTableViewCell.swift
-// Loop
-//
-// Created by Nate Racklyeft on 7/2/16.
-// Copyright © 2016 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-
-class ButtonTableViewCell: UITableViewCell, NibLoadable {
-
- @IBOutlet weak var button: UIButton!
-
- override func prepareForReuse() {
- super.prepareForReuse()
-
- button.removeTarget(nil, action: nil, for: .touchUpInside)
- }
-}
diff --git a/RileyLink/Views/ButtonTableViewCell.xib b/RileyLink/Views/ButtonTableViewCell.xib
deleted file mode 100644
index f1e8f865d..000000000
--- a/RileyLink/Views/ButtonTableViewCell.xib
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/RileyLink/Views/RileyLinkDeviceTableViewCell.swift b/RileyLink/Views/RileyLinkDeviceTableViewCell.swift
deleted file mode 100644
index b296c587d..000000000
--- a/RileyLink/Views/RileyLinkDeviceTableViewCell.swift
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// RileyLinkDeviceTableViewCell.swift
-// RileyLink
-//
-// Created by Nathan Racklyeft on 5/22/16.
-// Copyright © 2016 Pete Schwamb. All rights reserved.
-//
-
-import UIKit
-import RileyLinkKitUI
-
-extension RileyLinkDeviceTableViewCell: IdentifiableClass { }
diff --git a/RileyLink/Views/SettingsImageTableViewCell.swift b/RileyLink/Views/SettingsImageTableViewCell.swift
new file mode 100644
index 000000000..505440bef
--- /dev/null
+++ b/RileyLink/Views/SettingsImageTableViewCell.swift
@@ -0,0 +1,53 @@
+//
+// SettingsImageTableViewCell.swift
+// Loop
+//
+// Copyright © 2018 LoopKit Authors. All rights reserved.
+//
+
+import UIKit
+
+
+class SettingsImageTableViewCell: UITableViewCell {
+ override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
+ super.init(style: .default, reuseIdentifier: reuseIdentifier)
+
+ setup()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ setup()
+ }
+
+ private func setup() {
+ guard let textLabel = textLabel, let imageView = imageView else {
+ return
+ }
+
+ textLabel.adjustsFontForContentSizeCategory = true
+ textLabel.font = UIFont.preferredFont(forTextStyle: .body)
+ textLabel.translatesAutoresizingMaskIntoConstraints = false
+ imageView.translatesAutoresizingMaskIntoConstraints = false
+
+ let parent = contentView.layoutMarginsGuide
+ NSLayoutConstraint.activate([
+ imageView.leadingAnchor.constraint(equalTo: parent.leadingAnchor),
+ imageView.topAnchor.constraint(greaterThanOrEqualTo: parent.topAnchor),
+ parent.bottomAnchor.constraint(greaterThanOrEqualTo: imageView.bottomAnchor),
+ imageView.centerYAnchor.constraint(equalTo: parent.centerYAnchor),
+ textLabel.leadingAnchor.constraintEqualToSystemSpacingAfter(imageView.trailingAnchor, multiplier: 2),
+ textLabel.topAnchor.constraint(greaterThanOrEqualTo: parent.topAnchor),
+ parent.bottomAnchor.constraint(greaterThanOrEqualTo: textLabel.bottomAnchor),
+ parent.trailingAnchor.constraint(equalTo: textLabel.trailingAnchor),
+ textLabel.centerYAnchor.constraint(equalTo: parent.centerYAnchor)
+ ])
+ }
+
+ override func prepareForReuse() {
+ super.prepareForReuse()
+
+ imageView?.image = nil
+ }
+}
diff --git a/RileyLink/Views/SwitchTableViewCell.swift b/RileyLink/Views/SwitchTableViewCell.swift
deleted file mode 100644
index 3e2a739e8..000000000
--- a/RileyLink/Views/SwitchTableViewCell.swift
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// SwitchTableViewCell.swift
-// Naterade
-//
-// Created by Nathan Racklyeft on 3/13/16.
-// Copyright © 2016 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-import RileyLinkKit
-
-class SwitchTableViewCell: UITableViewCell, IdentifiableClass {
-
- @IBOutlet weak var titleLabel: UILabel!
-
- @IBOutlet var `switch`: UISwitch?
-
- override func prepareForReuse() {
- super.prepareForReuse()
-
- `switch`?.removeTarget(nil, action: nil, for: .valueChanged)
- }
-
-}
diff --git a/RileyLink/Views/ValidatingIndicatorView.swift b/RileyLink/Views/ValidatingIndicatorView.swift
deleted file mode 100644
index 91765a2d8..000000000
--- a/RileyLink/Views/ValidatingIndicatorView.swift
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// ValidatingIndicatorView.swift
-// Loop
-//
-// Created by Nate Racklyeft on 7/2/16.
-// Copyright © 2016 Nathan Racklyeft. All rights reserved.
-//
-
-import UIKit
-
-private let Margin: CGFloat = 8
-
-
-class ValidatingIndicatorView: UIView {
-
- let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
-
- let label = UILabel()
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- label.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
- label.text = LocalizedString("Verifying", comment: "Label indicating validation is occurring")
- label.sizeToFit()
-
- addSubview(indicatorView)
- addSubview(label)
-
- self.frame.size = intrinsicContentSize
-
- setNeedsLayout()
-
- indicatorView.startAnimating()
- }
-
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- override func layoutSubviews() {
- super.layoutSubviews()
-
- // Center the label in the bounds so it appears aligned, then let the indicator view hang from the left side
- label.frame = bounds
- indicatorView.center.y = bounds.midY
- indicatorView.frame.origin.x = -indicatorView.frame.size.width - Margin
- }
-
- override var intrinsicContentSize : CGSize {
- return label.intrinsicContentSize
- }
-}
diff --git a/RileyLinkBLEKit/Command.swift b/RileyLinkBLEKit/Command.swift
index 542fcd243..c011d10bd 100644
--- a/RileyLinkBLEKit/Command.swift
+++ b/RileyLinkBLEKit/Command.swift
@@ -200,6 +200,35 @@ struct UpdateRegister: Command {
}
}
+struct ReadRegister: Command {
+ typealias ResponseType = ReadRegisterResponse
+
+ enum Response: UInt8 {
+ case success = 1
+ case invalidRegister = 2
+ }
+
+ let address: CC111XRegister
+ let firmwareVersion: RadioFirmwareVersion
+
+ init(_ address: CC111XRegister, firmwareVersion: RadioFirmwareVersion) {
+ self.address = address
+ self.firmwareVersion = firmwareVersion
+ }
+
+ var data: Data {
+ var data = Data(bytes: [
+ RileyLinkCommand.readRegister.rawValue,
+ address.rawValue,
+ ])
+ if firmwareVersion.needsExtraByteForReadRegisterCommand {
+ data.append(address.rawValue)
+ }
+ return data
+ }
+}
+
+
struct SetModeRegisters: Command {
typealias ResponseType = UpdateRegisterResponse
diff --git a/RileyLinkBLEKit/CommandSession.swift b/RileyLinkBLEKit/CommandSession.swift
index 3686f7e50..75e5e0055 100644
--- a/RileyLinkBLEKit/CommandSession.swift
+++ b/RileyLinkBLEKit/CommandSession.swift
@@ -128,6 +128,23 @@ public struct CommandSession {
_ = try writeCommand(command, timeout: 0)
}
+ /// - Throws: RileyLinkDeviceError
+ public func readRegister(_ address: CC111XRegister) throws -> UInt8 {
+ guard firmwareVersion.supportsReadRegister else {
+ throw RileyLinkDeviceError.unsupportedCommand(RileyLinkCommand.readRegister)
+ }
+
+ let command = ReadRegister(address, firmwareVersion: firmwareVersion)
+ let response: ReadRegisterResponse = try writeCommand(command, timeout: 0)
+
+ guard response.code == .success else {
+ throw RileyLinkDeviceError.invalidInput("Unsupported register: \(String(describing: address))")
+ }
+
+ return response.value
+ }
+
+
/// - Throws: RileyLinkDeviceError
public func enableCCLEDs() throws {
let enableBlue = SetLEDMode(.blue, mode: .auto)
@@ -142,13 +159,24 @@ public struct CommandSession {
public func setBaseFrequency(_ frequency: Measurement) throws {
let val = Int(
frequency.converted(to: .hertz).value /
- (CommandSession.xtalFrequency / pow(2, 16)).converted(to: .hertz
- ).value)
+ (CommandSession.xtalFrequency / pow(2, 16)).converted(to: .hertz).value)
try updateRegister(.freq0, value: UInt8(val & 0xff))
try updateRegister(.freq1, value: UInt8((val >> 8) & 0xff))
try updateRegister(.freq2, value: UInt8((val >> 16) & 0xff))
}
+
+ public func readBaseFrequency() throws -> Measurement {
+ let freq0 = try readRegister(.freq0)
+ let freq1 = try readRegister(.freq1)
+ let freq2 = try readRegister(.freq2)
+
+ let value = Double(UInt32(freq0) + (UInt32(freq1) << 8) + (UInt32(freq2) << 16))
+
+ let frequency = value * (CommandSession.xtalFrequency / pow(2, 16)).converted(to: .hertz).value
+
+ return Measurement(value: frequency, unit: .hertz).converted(to: .megahertz)
+ }
/// Sends data to the pump, listening for a reply
///
diff --git a/RileyLinkBLEKit/Info.plist b/RileyLinkBLEKit/Info.plist
index f936f8d95..f841d8f2c 100644
--- a/RileyLinkBLEKit/Info.plist
+++ b/RileyLinkBLEKit/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift
index 4873e1d33..f3c671c5b 100644
--- a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift
+++ b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift
@@ -216,15 +216,16 @@ extension PeripheralManager {
let value = try command.writableData()
- log.debug("RL Send: %@", value.hexadecimalString)
switch responseType {
case .single:
+ log.debug("RL Send (single): %@", value.hexadecimalString)
return try writeCommand(value,
for: characteristic,
timeout: timeout
)
case .buffered:
+ log.debug("RL Send (buffered): %@", value.hexadecimalString)
return try writeLegacyCommand(value,
for: characteristic,
timeout: timeout,
@@ -249,7 +250,7 @@ extension PeripheralManager {
let value = try command.writableData()
- log.debug("RL Send: %@", value.hexadecimalString)
+ log.debug("RL Send (no response expected): %@", value.hexadecimalString)
do {
try writeValue(value, for: characteristic, type: .withResponse, timeout: timeout)
diff --git a/RileyLinkBLEKit/RadioFirmwareVersion.swift b/RileyLinkBLEKit/RadioFirmwareVersion.swift
index 34e959fae..2a1668be6 100644
--- a/RileyLinkBLEKit/RadioFirmwareVersion.swift
+++ b/RileyLinkBLEKit/RadioFirmwareVersion.swift
@@ -77,13 +77,31 @@ extension RadioFirmwareVersion {
}
var needsExtraByteForUpdateRegisterCommand: Bool {
+ // Fixed in 2.2
return !atLeastV2
}
-
+
+ var needsExtraByteForReadRegisterCommand: Bool {
+ // Fixed in 2.3
+ guard components.count >= 2 else {
+ return true;
+ }
+ let major = components[0]
+ let minor = components[1]
+ return major < 2 || (major == 2 && minor <= 2)
+ }
+
var supportsRileyLinkStatistics: Bool {
return atLeastV2_2
}
+ var supportsCustomPreamble: Bool {
+ return atLeastV2
+ }
+
+ var supportsReadRegister: Bool {
+ return atLeastV2
+ }
}
diff --git a/RileyLinkBLEKit/Response.swift b/RileyLinkBLEKit/Response.swift
index 0d576be95..2c5751da3 100644
--- a/RileyLinkBLEKit/Response.swift
+++ b/RileyLinkBLEKit/Response.swift
@@ -42,6 +42,28 @@ struct CodeResponse: Response {
}
}
+struct ReadRegisterResponse: Response {
+ let code: ResponseCode
+ let value: UInt8
+
+ init?(data: Data) {
+ guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
+ return nil
+ }
+
+ self.init(code: code, value: data[data.startIndex.advanced(by: 1)])
+ }
+
+ init?(legacyData data: Data) {
+ self.init(code: .success, value: data[0])
+ }
+
+ private init?(code: ResponseCode, value: UInt8) {
+ self.code = code
+ self.value = value
+ }
+}
+
struct UpdateRegisterResponse: Response {
let code: ResponseCode
diff --git a/RileyLinkBLEKit/RileyLinkConnectionManager.swift b/RileyLinkBLEKit/RileyLinkConnectionManager.swift
new file mode 100644
index 000000000..661f899fb
--- /dev/null
+++ b/RileyLinkBLEKit/RileyLinkConnectionManager.swift
@@ -0,0 +1,99 @@
+//
+// RileyLinkConnectionManager.swift
+// RileyLinkBLEKit
+//
+// Created by Pete Schwamb on 8/16/18.
+// Copyright © 2018 Pete Schwamb. All rights reserved.
+//
+
+import Foundation
+
+public protocol RileyLinkConnectionManagerDelegate : class {
+ func rileyLinkConnectionManager(_ rileyLinkConnectionManager: RileyLinkConnectionManager, didChange state: RileyLinkConnectionManagerState)
+}
+
+public class RileyLinkConnectionManager {
+
+ public typealias RawStateValue = [String : Any]
+
+ /// The current, serializable state of the manager
+ public var rawState: RawStateValue {
+ return state.rawValue
+ }
+
+ public private(set) var state: RileyLinkConnectionManagerState {
+ didSet {
+ delegate?.rileyLinkConnectionManager(self, didChange: state)
+ }
+ }
+
+ public var deviceProvider: RileyLinkDeviceProvider {
+ return rileyLinkDeviceManager
+ }
+
+ public weak var delegate: RileyLinkConnectionManagerDelegate?
+
+ private let rileyLinkDeviceManager: RileyLinkDeviceManager
+
+ private var autoConnectIDs: Set {
+ get {
+ return state.autoConnectIDs
+ }
+ set {
+ state.autoConnectIDs = newValue
+ }
+ }
+
+ public init(state: RileyLinkConnectionManagerState) {
+ self.rileyLinkDeviceManager = RileyLinkDeviceManager(autoConnectIDs: state.autoConnectIDs)
+ self.state = state
+ }
+
+ public init(autoConnectIDs: Set) {
+ self.rileyLinkDeviceManager = RileyLinkDeviceManager(autoConnectIDs: autoConnectIDs)
+ self.state = RileyLinkConnectionManagerState(autoConnectIDs: autoConnectIDs)
+ }
+
+ public convenience init?(rawValue: RawStateValue) {
+ if let state = RileyLinkConnectionManagerState(rawValue: rawValue) {
+ self.init(state: state)
+ } else {
+ return nil
+ }
+ }
+
+ public var connectingCount: Int {
+ return self.autoConnectIDs.count
+ }
+
+ public func shouldConnect(to deviceID: String) -> Bool {
+ return self.autoConnectIDs.contains(deviceID)
+ }
+
+ public func connect(_ device: RileyLinkDevice) {
+ autoConnectIDs.insert(device.peripheralIdentifier.uuidString)
+ rileyLinkDeviceManager.connect(device)
+ }
+
+ public func disconnect(_ device: RileyLinkDevice) {
+ autoConnectIDs.remove(device.peripheralIdentifier.uuidString)
+ rileyLinkDeviceManager.disconnect(device)
+ }
+
+ public func setScanningEnabled(_ enabled: Bool) {
+ rileyLinkDeviceManager.setScanningEnabled(enabled)
+ }
+}
+
+public protocol RileyLinkDeviceProvider: class {
+ func getDevices(_ completion: @escaping (_ devices: [RileyLinkDevice]) -> Void)
+ var idleListeningEnabled: Bool { get }
+ var timerTickEnabled: Bool { get set }
+ func deprioritize(_ device: RileyLinkDevice, completion: (() -> Void)?)
+ func assertIdleListening(forcingRestart: Bool)
+ var idleListeningState: RileyLinkDevice.IdleListeningState { get set }
+
+ var debugDescription: String { get }
+}
+
+extension RileyLinkDeviceManager: RileyLinkDeviceProvider {}
diff --git a/RileyLinkBLEKit/RileyLinkConnectionManagerState.swift b/RileyLinkBLEKit/RileyLinkConnectionManagerState.swift
new file mode 100644
index 000000000..25a22dcfa
--- /dev/null
+++ b/RileyLinkBLEKit/RileyLinkConnectionManagerState.swift
@@ -0,0 +1,39 @@
+//
+// RileyLinkConnectionManagerState.swift
+// RileyLinkBLEKit
+//
+// Created by Pete Schwamb on 8/21/18.
+// Copyright © 2018 Pete Schwamb. All rights reserved.
+//
+
+import Foundation
+
+public struct RileyLinkConnectionManagerState: RawRepresentable, Equatable {
+
+ public typealias RawValue = RileyLinkConnectionManager.RawStateValue
+
+ public var autoConnectIDs: Set
+
+ public init(autoConnectIDs: Set) {
+ self.autoConnectIDs = autoConnectIDs
+ }
+
+ public init?(rawValue: RileyLinkConnectionManager.RawStateValue) {
+ guard
+ let autoConnectIDs = rawValue["autoConnectIDs"] as? [String]
+ else {
+ return nil
+ }
+
+ self.init(autoConnectIDs: Set(autoConnectIDs))
+ }
+
+ public var rawValue: RawValue {
+ return [
+ "autoConnectIDs": Array(autoConnectIDs),
+ ]
+ }
+
+
+
+}
diff --git a/RileyLinkBLEKit/RileyLinkDevice.swift b/RileyLinkBLEKit/RileyLinkDevice.swift
index e56286c76..6062c96d6 100644
--- a/RileyLinkBLEKit/RileyLinkDevice.swift
+++ b/RileyLinkBLEKit/RileyLinkDevice.swift
@@ -267,6 +267,7 @@ extension RileyLinkDevice {
extension RileyLinkDevice: PeripheralManagerDelegate {
// This is called from the central's queue
func peripheralManager(_ manager: PeripheralManager, didUpdateValueFor characteristic: CBCharacteristic) {
+ log.debug("Did UpdateValueFor %@", characteristic)
switch MainServiceCharacteristicUUID(rawValue: characteristic.uuid.uuidString) {
case .data?:
guard let value = characteristic.value, value.count > 0 else {
diff --git a/RileyLinkBLEKit/RileyLinkDeviceManager.swift b/RileyLinkBLEKit/RileyLinkDeviceManager.swift
index 0480dc25f..e536bc028 100644
--- a/RileyLinkBLEKit/RileyLinkDeviceManager.swift
+++ b/RileyLinkBLEKit/RileyLinkDeviceManager.swift
@@ -81,6 +81,12 @@ public class RileyLinkDeviceManager: NSObject {
// MARK: - Connecting
extension RileyLinkDeviceManager {
+ public func getAutoConnectIDs(_ completion: @escaping (_ autoConnectIDs: Set) -> Void) {
+ centralQueue.async {
+ completion(self.autoConnectIDs)
+ }
+ }
+
public func connect(_ device: RileyLinkDevice) {
centralQueue.async {
self.autoConnectIDs.insert(device.manager.peripheral.identifier.uuidString)
@@ -167,7 +173,7 @@ extension RileyLinkDeviceManager {
}
}
- public func deprioritize(_ device: RileyLinkDevice, _ completion: (() -> Void)? = nil) {
+ public func deprioritize(_ device: RileyLinkDevice, completion: (() -> Void)? = nil) {
centralQueue.async {
self.devices.deprioritize(device)
completion?()
@@ -309,3 +315,8 @@ extension RileyLinkDeviceManager {
extension Notification.Name {
public static let ManagerDevicesDidChange = Notification.Name("com.rileylink.RileyLinkBLEKit.DevicesDidChange")
}
+
+extension RileyLinkDeviceManager {
+ public static let autoConnectIDsStateKey = "com.rileylink.RileyLinkBLEKit.AutoConnectIDs"
+}
+
diff --git a/RileyLinkBLEKitTests/Info.plist b/RileyLinkBLEKitTests/Info.plist
index 12db38e68..499029a0a 100644
--- a/RileyLinkBLEKitTests/Info.plist
+++ b/RileyLinkBLEKitTests/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleVersion
1
diff --git a/RileyLinkKit/Info.plist b/RileyLinkKit/Info.plist
index 0de69c100..241ef8699 100644
--- a/RileyLinkKit/Info.plist
+++ b/RileyLinkKit/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift
index 6df0e151b..34b39ad60 100644
--- a/RileyLinkKit/PumpOpsSession.swift
+++ b/RileyLinkKit/PumpOpsSession.swift
@@ -711,15 +711,6 @@ extension PumpOpsSession {
/// - PumpOpsError.unexpectedResponse
/// - PumpOpsError.unknownResponse
public func changeWatchdogMarriageProfile(_ watchdogID: Data) throws {
- try setRXFilterMode(.wide)
- defer {
- do {
- try configureRadio(for: settings.pumpRegion)
- } catch {
- // Best effort resetting radio filter mode
- }
- }
-
let commandTimeout = TimeInterval(seconds: 30)
// Wait for the pump to start polling
@@ -963,8 +954,11 @@ extension PumpOpsSession {
do {
pageData = try getHistoryPage(pageNum)
- } catch PumpOpsError.pumpError {
- break pages
+ } catch PumpCommandError.arguments(let error) {
+ if case PumpOpsError.pumpError(.pageDoesNotExist) = error {
+ return (events, pumpModel)
+ }
+ throw PumpCommandError.arguments(error)
}
var idx = 0
diff --git a/RileyLinkKit/RileyLinkDeviceManager.swift b/RileyLinkKit/RileyLinkDeviceManager.swift
index c1de5fa5c..8fafc5b4e 100644
--- a/RileyLinkKit/RileyLinkDeviceManager.swift
+++ b/RileyLinkKit/RileyLinkDeviceManager.swift
@@ -7,7 +7,7 @@
import RileyLinkBLEKit
-extension RileyLinkDeviceManager {
+extension RileyLinkDeviceProvider {
public func firstConnectedDevice(_ completion: @escaping (_ device: RileyLinkDevice?) -> Void) {
getDevices { (devices) in
completion(devices.firstConnected)
diff --git a/RileyLinkKit/RileyLinkPumpManager.swift b/RileyLinkKit/RileyLinkPumpManager.swift
index 9bdd4b661..3eb8b6e25 100644
--- a/RileyLinkKit/RileyLinkPumpManager.swift
+++ b/RileyLinkKit/RileyLinkPumpManager.swift
@@ -7,33 +7,29 @@
import RileyLinkBLEKit
-
open class RileyLinkPumpManager {
- public init(rileyLinkPumpManagerState: RileyLinkPumpManagerState, rileyLinkManager: RileyLinkDeviceManager? = nil) {
- lockedRileyLinkPumpManagerState = Locked(rileyLinkPumpManagerState)
-
- self.rileyLinkManager = rileyLinkManager ?? RileyLinkDeviceManager(autoConnectIDs: rileyLinkPumpManagerState.connectedPeripheralIDs)
-
+
+ public init(rileyLinkDeviceProvider: RileyLinkDeviceProvider,
+ rileyLinkConnectionManager: RileyLinkConnectionManager? = nil) {
+
+ self.rileyLinkDeviceProvider = rileyLinkDeviceProvider
+ self.rileyLinkConnectionManager = rileyLinkConnectionManager
+
// Listen for device notifications
NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkPacketNotification(_:)), name: .DevicePacketReceived, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkTimerTickNotification(_:)), name: .DeviceTimerDidTick, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(deviceStateDidChange(_:)), name: .DeviceStateDidChange, object: nil)
}
-
- /// Manages all the RileyLinks
- public let rileyLinkManager: RileyLinkDeviceManager
-
- open var rileyLinkPumpManagerState: RileyLinkPumpManagerState {
- get {
- return lockedRileyLinkPumpManagerState.value
- }
- set {
- lockedRileyLinkPumpManagerState.value = newValue
- }
- }
- private let lockedRileyLinkPumpManagerState: Locked
-
- // TODO: Eveluate if this is necessary
+
+ /// Manages all the RileyLinks - access to management is optional
+ public let rileyLinkConnectionManager: RileyLinkConnectionManager?
+
+ open var rileyLinkConnectionManagerState: RileyLinkConnectionManagerState?
+
+ /// Access to rileylink devices
+ public let rileyLinkDeviceProvider: RileyLinkDeviceProvider
+
+ // TODO: Evaluate if this is necessary
public let queue = DispatchQueue(label: "com.loopkit.RileyLinkPumpManager", qos: .utility)
/// Isolated to queue
@@ -57,16 +53,15 @@ open class RileyLinkPumpManager {
open var debugDescription: String {
return [
"## RileyLinkPumpManager",
- "rileyLinkPumpManagerState: \(String(reflecting: rileyLinkPumpManagerState))",
+ "rileyLinkConnectionManager: \(String(reflecting: rileyLinkConnectionManager))",
"lastTimerTick: \(String(describing: lastTimerTick))",
"deviceStates: \(String(reflecting: deviceStates))",
"",
- String(reflecting: rileyLinkManager),
+ String(reflecting: rileyLinkDeviceProvider),
].joined(separator: "\n")
}
}
-
// MARK: - RileyLink Updates
extension RileyLinkPumpManager {
@objc private func deviceStateDidChange(_ note: Notification) {
@@ -111,14 +106,22 @@ extension RileyLinkPumpManager {
self.deviceTimerDidTick(device)
}
}
-
+
open func connectToRileyLink(_ device: RileyLinkDevice) {
- rileyLinkPumpManagerState.connectedPeripheralIDs.insert(device.peripheralIdentifier.uuidString)
- rileyLinkManager.connect(device)
+ rileyLinkConnectionManager?.connect(device)
}
open func disconnectFromRileyLink(_ device: RileyLinkDevice) {
- rileyLinkPumpManagerState.connectedPeripheralIDs.remove(device.peripheralIdentifier.uuidString)
- rileyLinkManager.disconnect(device)
+ rileyLinkConnectionManager?.disconnect(device)
}
+
}
+
+// MARK: - RileyLinkConnectionManagerDelegate
+extension RileyLinkPumpManager: RileyLinkConnectionManagerDelegate {
+ public func rileyLinkConnectionManager(_ rileyLinkConnectionManager: RileyLinkConnectionManager, didChange state: RileyLinkConnectionManagerState) {
+ self.rileyLinkConnectionManagerState = state
+ }
+}
+
+
diff --git a/RileyLinkKit/RileyLinkPumpManagerState.swift b/RileyLinkKit/RileyLinkPumpManagerState.swift
deleted file mode 100644
index 95de3b7c5..000000000
--- a/RileyLinkKit/RileyLinkPumpManagerState.swift
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// RileyLinkPumpManagerState.swift
-// Loop
-//
-// Copyright © 2018 LoopKit Authors. All rights reserved.
-//
-
-import Foundation
-import LoopKit
-
-
-public struct RileyLinkPumpManagerState: RawRepresentable, Equatable {
- public typealias RawValue = PumpManager.RawStateValue
-
- public var connectedPeripheralIDs: Set
-
- public init(connectedPeripheralIDs: Set) {
- self.connectedPeripheralIDs = connectedPeripheralIDs
- }
-
- public init?(rawValue: RawValue) {
- guard let connectedPeripheralIDs = rawValue["connectedPeripheralIDs"] as? [String] else {
- return nil
- }
-
- self.init(connectedPeripheralIDs: Set(connectedPeripheralIDs))
- }
-
- public var rawValue: RawValue {
- return [
- "connectedPeripheralIDs": Array(connectedPeripheralIDs)
- ]
- }
-}
-
-
-extension RileyLinkPumpManagerState: CustomDebugStringConvertible {
- public var debugDescription: String {
- return [
- "## RileyLinkPumpManagerState",
- "connectedPeripheralIDs: \(connectedPeripheralIDs)",
- ].joined(separator: "\n")
- }
-}
diff --git a/RileyLinkKitTests/Info.plist b/RileyLinkKitTests/Info.plist
index 5a6398fbf..9b0436e59 100644
--- a/RileyLinkKitTests/Info.plist
+++ b/RileyLinkKitTests/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion
diff --git a/RileyLinkKitUI/Info.plist b/RileyLinkKitUI/Info.plist
index f936f8d95..f841d8f2c 100644
--- a/RileyLinkKitUI/Info.plist
+++ b/RileyLinkKitUI/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift
index a0489ce39..a4a051f0d 100644
--- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift
+++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift
@@ -30,22 +30,41 @@ public class RileyLinkDeviceTableViewController: UITableViewController {
cellForRow(.version)?.detailTextLabel?.text = firmwareVersion
}
}
-
- private var lastIdle: Date? {
+
+ private var uptime: TimeInterval? {
didSet {
guard isViewLoaded else {
return
}
-
- cellForRow(.idleStatus)?.setDetailDate(lastIdle, formatter: dateFormatter)
+
+ cellForRow(.uptime)?.setDetailAge(uptime)
}
}
+ private var frequency: Measurement? {
+ didSet {
+ guard isViewLoaded else {
+ return
+ }
+
+ cellForRow(.frequency)?.setDetailFrequency(frequency, formatter: frequencyFormatter)
+ }
+ }
+
var rssiFetchTimer: Timer? {
willSet {
rssiFetchTimer?.invalidate()
}
}
+
+ private lazy var frequencyFormatter: MeasurementFormatter = {
+ let formatter = MeasurementFormatter()
+
+ formatter.numberFormatter = decimalFormatter
+
+ return formatter
+ }()
+
private var appeared = false
@@ -77,11 +96,36 @@ public class RileyLinkDeviceTableViewController: UITableViewController {
func updateDeviceStatus() {
device.getStatus { (status) in
DispatchQueue.main.async {
- self.lastIdle = status.lastIdle
self.firmwareVersion = status.firmwareDescription
}
}
}
+
+ func updateUptime() {
+ device.runSession(withName: "Get stats for uptime") { (session) in
+ do {
+ let statistics = try session.getRileyLinkStatistics()
+ DispatchQueue.main.async {
+ self.uptime = statistics.uptime
+ }
+ } catch { }
+ }
+ }
+
+ func updateFrequency() {
+
+ device.runSession(withName: "Get base frequency") { (session) in
+ do {
+ let frequency = try session.readBaseFrequency()
+ DispatchQueue.main.async {
+ self.frequency = frequency
+ }
+ } catch let error {
+ print("Error: \(error)")
+ }
+ }
+
+ }
// References to registered notification center observers
private var notificationObservers: [Any] = []
@@ -134,6 +178,11 @@ public class RileyLinkDeviceTableViewController: UITableViewController {
appeared = true
updateRSSI()
+
+ updateFrequency()
+
+ updateUptime()
+
}
public override func viewWillDisappear(_ animated: Bool) {
@@ -184,7 +233,8 @@ public class RileyLinkDeviceTableViewController: UITableViewController {
case version
case rssi
case connection
- case idleStatus
+ case uptime
+ case frequency
}
private func cellForRow(_ row: DeviceRow) -> UITableViewCell? {
@@ -230,11 +280,13 @@ public class RileyLinkDeviceTableViewController: UITableViewController {
cell.detailTextLabel?.text = device.peripheralState.description
case .rssi:
cell.textLabel?.text = LocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)")
-
cell.setDetailRSSI(bleRSSI, formatter: integerFormatter)
- case .idleStatus:
- cell.textLabel?.text = LocalizedString("On Idle", comment: "The title of the cell showing the last idle")
- cell.setDetailDate(lastIdle, formatter: dateFormatter)
+ case .uptime:
+ cell.textLabel?.text = NSLocalizedString("Uptime", comment: "The title of the cell showing uptime")
+ cell.setDetailAge(uptime)
+ case .frequency:
+ cell.textLabel?.text = NSLocalizedString("Frequency", comment: "The title of the cell showing current rileylink frequency")
+ cell.setDetailFrequency(frequency, formatter: frequencyFormatter)
}
case .commands:
cell.accessoryType = .disclosureIndicator
@@ -315,6 +367,17 @@ extension RileyLinkDeviceTableViewController: TextFieldTableViewControllerDelega
}
}
+private extension TimeInterval {
+ func format(using units: NSCalendar.Unit) -> String? {
+ let formatter = DateComponentsFormatter()
+ formatter.allowedUnits = units
+ formatter.unitsStyle = .full
+ formatter.zeroFormattingBehavior = .dropLeading
+ formatter.maximumUnitCount = 2
+
+ return formatter.string(from: self)
+ }
+}
private extension UITableViewCell {
func setDetailDate(_ date: Date?, formatter: DateFormatter) {
@@ -328,18 +391,21 @@ private extension UITableViewCell {
func setDetailRSSI(_ decibles: Int?, formatter: NumberFormatter) {
detailTextLabel?.text = formatter.decibleString(from: decibles) ?? "-"
}
-
- func setAwakeUntil(_ awakeUntil: Date?, formatter: DateFormatter) {
- switch awakeUntil {
- case let until? where until.timeIntervalSinceNow < 0:
- textLabel?.text = LocalizedString("Last Awake", comment: "The title of the cell describing an awake radio")
- setDetailDate(until, formatter: formatter)
- case let until?:
- textLabel?.text = LocalizedString("Awake Until", comment: "The title of the cell describing an awake radio")
- setDetailDate(until, formatter: formatter)
- default:
- textLabel?.text = LocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data")
- detailTextLabel?.text = nil
+
+ func setDetailAge(_ age: TimeInterval?) {
+ if let age = age {
+ detailTextLabel?.text = age.format(using: [.day, .hour, .minute])
+ } else {
+ detailTextLabel?.text = ""
}
}
+
+ func setDetailFrequency(_ frequency: Measurement?, formatter: MeasurementFormatter) {
+ if let frequency = frequency {
+ detailTextLabel?.text = formatter.string(from: frequency)
+ } else {
+ detailTextLabel?.text = ""
+ }
+ }
+
}
diff --git a/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift b/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift
index 7c35bbd80..07395ade6 100644
--- a/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift
+++ b/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift
@@ -23,7 +23,7 @@ public class RileyLinkDevicesTableViewDataSource: NSObject {
tableView.register(RileyLinkDevicesHeaderView.self, forHeaderFooterViewReuseIdentifier: RileyLinkDevicesHeaderView.className)
// Register for manager notifications
- NotificationCenter.default.addObserver(self, selector: #selector(reloadDevices), name: .ManagerDevicesDidChange, object: rileyLinkPumpManager.rileyLinkManager)
+ NotificationCenter.default.addObserver(self, selector: #selector(reloadDevices), name: .ManagerDevicesDidChange, object: rileyLinkPumpManager.rileyLinkDeviceProvider)
// Register for device notifications
for name in [.DeviceConnectionStateDidChange, .DeviceRSSIDidChange, .DeviceNameDidChange] as [Notification.Name] {
@@ -54,7 +54,7 @@ public class RileyLinkDevicesTableViewDataSource: NSObject {
public var isScanningEnabled: Bool = false {
didSet {
- rileyLinkPumpManager.rileyLinkManager.setScanningEnabled(isScanningEnabled)
+ rileyLinkPumpManager.rileyLinkConnectionManager?.setScanningEnabled(isScanningEnabled)
if isScanningEnabled {
rssiFetchTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateRSSI), userInfo: nil, repeats: true)
@@ -89,8 +89,11 @@ public class RileyLinkDevicesTableViewDataSource: NSObject {
///
/// - Parameter device: The peripheral
/// - Returns: The adjusted connection state
- private func preferenceStateForDevice(_ device: RileyLinkDevice) -> CBPeripheralState {
- let isAutoConnectDevice = self.rileyLinkPumpManager.rileyLinkPumpManagerState.connectedPeripheralIDs.contains(device.peripheralIdentifier.uuidString)
+ private func preferenceStateForDevice(_ device: RileyLinkDevice) -> CBPeripheralState? {
+ guard let connectionManager = rileyLinkPumpManager.rileyLinkConnectionManager else {
+ return nil
+ }
+ let isAutoConnectDevice = connectionManager.shouldConnect(to: device.peripheralIdentifier.uuidString)
var state = device.peripheralState
switch state {
@@ -114,7 +117,7 @@ public class RileyLinkDevicesTableViewDataSource: NSObject {
}
@objc private func reloadDevices() {
- rileyLinkPumpManager.rileyLinkManager.getDevices { (devices) in
+ rileyLinkPumpManager.rileyLinkDeviceProvider.getDevices { (devices) in
DispatchQueue.main.async {
self.devices = devices
}
@@ -169,7 +172,7 @@ extension RileyLinkDevicesTableViewDataSource: UITableViewDataSource {
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let deviceCell = tableView.dequeueReusableCell(withIdentifier: RileyLinkDeviceTableViewCell.className) as! RileyLinkDeviceTableViewCell
let device = devices[indexPath.row]
-
+
deviceCell.configureCellWithName(
device.name,
signal: decimalFormatter.decibleString(from: deviceRSSI[device.peripheralIdentifier]),
diff --git a/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift b/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift
index fe2529eb1..2f0e1859e 100644
--- a/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift
+++ b/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift
@@ -21,18 +21,18 @@ open class RileyLinkManagerSetupViewController: UINavigationController, PumpMana
open weak var setupDelegate: PumpManagerSetupViewControllerDelegate?
- open private(set) var rileyLinkPumpManager: RileyLinkPumpManager?
+ open var rileyLinkPumpManager: RileyLinkPumpManager?
open override func viewDidLoad() {
super.viewDidLoad()
-
+
delegate = self
}
-
+
open func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
let viewControllers = navigationController.viewControllers
let count = navigationController.viewControllers.count
-
+
if count >= 2, let setupViewController = viewControllers[count - 2] as? RileyLinkSetupTableViewController {
rileyLinkPumpManager = setupViewController.rileyLinkPumpManager
}
diff --git a/RileyLinkKitUI/RileyLinkSetupTableViewController.swift b/RileyLinkKitUI/RileyLinkSetupTableViewController.swift
index 8c0076622..20c0f34b1 100644
--- a/RileyLinkKitUI/RileyLinkSetupTableViewController.swift
+++ b/RileyLinkKitUI/RileyLinkSetupTableViewController.swift
@@ -9,11 +9,11 @@ import UIKit
import LoopKit
import LoopKitUI
import RileyLinkKit
-
+import RileyLinkBLEKit
public class RileyLinkSetupTableViewController: SetupTableViewController {
- let rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkPumpManagerState: RileyLinkPumpManagerState(connectedPeripheralIDs: []))
+ let rileyLinkPumpManager: RileyLinkPumpManager
private lazy var devicesDataSource: RileyLinkDevicesTableViewDataSource = {
return RileyLinkDevicesTableViewDataSource(
@@ -21,6 +21,16 @@ public class RileyLinkSetupTableViewController: SetupTableViewController {
devicesSectionIndex: Section.devices.rawValue
)
}()
+
+ public required init?(coder aDecoder: NSCoder) {
+ let rileyLinkConnectionManager = RileyLinkConnectionManager(autoConnectIDs: [])
+ rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkDeviceProvider: rileyLinkConnectionManager.deviceProvider, rileyLinkConnectionManager: rileyLinkConnectionManager)
+
+ rileyLinkConnectionManager.delegate = rileyLinkPumpManager
+
+ super.init(coder: aDecoder)
+ }
+
public override func viewDidLoad() {
super.viewDidLoad()
@@ -130,7 +140,11 @@ public class RileyLinkSetupTableViewController: SetupTableViewController {
// MARK: - Navigation
private var shouldContinue: Bool {
- return devicesDataSource.rileyLinkPumpManager.rileyLinkPumpManagerState.connectedPeripheralIDs.count > 0
+ guard let connectionManager = rileyLinkPumpManager.rileyLinkConnectionManager else {
+ return false
+ }
+
+ return connectionManager.connectingCount > 0
}
@objc private func deviceConnectionStateDidChange() {
diff --git a/RileyLinkTests/RileyLinkTests-Info.plist b/RileyLinkTests/RileyLinkTests-Info.plist
index f1cae6f2b..3c83b2ee6 100644
--- a/RileyLinkTests/RileyLinkTests-Info.plist
+++ b/RileyLinkTests/RileyLinkTests-Info.plist
@@ -13,7 +13,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 2.0.3
+ 2.0.4
CFBundleSignature
????
CFBundleVersion