From b90b27721d33491f0b2d1f4ae33b1d1f18569dc9 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 7 Jan 2017 15:07:19 -0800 Subject: [PATCH 1/5] Only allow one active glucose data source Separate CGM sources out into their own section and enforce zero or one active sources at any given time. This requires a new boolean value to track whether the G5 transmitter is enabled independently of the actual transmitter ID. While we're at it, create a separate config section for the pump to group it with the pump battery type since those are not really configuration values and go together. --- Loop/Extensions/NSUserDefaults.swift | 17 ++ Loop/Managers/DeviceDataManager.swift | 15 +- .../SettingsTableViewController.swift | 256 +++++++++++++----- 3 files changed, 223 insertions(+), 65 deletions(-) diff --git a/Loop/Extensions/NSUserDefaults.swift b/Loop/Extensions/NSUserDefaults.swift index cc13e51eb5..17389cf3b4 100644 --- a/Loop/Extensions/NSUserDefaults.swift +++ b/Loop/Extensions/NSUserDefaults.swift @@ -20,6 +20,7 @@ extension UserDefaults { case InsulinActionDuration = "com.loudnate.Naterade.InsulinActionDuration" case InsulinSensitivitySchedule = "com.loudnate.Naterade.InsulinSensitivitySchedule" case G4ReceiverEnabled = "com.loudnate.Loop.G4ReceiverEnabled" + case G5TransmitterEnabled = "com.loopkit.Loop.TransmitterEnabled" case G5TransmitterID = "com.loudnate.Naterade.TransmitterID" case GlucoseTargetRangeSchedule = "com.loudnate.Naterade.GlucoseTargetRangeSchedule" case MaximumBasalRatePerHour = "com.loudnate.Naterade.MaximumBasalRatePerHour" @@ -223,6 +224,22 @@ extension UserDefaults { } } + var transmitterEnabled: Bool { + get { + if object(forKey: Key.G5TransmitterEnabled.rawValue) == nil { + // Old versions of Loop used the existence of transmitterID to indicate + // that the transmitter is enabled. Upgrade to the new format now. The + // transmitter is enabled if there's a 6 character transmitter ID + set(transmitterID?.characters.count == 6, forKey: Key.G5TransmitterEnabled.rawValue) + } + + return bool(forKey: Key.G5TransmitterEnabled.rawValue) + } + set { + set(newValue, forKey: Key.G5TransmitterEnabled.rawValue) + } + } + var transmitterID: String? { get { return string(forKey: Key.G5TransmitterID.rawValue) diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 4dad875a39..d2d00d1114 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -54,6 +54,15 @@ final class DeviceDataManager: CarbStoreDelegate, CarbStoreSyncDelegate, DoseSto } } + var transmitterEnabled: Bool { + get { + return UserDefaults.standard.transmitterEnabled + } + set { + return UserDefaults.standard.transmitterEnabled = newValue + } + } + var sensorInfo: SensorDisplayable? { return latestGlucoseG5 ?? latestGlucoseG4 ?? latestGlucoseFromShare ?? latestPumpStatusFromMySentry } @@ -1050,7 +1059,10 @@ final class DeviceDataManager: CarbStoreDelegate, CarbStoreSyncDelegate, DoseSto receiver?.delegate = self } - if let transmitterID = UserDefaults.standard.transmitterID, transmitterID.characters.count == 6 { + if UserDefaults.standard.transmitterEnabled, + let transmitterID = UserDefaults.standard.transmitterID, + transmitterID.characters.count == 6 { + transmitter = Transmitter(ID: transmitterID, passiveModeEnabled: true) transmitter?.delegate = self } @@ -1071,6 +1083,7 @@ extension DeviceDataManager: CustomDebugStringConvertible { "latestGlucoseG4: \(latestGlucoseG4)", "pumpState: \(String(reflecting: pumpState))", "preferredInsulinDataSource: \(preferredInsulinDataSource)", + "transmitterEnabled: \(transmitterEnabled)", "transmitterID: \(transmitterID)", "glucoseTargetRangeSchedule: \(glucoseTargetRangeSchedule?.debugDescription ?? "")", "workoutModeEnabled: \(workoutModeEnabled)", diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index 5250817f37..6ef5e442a6 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -47,7 +47,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu dataManager.rileyLinkManager.deviceScanningEnabled = true - if dataManager.transmitterID != nil || dataManager.receiverEnabled, let glucoseStore = dataManager.glucoseStore, glucoseStore.authorizationRequired { + if dataManager.transmitterEnabled || dataManager.receiverEnabled, let glucoseStore = dataManager.glucoseStore, glucoseStore.authorizationRequired { glucoseStore.authorize({ (success, error) -> Void in // Do nothing for now }) @@ -79,10 +79,12 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu fileprivate enum Section: Int { case loop = 0 case devices + case pump + case cgm case configuration case services - static let count = 4 + static let count = 6 } fileprivate enum LoopRow: Int { @@ -93,20 +95,31 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu static let count = 3 } - fileprivate enum ConfigurationRow: Int { + fileprivate enum PumpRow: Int { case pumpID = 0 - case transmitterID - case receiverEnabled - case glucoseTargetRange + case batteryChemistry + + static let count = 2 + } + + fileprivate enum CgmRow: Int { + case receiverEnabled = 0 + case transmitterEnabled + case transmitterID // optional, only displayed if transmitterEnabled + + static let count = 3 + } + + fileprivate enum ConfigurationRow: Int { + case glucoseTargetRange = 0 case insulinActionDuration case basalRate case carbRatio case insulinSensitivity case maxBasal case maxBolus - case batteryChemistry - static let count = 11 + static let count = 7 } fileprivate enum ServiceRow: Int { @@ -138,6 +151,14 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu switch Section(rawValue: section)! { case .loop: return LoopRow.count + case .pump: + return PumpRow.count + case .cgm: + if dataManager.transmitterEnabled { + return CgmRow.count + } else { + return CgmRow.count - 1 + } case .configuration: return ConfigurationRow.count case .devices: @@ -177,8 +198,19 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu return cell } - case .configuration: - if case .receiverEnabled = ConfigurationRow(rawValue: indexPath.row)! { + case .pump: + let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) + switch PumpRow(rawValue: indexPath.row)! { + case .pumpID: + configCell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title text for the pump ID config value") + configCell.detailTextLabel?.text = dataManager.pumpID ?? TapToSetString + case .batteryChemistry: + configCell.textLabel?.text = NSLocalizedString("Pump Battery Type", comment: "The title text for the battery type value") + configCell.detailTextLabel?.text = String(describing: dataManager.batteryChemistry) + } + cell = configCell + case .cgm: + if case .receiverEnabled = CgmRow(rawValue: indexPath.row)! { let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell switchCell.`switch`?.isOn = dataManager.receiverEnabled @@ -189,17 +221,33 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu return switchCell } - let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) + if case .transmitterEnabled = CgmRow(rawValue: indexPath.row)! { + let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell - switch ConfigurationRow(rawValue: indexPath.row)! { - case .pumpID: - configCell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title text for the pump ID config value") - configCell.detailTextLabel?.text = dataManager.pumpID ?? TapToSetString + switchCell.`switch`?.isOn = dataManager.transmitterEnabled + switchCell.titleLabel.text = NSLocalizedString("G5 Transmitter", comment: "The title text for the G5 Transmitter enabled switch cell") + + switchCell.`switch`?.addTarget(self, action: #selector(transmitterEnabledChanged(_:)), for: .valueChanged) + + return switchCell + + } + + let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) + switch CgmRow(rawValue: indexPath.row)! { + case .transmitterEnabled: + break case .transmitterID: configCell.textLabel?.text = NSLocalizedString("G5 Transmitter ID", comment: "The title text for the Dexcom G5 transmitter ID config value") configCell.detailTextLabel?.text = dataManager.transmitterID ?? TapToSetString case .receiverEnabled: break + } + cell = configCell + case .configuration: + let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) + + switch ConfigurationRow(rawValue: indexPath.row)! { case .basalRate: configCell.textLabel?.text = NSLocalizedString("Basal Rates", comment: "The title text for the basal rate schedule") @@ -274,14 +322,6 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } else { configCell.detailTextLabel?.text = TapToSetString } - case .batteryChemistry: - configCell.textLabel?.text = NSLocalizedString("Pump Battery Type", comment: "The title text for the battery type value") - configCell.detailTextLabel?.text = String(describing: dataManager.batteryChemistry) -// if let sentrySupported = dataManager.pumpState?.pumpModel?.hasMySentry, sentrySupported { -// configCell.textLabel?.isEnabled = false -// configCell.detailTextLabel?.isEnabled = false -// configCell.isUserInteractionEnabled = false -// } } cell = configCell @@ -333,6 +373,10 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu case .loop: let bundle = Bundle.main return bundle.localizedNameAndVersion + case .pump: + return NSLocalizedString("Pump", comment: "The title of the pump section in settings") + case .cgm: + return NSLocalizedString("Continuous Glucose Monitor", comment: "The title of the continuous glucose monitor section in settings") case .configuration: return NSLocalizedString("Configuration", comment: "The title of the configuration section in settings") case .devices: @@ -348,17 +392,59 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu let sender = tableView.cellForRow(at: indexPath) switch Section(rawValue: indexPath.section)! { - case .configuration: - let row = ConfigurationRow(rawValue: indexPath.row)! + case .pump: + let row = PumpRow(rawValue: indexPath.row)! switch row { - case .pumpID, .transmitterID, .insulinActionDuration, .maxBasal, .maxBolus: + case .pumpID: let vc: TextFieldTableViewController - switch row { case .pumpID: vc = PumpIDTableViewController(pumpID: dataManager.pumpID, region: dataManager.pumpState?.pumpRegion) + default: + fatalError() + } + vc.title = sender?.textLabel?.text + vc.indexPath = indexPath + vc.delegate = self + + show(vc, sender: indexPath) + case .batteryChemistry: + let vc = RadioSelectionTableViewController.batteryChemistryType(dataManager.batteryChemistry) + vc.title = sender?.textLabel?.text + vc.delegate = self + + show(vc, sender: sender) + } + case .cgm: + let row = CgmRow(rawValue: indexPath.row)! + switch row { + case .transmitterEnabled: + break + case .transmitterID: + let vc: TextFieldTableViewController + + switch row { case .transmitterID: vc = .transmitterID(dataManager.transmitterID) + default: + fatalError() + } + + vc.title = sender?.textLabel?.text + vc.indexPath = indexPath + vc.delegate = self + + show(vc, sender: indexPath) + case .receiverEnabled: + break + } + case .configuration: + let row = ConfigurationRow(rawValue: indexPath.row)! + switch row { + case .insulinActionDuration, .maxBasal, .maxBolus: + let vc: TextFieldTableViewController + + switch row { case .insulinActionDuration: vc = .insulinActionDuration(dataManager.insulinActionDuration) case .maxBasal: @@ -464,14 +550,6 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } else { show(scheduleVC, sender: sender) } - case .receiverEnabled: - break - case .batteryChemistry: - let vc = RadioSelectionTableViewController.batteryChemistryType(dataManager.batteryChemistry) - vc.title = sender?.textLabel?.text - vc.delegate = self - - show(vc, sender: sender) } case .devices: let vc = RileyLinkDeviceTableViewController() @@ -544,7 +622,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu switch Section(rawValue: section)! { case .devices: return devicesSectionTitleView - case .loop, .configuration, .services: + case .loop, .pump, .cgm, .configuration, .services: return nil } } @@ -570,8 +648,43 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } } + func transmitterEnabledChanged(_ sender: UISwitch) { + if sender.isOn { + enableTransmitter() + } else { + disableTransmitter() + } + } + + func enableTransmitter() { + if dataManager.transmitterEnabled == false { + dataManager.transmitterEnabled = true + disableReceiver() + tableView.insertRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .bottom) + } + } + + func disableTransmitter() { + if dataManager.transmitterEnabled { + dataManager.transmitterEnabled = false + let switchCell = tableView.cellForRow(at: IndexPath(row: CgmRow.transmitterEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell + switchCell.`switch`?.setOn(false, animated: true) + tableView.deleteRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .bottom) + } + } + func receiverEnabledChanged(_ sender: UISwitch) { dataManager.receiverEnabled = sender.isOn + + if sender.isOn { + disableTransmitter() + } + } + + func disableReceiver() { + dataManager.receiverEnabled = false + let switchCell = tableView.cellForRow(at: IndexPath(row: CgmRow.receiverEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell + switchCell.`switch`?.setOn(false, animated: true) } // MARK: - DailyValueScheduleTableViewControllerDelegate @@ -627,13 +740,13 @@ extension SettingsTableViewController: RadioSelectionTableViewControllerDelegate assertionFailure() } - case .configuration: - switch ConfigurationRow(rawValue: indexPath.row)! { + case .pump: + switch PumpRow(rawValue: indexPath.row)! { case .batteryChemistry: if let selectedIndex = controller.selectedIndex, let dataSource = BatteryChemistryType(rawValue: selectedIndex) { dataManager.batteryChemistry = dataSource - tableView.reloadRows(at: [IndexPath(row: ConfigurationRow.batteryChemistry.rawValue, section: Section.configuration.rawValue)], with: .none) + tableView.reloadRows(at: [IndexPath(row: PumpRow.batteryChemistry.rawValue, section: Section.configuration.rawValue)], with: .none) } default: assertionFailure() @@ -648,34 +761,49 @@ extension SettingsTableViewController: RadioSelectionTableViewControllerDelegate extension SettingsTableViewController: TextFieldTableViewControllerDelegate { func textFieldTableViewControllerDidEndEditing(_ controller: TextFieldTableViewController) { if let indexPath = controller.indexPath { - switch ConfigurationRow(rawValue: indexPath.row)! { - case .pumpID: - dataManager.pumpID = controller.value + switch Section(rawValue: indexPath.section)! { + case .pump: + switch PumpRow(rawValue: indexPath.row)! { + case .pumpID: + dataManager.pumpID = controller.value - if let controller = controller as? PumpIDTableViewController, - let region = controller.region - { - dataManager.pumpState?.pumpRegion = region - } - case .transmitterID: - dataManager.transmitterID = controller.value - case .insulinActionDuration: - if let value = controller.value, let duration = valueNumberFormatter.number(from: value)?.doubleValue { - dataManager.insulinActionDuration = TimeInterval(hours: duration) - } else { - dataManager.insulinActionDuration = nil + if let controller = controller as? PumpIDTableViewController, + let region = controller.region + { + dataManager.pumpState?.pumpRegion = region + } + default: + assertionFailure() } - case .maxBasal: - if let value = controller.value, let rate = valueNumberFormatter.number(from: value)?.doubleValue { - dataManager.maximumBasalRatePerHour = rate - } else { - dataManager.maximumBasalRatePerHour = nil + case .cgm: + switch CgmRow(rawValue: indexPath.row)! { + case .transmitterID: + dataManager.transmitterID = controller.value + default: + assertionFailure() } - case .maxBolus: - if let value = controller.value, let units = valueNumberFormatter.number(from: value)?.doubleValue { - dataManager.maximumBolus = units - } else { - dataManager.maximumBolus = nil + case .configuration: + switch ConfigurationRow(rawValue: indexPath.row)! { + case .insulinActionDuration: + if let value = controller.value, let duration = valueNumberFormatter.number(from: value)?.doubleValue { + dataManager.insulinActionDuration = TimeInterval(hours: duration) + } else { + dataManager.insulinActionDuration = nil + } + case .maxBasal: + if let value = controller.value, let rate = valueNumberFormatter.number(from: value)?.doubleValue { + dataManager.maximumBasalRatePerHour = rate + } else { + dataManager.maximumBasalRatePerHour = nil + } + case .maxBolus: + if let value = controller.value, let units = valueNumberFormatter.number(from: value)?.doubleValue { + dataManager.maximumBolus = units + } else { + dataManager.maximumBolus = nil + } + default: + assertionFailure() } default: assertionFailure() From f973b4716e17b450afafc3520b2917ad0e499686 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 7 Jan 2017 15:48:28 -0800 Subject: [PATCH 2/5] Improve animation mode for showing G5 Transmitter ID The top animation is a clearer indication that this is an extension of the G5 Transmitter enabled switch. --- Loop/View Controllers/SettingsTableViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index 6ef5e442a6..ddb5b3537c 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -660,7 +660,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu if dataManager.transmitterEnabled == false { dataManager.transmitterEnabled = true disableReceiver() - tableView.insertRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .bottom) + tableView.insertRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .top) } } @@ -669,7 +669,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu dataManager.transmitterEnabled = false let switchCell = tableView.cellForRow(at: IndexPath(row: CgmRow.transmitterEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell switchCell.`switch`?.setOn(false, animated: true) - tableView.deleteRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .bottom) + tableView.deleteRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .top) } } From 6f3b5b1d2dcbffb6852f3c34e6e175beebc2e1b7 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 8 Jan 2017 13:22:58 -0800 Subject: [PATCH 3/5] Be more specific with the key name --- Loop/Extensions/NSUserDefaults.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loop/Extensions/NSUserDefaults.swift b/Loop/Extensions/NSUserDefaults.swift index 17389cf3b4..e05f4ffc51 100644 --- a/Loop/Extensions/NSUserDefaults.swift +++ b/Loop/Extensions/NSUserDefaults.swift @@ -20,7 +20,7 @@ extension UserDefaults { case InsulinActionDuration = "com.loudnate.Naterade.InsulinActionDuration" case InsulinSensitivitySchedule = "com.loudnate.Naterade.InsulinSensitivitySchedule" case G4ReceiverEnabled = "com.loudnate.Loop.G4ReceiverEnabled" - case G5TransmitterEnabled = "com.loopkit.Loop.TransmitterEnabled" + case G5TransmitterEnabled = "com.loopkit.Loop.G5TransmitterEnabled" case G5TransmitterID = "com.loudnate.Naterade.TransmitterID" case GlucoseTargetRangeSchedule = "com.loudnate.Naterade.GlucoseTargetRangeSchedule" case MaximumBasalRatePerHour = "com.loudnate.Naterade.MaximumBasalRatePerHour" From fe940bb7f7c566ba681435b5b9fc5d77298591ed Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 8 Jan 2017 13:23:30 -0800 Subject: [PATCH 4/5] Use 'CGM' instead of 'Cgm' --- .../SettingsTableViewController.swift | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index ddb5b3537c..dca949e90f 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -102,7 +102,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu static let count = 2 } - fileprivate enum CgmRow: Int { + fileprivate enum CGMRow: Int { case receiverEnabled = 0 case transmitterEnabled case transmitterID // optional, only displayed if transmitterEnabled @@ -155,9 +155,9 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu return PumpRow.count case .cgm: if dataManager.transmitterEnabled { - return CgmRow.count + return CGMRow.count } else { - return CgmRow.count - 1 + return CGMRow.count - 1 } case .configuration: return ConfigurationRow.count @@ -210,7 +210,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } cell = configCell case .cgm: - if case .receiverEnabled = CgmRow(rawValue: indexPath.row)! { + if case .receiverEnabled = CGMRow(rawValue: indexPath.row)! { let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell switchCell.`switch`?.isOn = dataManager.receiverEnabled @@ -221,7 +221,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu return switchCell } - if case .transmitterEnabled = CgmRow(rawValue: indexPath.row)! { + if case .transmitterEnabled = CGMRow(rawValue: indexPath.row)! { let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell switchCell.`switch`?.isOn = dataManager.transmitterEnabled @@ -234,7 +234,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) - switch CgmRow(rawValue: indexPath.row)! { + switch CGMRow(rawValue: indexPath.row)! { case .transmitterEnabled: break case .transmitterID: @@ -416,7 +416,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu show(vc, sender: sender) } case .cgm: - let row = CgmRow(rawValue: indexPath.row)! + let row = CGMRow(rawValue: indexPath.row)! switch row { case .transmitterEnabled: break @@ -660,16 +660,16 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu if dataManager.transmitterEnabled == false { dataManager.transmitterEnabled = true disableReceiver() - tableView.insertRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .top) + tableView.insertRows(at: [IndexPath(row: CGMRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .top) } } func disableTransmitter() { if dataManager.transmitterEnabled { dataManager.transmitterEnabled = false - let switchCell = tableView.cellForRow(at: IndexPath(row: CgmRow.transmitterEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell + let switchCell = tableView.cellForRow(at: IndexPath(row: CGMRow.transmitterEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell switchCell.`switch`?.setOn(false, animated: true) - tableView.deleteRows(at: [IndexPath(row: CgmRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .top) + tableView.deleteRows(at: [IndexPath(row: CGMRow.transmitterID.rawValue, section:Section.cgm.rawValue)], with: .top) } } @@ -683,7 +683,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu func disableReceiver() { dataManager.receiverEnabled = false - let switchCell = tableView.cellForRow(at: IndexPath(row: CgmRow.receiverEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell + let switchCell = tableView.cellForRow(at: IndexPath(row: CGMRow.receiverEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell switchCell.`switch`?.setOn(false, animated: true) } @@ -776,7 +776,7 @@ extension SettingsTableViewController: TextFieldTableViewControllerDelegate { assertionFailure() } case .cgm: - switch CgmRow(rawValue: indexPath.row)! { + switch CGMRow(rawValue: indexPath.row)! { case .transmitterID: dataManager.transmitterID = controller.value default: From f18813ab1e3854a478ced4d466c3fb6aabf600ac Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sun, 8 Jan 2017 14:23:22 -0800 Subject: [PATCH 5/5] Mark target-action methods with @objc to make sure that they're using dynamic dispatch. Also make the internal methods private for good measure. --- .../SettingsTableViewController.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index dca949e90f..8a3b094795 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -629,11 +629,11 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu // MARK: - Device mangement - func dosingEnabledChanged(_ sender: UISwitch) { + @objc private func dosingEnabledChanged(_ sender: UISwitch) { dataManager.loopManager.dosingEnabled = sender.isOn } - func deviceConnectionChanged(_ connectSwitch: UISwitch) { + @objc private func deviceConnectionChanged(_ connectSwitch: UISwitch) { let switchOrigin = connectSwitch.convert(CGPoint.zero, to: tableView) if let indexPath = tableView.indexPathForRow(at: switchOrigin), indexPath.section == Section.devices.rawValue @@ -648,7 +648,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } } - func transmitterEnabledChanged(_ sender: UISwitch) { + @objc private func transmitterEnabledChanged(_ sender: UISwitch) { if sender.isOn { enableTransmitter() } else { @@ -656,7 +656,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } } - func enableTransmitter() { + private func enableTransmitter() { if dataManager.transmitterEnabled == false { dataManager.transmitterEnabled = true disableReceiver() @@ -664,7 +664,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } } - func disableTransmitter() { + private func disableTransmitter() { if dataManager.transmitterEnabled { dataManager.transmitterEnabled = false let switchCell = tableView.cellForRow(at: IndexPath(row: CGMRow.transmitterEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell @@ -673,7 +673,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } } - func receiverEnabledChanged(_ sender: UISwitch) { + @objc private func receiverEnabledChanged(_ sender: UISwitch) { dataManager.receiverEnabled = sender.isOn if sender.isOn { @@ -681,7 +681,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu } } - func disableReceiver() { + private func disableReceiver() { dataManager.receiverEnabled = false let switchCell = tableView.cellForRow(at: IndexPath(row: CGMRow.receiverEnabled.rawValue, section: Section.cgm.rawValue)) as! SwitchTableViewCell switchCell.`switch`?.setOn(false, animated: true)