diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index 522fea9dfc..93566dda01 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 4302F4DB1D4D6E9F00F0FCAF /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4302F4DA1D4D6E9F00F0FCAF /* NSData.swift */; }; + 4302F4E11D4E9C8900F0FCAF /* TextFieldTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4302F4E01D4E9C8900F0FCAF /* TextFieldTableViewController.swift */; }; 430DA58E1D4AEC230097D1CA /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58D1D4AEC230097D1CA /* NSBundle.swift */; }; 430DA5901D4B0E4C0097D1CA /* MySentryPumpStatusMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58F1D4B0E4C0097D1CA /* MySentryPumpStatusMessageBody.swift */; }; 4315D2871CA5CC3B00589052 /* CarbEntryEditTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4315D2861CA5CC3B00589052 /* CarbEntryEditTableViewController.swift */; }; @@ -220,6 +222,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 4302F4DA1D4D6E9F00F0FCAF /* NSData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSData.swift; sourceTree = ""; }; + 4302F4E01D4E9C8900F0FCAF /* TextFieldTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewController.swift; sourceTree = ""; }; 430DA58D1D4AEC230097D1CA /* NSBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSBundle.swift; sourceTree = ""; }; 430DA58F1D4B0E4C0097D1CA /* MySentryPumpStatusMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryPumpStatusMessageBody.swift; sourceTree = ""; }; 4315D2861CA5CC3B00589052 /* CarbEntryEditTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarbEntryEditTableViewController.swift; sourceTree = ""; }; @@ -585,6 +589,7 @@ 434FF1E91CF26C29000DB779 /* IdentifiableClass.swift */, 434F54561D287FDB002A9274 /* NibLoadable.swift */, 430DA58D1D4AEC230097D1CA /* NSBundle.swift */, + 4302F4DA1D4D6E9F00F0FCAF /* NSData.swift */, 43CE7CDD1CA8B63E003CC1B0 /* NSDate.swift */, 4398973A1CD2FC2000223065 /* NSDateFormatter.swift */, 439897341CD2F7DE00223065 /* NSTimeInterval.swift */, @@ -607,6 +612,7 @@ 43DBF0561C93F6EB00B3C386 /* ReservoirTableViewController.swift */, 43F5C2DA1B92A5E1003EB13D /* SettingsTableViewController.swift */, 43E3449E1B9D68E900C85C07 /* StatusTableViewController.swift */, + 4302F4E01D4E9C8900F0FCAF /* TextFieldTableViewController.swift */, ); path = "View Controllers"; sourceTree = ""; @@ -971,6 +977,7 @@ 437CCADE1D2858FD0075D2C3 /* AuthenticationViewController.swift in Sources */, 43A5676B1C96155700334FAC /* SwitchTableViewCell.swift in Sources */, 43A567691C94880B00334FAC /* LoopDataManager.swift in Sources */, + 4302F4E11D4E9C8900F0FCAF /* TextFieldTableViewController.swift in Sources */, 43E344A41B9E1B1C00C85C07 /* NSUserDefaults.swift in Sources */, 43649A631C7A347F00523D7F /* CollectionType.swift in Sources */, 437CEEBE1CD6E0CB003C8C80 /* LoopCompletionHUDView.swift in Sources */, @@ -1009,6 +1016,7 @@ 436A0DA51D236A2A00104B24 /* LoopError.swift in Sources */, 437CEEC01CD6FCD8003C8C80 /* BasalRateHUDView.swift in Sources */, 43E2D8C61D204678004DA55F /* KeychainManager.swift in Sources */, + 4302F4DB1D4D6E9F00F0FCAF /* NSData.swift in Sources */, 437CEECA1CD84DB7003C8C80 /* BatteryLevelHUDView.swift in Sources */, 43F78D261C8FC000002152D1 /* DoseMath.swift in Sources */, 4331E07A1C85650D00FBE832 /* ChartAxisValueDoubleLog.swift in Sources */, diff --git a/Loop/Extensions/NSData.swift b/Loop/Extensions/NSData.swift new file mode 100644 index 0000000000..1df7d3c748 --- /dev/null +++ b/Loop/Extensions/NSData.swift @@ -0,0 +1,29 @@ +// +// NSData.swift +// Loop +// +// Created by Nate Racklyeft on 7/30/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +extension NSData { + @nonobjc subscript(index: Int) -> UInt8 { + let bytes: [UInt8] = self[index...index] + + return bytes[0] + } + + subscript(range: Range) -> [UInt8] { + var dataArray = [UInt8](count: range.count, repeatedValue: 0) + self.getBytes(&dataArray, range: NSRange(range)) + + return dataArray + } + + subscript(range: Range) -> NSData { + return subdataWithRange(NSRange(range)) + } +} diff --git a/Loop/Info.plist b/Loop/Info.plist index 468ecb31df..c3509d8c51 100644 --- a/Loop/Info.plist +++ b/Loop/Info.plist @@ -4,6 +4,8 @@ CFBundleDevelopmentRegion en + ITSAppUsesNonExemptEncryption + CFBundleDisplayName Loop CFBundleExecutable diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index 965571debe..befd986a4e 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -328,38 +328,21 @@ class SettingsTableViewController: UITableViewController, DailyValueScheduleTabl let row = ConfigurationRow(rawValue: indexPath.row)! switch row { case .PumpID, .TransmitterID, .InsulinActionDuration, .MaxBasal, .MaxBolus: - let vc = TextFieldTableViewController() + let vc: TextFieldTableViewController switch row { case .PumpID: - vc.placeholder = NSLocalizedString("Enter the 6-digit pump ID", comment: "The placeholder text instructing users how to enter a pump ID") - vc.value = dataManager.pumpID + vc = .pumpID(dataManager.pumpID) case .TransmitterID: - vc.placeholder = NSLocalizedString("Enter the 6-digit transmitter ID", comment: "The placeholder text instructing users how to enter a pump ID") - vc.value = dataManager.transmitterID + vc = .transmitterID(dataManager.transmitterID) case .InsulinActionDuration: - vc.placeholder = NSLocalizedString("Enter a number of hours", comment: "The placeholder text instructing users how to enter an insulin action duration") - vc.keyboardType = .DecimalPad - - if let insulinActionDuration = dataManager.insulinActionDuration { - vc.value = valueNumberFormatter.stringFromNumber(insulinActionDuration.hours) - } + vc = .insulinActionDuration(dataManager.insulinActionDuration) case .MaxBasal: - vc.placeholder = NSLocalizedString("Enter a rate in units per hour", comment: "The placeholder text instructing users how to enter a maximum basal rate") - vc.keyboardType = .DecimalPad - - if let maxBasal = dataManager.maximumBasalRatePerHour { - vc.value = valueNumberFormatter.stringFromNumber(maxBasal) - } + vc = .maxBasal(dataManager.maximumBasalRatePerHour) case .MaxBolus: - vc.placeholder = NSLocalizedString("Enter a number of units", comment: "The placeholder text instructing users how to enter a maximum bolus") - vc.keyboardType = .DecimalPad - - if let maxBolus = dataManager.maximumBolus { - vc.value = valueNumberFormatter.stringFromNumber(maxBolus) - } + vc = .maxBolus(dataManager.maximumBolus) default: - assertionFailure() + fatalError() } vc.title = sender?.textLabel?.text diff --git a/Loop/View Controllers/TextFieldTableViewController.swift b/Loop/View Controllers/TextFieldTableViewController.swift new file mode 100644 index 0000000000..5858d7f5b0 --- /dev/null +++ b/Loop/View Controllers/TextFieldTableViewController.swift @@ -0,0 +1,83 @@ +// +// TextFieldTableViewController.swift +// Loop +// +// Created by Nate Racklyeft on 7/31/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import LoopKit + + +/// Convenience static constructors used to contain common configuration +extension TextFieldTableViewController { + typealias T = TextFieldTableViewController + + private static let valueNumberFormatter: NSNumberFormatter = { + let formatter = NSNumberFormatter() + + formatter.numberStyle = .DecimalStyle + formatter.minimumFractionDigits = 0 + formatter.maximumFractionDigits = 2 + + return formatter + }() + + static func pumpID(value: String?) -> T { + let vc = T() + + vc.placeholder = NSLocalizedString("Enter the 6-digit pump ID", comment: "The placeholder text instructing users how to enter a pump ID") + vc.keyboardType = .NumberPad + vc.value = value + + return vc + } + + static func transmitterID(value: String?) -> T { + let vc = T() + + vc.placeholder = NSLocalizedString("Enter the 6-digit transmitter ID", comment: "The placeholder text instructing users how to enter a pump ID") + vc.value = value + + return vc + } + + static func insulinActionDuration(value: NSTimeInterval?) -> T { + let vc = T() + + vc.placeholder = NSLocalizedString("Enter a number of hours", comment: "The placeholder text instructing users how to enter an insulin action duration") + vc.keyboardType = .DecimalPad + + if let insulinActionDuration = value { + vc.value = valueNumberFormatter.stringFromNumber(insulinActionDuration.hours) + } + + return vc + } + + static func maxBasal(value: Double?) -> T { + let vc = T() + + vc.placeholder = NSLocalizedString("Enter a rate in units per hour", comment: "The placeholder text instructing users how to enter a maximum basal rate") + vc.keyboardType = .DecimalPad + + if let maxBasal = value { + vc.value = valueNumberFormatter.stringFromNumber(maxBasal) + } + + return vc + } + + static func maxBolus(value: Double?) -> T { + let vc = T() + + vc.placeholder = NSLocalizedString("Enter a number of units", comment: "The placeholder text instructing users how to enter a maximum bolus") + vc.keyboardType = .DecimalPad + + if let maxBolus = value { + vc.value = valueNumberFormatter.stringFromNumber(maxBolus) + } + + return vc + } +}