From b671e4ba6bb8fa8e76faf71cc153988ae61e96ea Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Fri, 1 Jul 2016 22:08:59 -0700 Subject: [PATCH] Version 0.6.0 (#146) * Renaming RL from RileyLinkDeviceTableViewController * Change default autocapitalization type * Revert debugging code. Avoid reloading table on start of rename op. Add disclosure indicator to RL Name row, to indicate it can be edited * Adding the read clock command For https://github.com/loudnate/Loop/issues/49 * Fixing missing idle status row * Fix ChangeSensorSetup2PumpEvent parsing on 551 pumps * Some NSUploadKit framework refactoring; ensuring tests are running (#144) * Adding easy sharing to the CommandResponseViewController (#143) * agvtool --- MinimedKit/Info.plist | 2 +- .../ReadSettingsCarelinkMessageBody.swift | 4 +- .../ChangeSensorSetup2PumpEvent.swift | 8 +- MinimedKitTests/Info.plist | 2 +- MinimedKitTests/PumpMessageTests.swift | 25 ---- NightscoutUploadKit/Info.plist | 2 +- NightscoutUploadKit/NightscoutUploader.swift | 77 +++++------- NightscoutUploadKitTests/Info.plist | 2 +- RileyLink.xcodeproj/project.pbxproj | 112 +++++++++++------- .../xcshareddata/xcschemes/RileyLink.xcscheme | 10 ++ RileyLink/DeviceDataManager.swift | 5 +- RileyLink/RileyLink-Info.plist | 2 +- .../RileyLinkListTableViewController.swift | 8 +- RileyLinkBLEKit/Info.plist | 2 +- RileyLinkBLEKit/RileyLinkBLEDevice.m | 8 +- RileyLinkBLEKit/RileyLinkBLEManager.h | 1 + RileyLinkBLEKitTests/Info.plist | 2 +- RileyLinkKit/Extensions/UITableViewCell.swift | 13 ++ RileyLinkKit/Info.plist | 2 +- RileyLinkKit/PumpOps.swift | 27 ++++- RileyLinkKit/RileyLinkDevice.swift | 4 + RileyLinkKit/RileyLinkDeviceManager.swift | 19 ++- .../UI/CommandResponseViewController.swift | 63 ++++++++++ .../RileyLinkDeviceTableViewCell.swift | 1 - .../RileyLinkDeviceTableViewCell.xib | 2 +- .../RileyLinkDeviceTableViewController.swift | 86 +++++++++++++- RileyLinkKit/UI/TextFieldTableViewCell.swift | 24 ++++ RileyLinkKit/UI/TextFieldTableViewCell.xib | 36 ++++++ .../UI/TextFieldTableViewController.swift | 89 ++++++++++++++ .../CommandResponseViewController.swift | 41 ------- RileyLinkKitTests/Info.plist | 2 +- RileyLinkTests/RileyLinkTests-Info.plist | 2 +- 32 files changed, 491 insertions(+), 192 deletions(-) delete mode 100644 MinimedKitTests/PumpMessageTests.swift create mode 100644 RileyLinkKit/Extensions/UITableViewCell.swift create mode 100644 RileyLinkKit/UI/CommandResponseViewController.swift rename RileyLinkKit/{Views => UI}/RileyLinkDeviceTableViewCell.swift (96%) rename RileyLinkKit/{Views => UI}/RileyLinkDeviceTableViewCell.xib (98%) rename RileyLinkKit/{ViewControllers => UI}/RileyLinkDeviceTableViewController.swift (87%) create mode 100644 RileyLinkKit/UI/TextFieldTableViewCell.swift create mode 100644 RileyLinkKit/UI/TextFieldTableViewCell.xib create mode 100644 RileyLinkKit/UI/TextFieldTableViewController.swift delete mode 100644 RileyLinkKit/ViewControllers/CommandResponseViewController.swift diff --git a/MinimedKit/Info.plist b/MinimedKit/Info.plist index 288c341b6..63c3e67d5 100644 --- a/MinimedKit/Info.plist +++ b/MinimedKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift index c30febb8c..b35c6971c 100644 --- a/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift +++ b/MinimedKit/Messages/ReadSettingsCarelinkMessageBody.swift @@ -54,10 +54,10 @@ public class ReadSettingsCarelinkMessageBody: CarelinkLongMessageBody { } let maxBolusTicks: UInt8 = rxData[7] - maxBolus = Double(maxBolusTicks) * self.dynamicType.maxBolusMultiplier + maxBolus = Double(maxBolusTicks) / self.dynamicType.maxBolusMultiplier let maxBasalTicks: Int = Int(bigEndianBytes: rxData[8...9]) - maxBasal = Double(maxBasalTicks) * self.dynamicType.maxBasalMultiplier + maxBasal = Double(maxBasalTicks) / self.dynamicType.maxBasalMultiplier let rawSelectedBasalProfile: UInt8 = rxData[12] selectedBasalProfile = BasalProfile(rawValue: rawSelectedBasalProfile) diff --git a/MinimedKit/PumpEvents/ChangeSensorSetup2PumpEvent.swift b/MinimedKit/PumpEvents/ChangeSensorSetup2PumpEvent.swift index f15c95bf1..61e8fc402 100644 --- a/MinimedKit/PumpEvents/ChangeSensorSetup2PumpEvent.swift +++ b/MinimedKit/PumpEvents/ChangeSensorSetup2PumpEvent.swift @@ -14,8 +14,12 @@ public struct ChangeSensorSetup2PumpEvent: TimestampedPumpEvent { public let timestamp: NSDateComponents public init?(availableData: NSData, pumpModel: PumpModel) { - length = 37 - + if pumpModel.hasLowSuspend { + length = 41 + } else { + length = 37 + } + guard length <= availableData.length else { return nil } diff --git a/MinimedKitTests/Info.plist b/MinimedKitTests/Info.plist index 94b6ed951..87f0ed731 100644 --- a/MinimedKitTests/Info.plist +++ b/MinimedKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/MinimedKitTests/PumpMessageTests.swift b/MinimedKitTests/PumpMessageTests.swift deleted file mode 100644 index a3fd32456..000000000 --- a/MinimedKitTests/PumpMessageTests.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// PumpMessageTests.swift -// RileyLink -// -// Created by Pete Schwamb on 2/28/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -import XCTest -@testable import MinimedKit - - -class PumpMessageTests: XCTestCase { - - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - super.tearDown() - } - -} diff --git a/NightscoutUploadKit/Info.plist b/NightscoutUploadKit/Info.plist index 288c341b6..63c3e67d5 100644 --- a/NightscoutUploadKit/Info.plist +++ b/NightscoutUploadKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index ffa850a91..403aeaa5c 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -18,9 +18,13 @@ public enum UploadError: ErrorType { case MissingTimezone } -public class NightscoutUploader: NSObject { +private let defaultNightscoutEntriesPath = "/api/v1/entries.json" +private let defaultNightscoutTreatmentPath = "/api/v1/treatments.json" +private let defaultNightscoutDeviceStatusPath = "/api/v1/devicestatus.json" - enum DexcomSensorError: UInt8 { +public class NightscoutUploader { + + enum DexcomSensorError: Int { case SensorNotActive = 1 case SensorNotCalibrated = 5 case BadRF = 12 @@ -29,46 +33,35 @@ public class NightscoutUploader: NSObject { public var siteURL: String? public var APISecret: String? - var entries: [AnyObject] - var deviceStatuses: [AnyObject] - var treatmentsQueue: [NightscoutTreatment] + private(set) var entries = [[String: AnyObject]]() + private(set) var deviceStatuses = [[String: AnyObject]]() + private(set) var treatmentsQueue = [NightscoutTreatment]() - var lastMeterMessageRxTime: NSDate? + private(set) var lastMeterMessageRxTime: NSDate? - public private(set) var observingPumpEventsSince: NSDate + public private(set) var observingPumpEventsSince: NSDate! - var lastStoredTreatmentTimestamp: NSDate = NSDate.distantPast() { - didSet { - NSUserDefaults.standardUserDefaults().lastStoredTreatmentTimestamp = lastStoredTreatmentTimestamp + private(set) var lastStoredTreatmentTimestamp: NSDate? { + get { + return NSUserDefaults.standardUserDefaults().lastStoredTreatmentTimestamp + } + set { + NSUserDefaults.standardUserDefaults().lastStoredTreatmentTimestamp = newValue } } - - let defaultNightscoutEntriesPath = "/api/v1/entries.json" - let defaultNightscoutTreatmentPath = "/api/v1/treatments.json" - let defaultNightscoutDeviceStatusPath = "/api/v1/devicestatus.json" - + public var errorHandler: ((error: ErrorType, context: String) -> Void)? - - public var pumpID: String? { - didSet { - if oldValue != nil { - self.observingPumpEventsSince = NSDate().dateByAddingTimeInterval(60*60*24*(-1)) - } - } + + public func reset() { + observingPumpEventsSince = NSDate(timeIntervalSinceNow: NSTimeInterval(hours: -24)) + lastStoredTreatmentTimestamp = nil } - public init(siteURL: String?, APISecret: String?, pumpID: String?) { - entries = [AnyObject]() - treatmentsQueue = [NightscoutTreatment]() - deviceStatuses = [AnyObject]() - + public init(siteURL: String?, APISecret: String?) { self.siteURL = siteURL self.APISecret = APISecret - self.pumpID = pumpID - self.observingPumpEventsSince = NSUserDefaults.standardUserDefaults().lastStoredTreatmentTimestamp ?? NSDate().dateByAddingTimeInterval(60*60*24*(-1)) - - super.init() + observingPumpEventsSince = lastStoredTreatmentTimestamp ?? NSDate(timeIntervalSinceNow: NSTimeInterval(hours: -24)) } // MARK: - Processing data from pump @@ -117,12 +110,6 @@ public class NightscoutUploader: NSObject { public func handlePumpStatus(status: MySentryPumpStatusMessageBody, device: String) { - enum DexcomSensorErrorType: Int { - case DX_SENSOR_NOT_ACTIVE = 1 - case DX_SENSOR_NOT_CALIBRATED = 5 - case DX_BAD_RF = 12 - } - var recordSGV = true let glucose: Int = { @@ -132,12 +119,12 @@ public class NightscoutUploader: NSObject { case .HighBG: return 401 case .WeakSignal: - return DexcomSensorErrorType.DX_BAD_RF.rawValue + return DexcomSensorError.BadRF.rawValue case .MeterBGNow, .CalError: - return DexcomSensorErrorType.DX_SENSOR_NOT_CALIBRATED.rawValue + return DexcomSensorError.SensorNotCalibrated.rawValue case .Lost, .Missing, .Ended, .Unknown, .Off, .Warmup: recordSGV = false - return DexcomSensorErrorType.DX_SENSOR_NOT_ACTIVE.rawValue + return DexcomSensorError.SensorNotActive.rawValue } }() @@ -235,7 +222,7 @@ public class NightscoutUploader: NSObject { let date = NSDate() let epochTime = date.timeIntervalSince1970 * 1000 - let entry = [ + let entry: [String: AnyObject] = [ "date": epochTime, "dateString": TimeFormat.timestampStrFromDate(date), "mbg": msg.glucose, @@ -244,7 +231,7 @@ public class NightscoutUploader: NSObject { ] // Skip duplicates - if lastMeterMessageRxTime == nil || lastMeterMessageRxTime!.timeIntervalSinceNow < -3 * 60 { + if lastMeterMessageRxTime == nil || lastMeterMessageRxTime!.timeIntervalSinceNow.minutes < -3 { entries.append(entry) lastMeterMessageRxTime = NSDate() } @@ -312,7 +299,7 @@ public class NightscoutUploader: NSObject { func flushDeviceStatuses() { let inFlight = deviceStatuses - deviceStatuses = [AnyObject]() + deviceStatuses = [] uploadToNS(inFlight, endpoint: defaultNightscoutDeviceStatusPath) { (error) in if let error = error { self.errorHandler?(error: error, context: "Uploading device status") @@ -324,7 +311,7 @@ public class NightscoutUploader: NSObject { func flushEntries() { let inFlight = entries - entries = [AnyObject]() + entries = [] uploadToNS(inFlight, endpoint: defaultNightscoutEntriesPath) { (error) in if let error = error { self.errorHandler?(error: error, context: "Uploading nightscout entries") @@ -336,7 +323,7 @@ public class NightscoutUploader: NSObject { func flushTreatments() { let inFlight = treatmentsQueue - treatmentsQueue = [NightscoutTreatment]() + treatmentsQueue = [] uploadToNS(inFlight.map({$0.dictionaryRepresentation}), endpoint: defaultNightscoutTreatmentPath) { (error) in if let error = error { self.errorHandler?(error: error, context: "Uploading nightscout treatment records") diff --git a/NightscoutUploadKitTests/Info.plist b/NightscoutUploadKitTests/Info.plist index 96201fb94..3b7334539 100644 --- a/NightscoutUploadKitTests/Info.plist +++ b/NightscoutUploadKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index d20c148df..01b840af0 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -63,6 +63,8 @@ 43B0ADC91D1268B300AAD278 /* TimeFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B0ADC81D1268B300AAD278 /* TimeFormat.swift */; }; 43B0ADCB1D126B1100AAD278 /* SelectBasalProfilePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B0ADCA1D126B1100AAD278 /* SelectBasalProfilePumpEvent.swift */; }; 43B0ADCC1D126E3000AAD278 /* NSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B0ADC31D12506A00AAD278 /* NSDateFormatter.swift */; }; + 43B6E0121D24E2320022E6D7 /* NightscoutPumpEventsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */; }; + 43B6E0161D24E4720022E6D7 /* Crypto.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C12618451CDB019C0064A849 /* Crypto.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 43CA93251CB8BB33000026B5 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43CA93241CB8BB33000026B5 /* CoreBluetooth.framework */; }; 43CA93291CB8CF22000026B5 /* ChangeTempBasalCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CA93281CB8CF22000026B5 /* ChangeTempBasalCarelinkMessageBody.swift */; }; 43CA932B1CB8CF76000026B5 /* ChangeTimeCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CA932A1CB8CF76000026B5 /* ChangeTimeCarelinkMessageBody.swift */; }; @@ -117,7 +119,6 @@ C14303161C97C98000A40450 /* PumpAckMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14303151C97C98000A40450 /* PumpAckMessageBody.swift */; }; C14303181C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14303171C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift */; }; C143031A1C9A610B00A40450 /* GetBatteryCarelinkMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14303191C9A610B00A40450 /* GetBatteryCarelinkMessageBodyTests.swift */; }; - C14C8A801C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */; }; C14D2B051C9F5D5800C98E4C /* TempBasalDurationPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14D2B041C9F5D5800C98E4C /* TempBasalDurationPumpEvent.swift */; }; C14D2B091C9F5EDA00C98E4C /* ChangeTempBasalTypePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14D2B081C9F5EDA00C98E4C /* ChangeTempBasalTypePumpEvent.swift */; }; C16843741CF009E600D53CCD /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843721CF009E600D53CCD /* SettingsTableViewController.swift */; }; @@ -204,6 +205,10 @@ C1B383311CD068C300CE7782 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 430D64CB1CB855AB00FCA750 /* RileyLinkBLEKit.framework */; }; C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */; }; C1B4A94E1D1C423D003B8985 /* NSUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A94D1D1C423D003B8985 /* NSUserDefaults.swift */; }; + C1B4A9551D1E613A003B8985 /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9521D1E613A003B8985 /* TextFieldTableViewCell.swift */; }; + C1B4A9561D1E613A003B8985 /* TextFieldTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C1B4A9531D1E613A003B8985 /* TextFieldTableViewCell.xib */; }; + C1B4A9571D1E613A003B8985 /* TextFieldTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9541D1E613A003B8985 /* TextFieldTableViewController.swift */; }; + C1B4A9591D1E6357003B8985 /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */; }; C1C3578F1C927303009BDD4F /* MeterMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C3578E1C927303009BDD4F /* MeterMessage.swift */; }; C1C357911C92733A009BDD4F /* MeterMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C357901C92733A009BDD4F /* MeterMessageTests.swift */; }; C1E535EA1991E36700C2AC49 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535E91991E36700C2AC49 /* NSData+Conversion.m */; }; @@ -233,7 +238,6 @@ C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */; }; C1EAD6E21C82BA7A006DBA60 /* CRC16.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */; }; C1EAD6E41C82BA87006DBA60 /* CRC16Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */; }; - C1EAD6E61C83966D006DBA60 /* PumpMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6E51C83966D006DBA60 /* PumpMessageTests.swift */; }; C1EB955D1C887FE5002517DF /* HistoryPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EB955C1C887FE5002517DF /* HistoryPage.swift */; }; C1EF58881B3F93FE001C8C80 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58871B3F93FE001C8C80 /* Config.m */; }; /* End PBXBuildFile section */ @@ -312,6 +316,16 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 43B6E0151D24E4610022E6D7 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 43B6E0161D24E4720022E6D7 /* Crypto.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C10D9BB81C82614F00378342 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -534,6 +548,10 @@ C1B3831D1CD0665D00CE7782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceDataManager.swift; sourceTree = ""; }; C1B4A94D1D1C423D003B8985 /* NSUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NSUserDefaults.swift; path = NightscoutUploadKit/NSUserDefaults.swift; sourceTree = SOURCE_ROOT; }; + C1B4A9521D1E613A003B8985 /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = ""; }; + C1B4A9531D1E613A003B8985 /* TextFieldTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextFieldTableViewCell.xib; sourceTree = ""; }; + C1B4A9541D1E613A003B8985 /* TextFieldTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewController.swift; sourceTree = ""; }; + C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewCell.swift; sourceTree = ""; }; C1C3578E1C927303009BDD4F /* MeterMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MeterMessage.swift; path = Messages/MeterMessage.swift; sourceTree = ""; }; C1C357901C92733A009BDD4F /* MeterMessageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MeterMessageTests.swift; path = Messages/MeterMessageTests.swift; sourceTree = ""; }; C1E535E81991E36700C2AC49 /* NSData+Conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Conversion.h"; sourceTree = ""; }; @@ -564,7 +582,6 @@ C1EAD6DF1C82B910006DBA60 /* CRC8Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC8Tests.swift; sourceTree = ""; }; C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC16.swift; sourceTree = ""; }; C1EAD6E31C82BA87006DBA60 /* CRC16Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CRC16Tests.swift; sourceTree = ""; }; - C1EAD6E51C83966D006DBA60 /* PumpMessageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpMessageTests.swift; sourceTree = ""; }; C1EAD6EA1C8409A9006DBA60 /* RileyLink-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RileyLink-Bridging-Header.h"; sourceTree = ""; }; C1EB955C1C887FE5002517DF /* HistoryPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HistoryPage.swift; sourceTree = ""; }; C1EF58861B3F93FE001C8C80 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; @@ -707,8 +724,7 @@ 43722FAF1CB9F7630038B7F2 /* RileyLinkKit */ = { isa = PBXGroup; children = ( - 439731251CF21BB800F474E5 /* Views */, - C170C9951CECD76500F3D8E5 /* ViewControllers */, + C1B4A9511D1E610F003B8985 /* UI */, C170C98C1CECD6CE00F3D8E5 /* Extensions */, 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */, 43722FB21CB9F7640038B7F2 /* Info.plist */, @@ -732,15 +748,6 @@ path = RileyLinkKitTests; sourceTree = ""; }; - 439731251CF21BB800F474E5 /* Views */ = { - isa = PBXGroup; - children = ( - 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */, - 431185A91CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib */, - ); - path = Views; - sourceTree = ""; - }; C10D9BC21C8269D500378342 /* MinimedKit */ = { isa = PBXGroup; children = ( @@ -778,7 +785,6 @@ C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */, 43FF221B1CB9B9DE00024F30 /* NSDateComponents.swift */, 43B0ADBF1D0FC03200AAD278 /* NSDateComponentsTests.swift */, - C1EAD6E51C83966D006DBA60 /* PumpMessageTests.swift */, C1EAD6DB1C82A4AB006DBA60 /* RFToolsTests.swift */, C121985D1C8DE72500BC374C /* Messages */, ); @@ -945,6 +951,7 @@ C170C98C1CECD6CE00F3D8E5 /* Extensions */ = { isa = PBXGroup; children = ( + C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */, C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */, 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */, C170C9901CECD72800F3D8E5 /* NSDate.swift */, @@ -952,15 +959,6 @@ path = Extensions; sourceTree = ""; }; - C170C9951CECD76500F3D8E5 /* ViewControllers */ = { - isa = PBXGroup; - children = ( - C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */, - C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */, - ); - path = ViewControllers; - sourceTree = ""; - }; C1842BB91C8E15C600DB42AC /* PumpEvents */ = { isa = PBXGroup; children = ( @@ -1074,6 +1072,20 @@ name = Managers; sourceTree = ""; }; + C1B4A9511D1E610F003B8985 /* UI */ = { + isa = PBXGroup; + children = ( + C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */, + 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */, + 431185A91CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib */, + C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */, + C1B4A9521D1E613A003B8985 /* TextFieldTableViewCell.swift */, + C1B4A9531D1E613A003B8985 /* TextFieldTableViewCell.xib */, + C1B4A9541D1E613A003B8985 /* TextFieldTableViewController.swift */, + ); + path = UI; + sourceTree = ""; + }; C1EAD6B81C826B92006DBA60 /* Extensions */ = { isa = PBXGroup; children = ( @@ -1348,6 +1360,7 @@ C1B383101CD0665D00CE7782 /* Sources */, C1B383111CD0665D00CE7782 /* Frameworks */, C1B383121CD0665D00CE7782 /* Resources */, + 43B6E0151D24E4610022E6D7 /* CopyFiles */, ); buildRules = ( ); @@ -1452,6 +1465,7 @@ buildActionMask = 2147483647; files = ( 431185AA1CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib in Resources */, + C1B4A9561D1E613A003B8985 /* TextFieldTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1545,6 +1559,8 @@ 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */, C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */, 431185AF1CF25A590059ED98 /* IdentifiableClass.swift in Sources */, + C1B4A9551D1E613A003B8985 /* TextFieldTableViewCell.swift in Sources */, + C1B4A9571D1E613A003B8985 /* TextFieldTableViewController.swift in Sources */, 434AB0C61CBCB41500422F4A /* RileyLinkDevice.swift in Sources */, 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */, 439731271CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift in Sources */, @@ -1556,6 +1572,7 @@ 434AB0BE1CBB4E3200422F4A /* RileyLinkDeviceManager.swift in Sources */, 434AB09E1CBA28F100422F4A /* NSTimeInterval.swift in Sources */, 434AB0951CBA0DF600422F4A /* Either.swift in Sources */, + C1B4A9591D1E6357003B8985 /* UITableViewCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1685,7 +1702,6 @@ C12198611C8DEB7B00BC374C /* DeviceLinkMessageBodyTests.swift in Sources */, C14303181C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift in Sources */, C1EAD6E41C82BA87006DBA60 /* CRC16Tests.swift in Sources */, - C1EAD6E61C83966D006DBA60 /* PumpMessageTests.swift in Sources */, 43CA93311CB97191000026B5 /* ReadTempBasalCarelinkMessageBodyTests.swift in Sources */, 43FF221C1CB9B9DE00024F30 /* NSDateComponents.swift in Sources */, C12198A31C8DFC3600BC374C /* BolusCarelinkMessageBodyTests.swift in Sources */, @@ -1734,7 +1750,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C14C8A801C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift in Sources */, C12EA260198B436900309FA4 /* RileyLinkTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1761,6 +1776,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 43B6E0121D24E2320022E6D7 /* NightscoutPumpEventsTests.swift in Sources */, C1B3831C1CD0665D00CE7782 /* NightscoutUploadKitTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1847,11 +1863,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -1875,11 +1891,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -1938,11 +1954,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -1968,11 +1984,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -2031,11 +2047,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -2060,11 +2076,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -2133,7 +2149,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -2175,7 +2191,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -2280,11 +2296,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -2313,11 +2329,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 7; + CURRENT_PROJECT_VERSION = 8; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 7; + DYLIB_CURRENT_VERSION = 8; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -2344,6 +2360,10 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = NightscoutUploadKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2363,6 +2383,10 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = NightscoutUploadKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; diff --git a/RileyLink.xcodeproj/xcshareddata/xcschemes/RileyLink.xcscheme b/RileyLink.xcodeproj/xcshareddata/xcschemes/RileyLink.xcscheme index c4d936820..0ba0ae26f 100644 --- a/RileyLink.xcodeproj/xcshareddata/xcschemes/RileyLink.xcscheme +++ b/RileyLink.xcodeproj/xcshareddata/xcschemes/RileyLink.xcscheme @@ -82,6 +82,16 @@ ReferencedContainer = "container:RileyLink.xcodeproj"> + + + + Void in print("Error \(error), while \(context)") } - nightscoutUploader.pumpID = pumpID getHistoryTimer = NSTimer.scheduledTimerWithTimeInterval(5.0 * 60, target:self, selector:#selector(DeviceDataManager.timerTriggered), userInfo:nil, repeats:true) diff --git a/RileyLink/RileyLink-Info.plist b/RileyLink/RileyLink-Info.plist index 64710dbec..a505ceaa6 100644 --- a/RileyLink/RileyLink-Info.plist +++ b/RileyLink/RileyLink-Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLink/RileyLinkListTableViewController.swift b/RileyLink/RileyLinkListTableViewController.swift index fa56bdb23..a5d3fe985 100644 --- a/RileyLink/RileyLinkListTableViewController.swift +++ b/RileyLink/RileyLinkListTableViewController.swift @@ -24,11 +24,9 @@ class RileyLinkListTableViewController: UITableViewController { switch note.name { case RileyLinkDeviceManager.DidDiscoverDeviceNotification: self?.tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: deviceManager.devices.count - 1, inSection: 0)], withRowAnimation: .Automatic) - case RileyLinkDeviceManager.ConnectionStateDidChangeNotification: - if let device = note.userInfo?[RileyLinkDeviceManager.RileyLinkDeviceKey] as? RileyLinkDevice, index = deviceManager.devices.indexOf({ $0 === device }) { - self?.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: 0)], withRowAnimation: .None) - } - case RileyLinkDeviceManager.RSSIDidChangeNotification: + case RileyLinkDeviceManager.ConnectionStateDidChangeNotification, + RileyLinkDeviceManager.RSSIDidChangeNotification, + RileyLinkDeviceManager.NameDidChangeNotification: if let device = note.userInfo?[RileyLinkDeviceManager.RileyLinkDeviceKey] as? RileyLinkDevice, index = deviceManager.devices.indexOf({ $0 === device }) { self?.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: 0)], withRowAnimation: .None) } diff --git a/RileyLinkBLEKit/Info.plist b/RileyLinkBLEKit/Info.plist index 288c341b6..63c3e67d5 100644 --- a/RileyLinkBLEKit/Info.plist +++ b/RileyLinkBLEKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkBLEKit/RileyLinkBLEDevice.m b/RileyLinkBLEKit/RileyLinkBLEDevice.m index 00ab4ec1e..ef09c8474 100644 --- a/RileyLinkBLEKit/RileyLinkBLEDevice.m +++ b/RileyLinkBLEKit/RileyLinkBLEDevice.m @@ -268,6 +268,10 @@ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForServi [self setCharacteristicsFromService:service]; } +- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral { + [[NSNotificationCenter defaultCenter] postNotificationName:RILEYLINK_EVENT_NAME_CHANGED object:self userInfo:@{@"Name": peripheral.name}]; +} + - (void)checkVersion { [self runSession:^(RileyLinkCmdSession * _Nonnull s) { GetVersionCmd *cmd = [[GetVersionCmd alloc] init]; @@ -426,10 +430,6 @@ - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForChara NSLog(@"Updated notification state for %@, %@", characteristic, error); } -- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral { - [[NSNotificationCenter defaultCenter] postNotificationName:RILEYLINK_EVENT_LIST_UPDATED object:nil]; -} - - (void)cleanup { NSLog(@"Entering cleanup"); diff --git a/RileyLinkBLEKit/RileyLinkBLEManager.h b/RileyLinkBLEKit/RileyLinkBLEManager.h index e960af155..0451eda3e 100644 --- a/RileyLinkBLEKit/RileyLinkBLEManager.h +++ b/RileyLinkBLEKit/RileyLinkBLEManager.h @@ -18,6 +18,7 @@ #define RILEYLINK_EVENT_DEVICE_READY @"RILEYLINK_EVENT_DEVICE_READY" #define RILEYLINK_EVENT_DEVICE_TIMER_TICK @"RILEYLINK_EVENT_DEVICE_TIMER_TICK" #define RILEYLINK_EVENT_RSSI_CHANGED @"RILEYLINK_EVENT_RSSI_CHANGED" +#define RILEYLINK_EVENT_NAME_CHANGED @"RILEYLINK_EVENT_NAME_CHANGED" #define RILEYLINK_SERVICE_UUID @"0235733b-99c5-4197-b856-69219c2a3845" #define RILEYLINK_DATA_UUID @"c842e849-5028-42e2-867c-016adada9155" diff --git a/RileyLinkBLEKitTests/Info.plist b/RileyLinkBLEKitTests/Info.plist index 94b6ed951..87f0ed731 100644 --- a/RileyLinkBLEKitTests/Info.plist +++ b/RileyLinkBLEKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKit/Extensions/UITableViewCell.swift b/RileyLinkKit/Extensions/UITableViewCell.swift new file mode 100644 index 000000000..269425371 --- /dev/null +++ b/RileyLinkKit/Extensions/UITableViewCell.swift @@ -0,0 +1,13 @@ +// +// UITableViewCell.swift +// CarbKit +// +// Created by Nathan Racklyeft on 1/15/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit + + +extension UITableViewCell: IdentifiableClass { +} diff --git a/RileyLinkKit/Info.plist b/RileyLinkKit/Info.plist index 288c341b6..63c3e67d5 100644 --- a/RileyLinkKit/Info.plist +++ b/RileyLinkKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index 108fc9511..acf3331aa 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -78,7 +78,7 @@ public class PumpOps { - parameter completion: A closure called after the command is complete. This closure takes a single Result argument: - Success(units): The reservoir volume, in units of insulin - - Failure(error): An error describing why the command failed. + - Failure(error): An error describing why the command failed */ public func readRemainingInsulin(completion: (Either) -> Void) { device.runSession { (session) in @@ -112,7 +112,30 @@ public class PumpOps { } } } - + + /** + Reads the pump's clock + + This operation is performed asynchronously and the completion will be executed on an arbitrary background queue. + + - parameter completion: A closure called after the command is complete. This closure takes a single Result argument: + - Success(clock): The pump's clock + - Failure(error): An error describing why the command failed + */ + public func readTime(completion: (Either) -> Void) { + device.runSession { (session) in + let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) + + do { + let response: ReadTimeCarelinkMessageBody = try ops.getMessageBodyWithType(.ReadTime) + + completion(.Success(response.dateComponents)) + } catch let error { + completion(.Failure(error)) + } + } + } + /** Sets a bolus diff --git a/RileyLinkKit/RileyLinkDevice.swift b/RileyLinkKit/RileyLinkDevice.swift index 6f63f170c..f728f2d6e 100644 --- a/RileyLinkKit/RileyLinkDevice.swift +++ b/RileyLinkKit/RileyLinkDevice.swift @@ -103,6 +103,10 @@ public class RileyLinkDevice { resultHandler(.Failure(Error.ConfigurationError)) } } + + public func setCustomName(name: String) { + device.setCustomName(name) + } public var ops: PumpOps? { if let pumpState = pumpState { diff --git a/RileyLinkKit/RileyLinkDeviceManager.swift b/RileyLinkKit/RileyLinkDeviceManager.swift index 3ac41dc65..e5b76ea59 100644 --- a/RileyLinkKit/RileyLinkDeviceManager.swift +++ b/RileyLinkKit/RileyLinkDeviceManager.swift @@ -17,10 +17,12 @@ public class RileyLinkDeviceManager { public static let ConnectionStateDidChangeNotification = "com.rileylink.RileyLinkKit.ConnectionStateDidChangeNotification" public static let RSSIDidChangeNotification = "com.rileylink.RileyLinkKit.RSSIDidChangeNotification" + public static let NameDidChangeNotification = "com.rileylink.RileyLinkKit.NameDidChangeNotification" public static let RileyLinkDeviceKey = "com.rileylink.RileyLinkKit.RileyLinkDevice" public static let RileyLinkRSSIKey = "com.rileylink.RileyLinkKit.RileyLinkRSSI" - + public static let RileyLinkNameKey = "com.rileylink.RileyLinkKit.RileyLinkName" + public var pumpState: PumpState? { didSet { for device in _devices { @@ -41,8 +43,10 @@ public class RileyLinkDeviceManager { NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(connectionStateDidChange(_:)), name: RILEYLINK_EVENT_DEVICE_DISCONNECTED, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rssiDidChange(_:)), name: RILEYLINK_EVENT_RSSI_CHANGED, object: nil) + + NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(nameDidChange(_:)), name: RILEYLINK_EVENT_NAME_CHANGED, object: nil) } - + public var deviceScanningEnabled: Bool { get { return BLEManager.scanningEnabled @@ -135,5 +139,14 @@ public class RileyLinkDeviceManager { NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.RSSIDidChangeNotification, object: self, userInfo: [self.dynamicType.RileyLinkDeviceKey: device, self.dynamicType.RileyLinkRSSIKey: note.userInfo!["RSSI"]!]) } } - + + @objc private func nameDidChange(note: NSNotification) { + if let BLEDevice = note.object as? RileyLinkBLEDevice, + index = _devices.indexOf({ $0.peripheral == BLEDevice.peripheral }) { + let device = _devices[index] + + NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.NameDidChangeNotification, object: self, userInfo: [self.dynamicType.RileyLinkDeviceKey: device, self.dynamicType.RileyLinkNameKey: note.userInfo!["Name"]!]) + } + } + } \ No newline at end of file diff --git a/RileyLinkKit/UI/CommandResponseViewController.swift b/RileyLinkKit/UI/CommandResponseViewController.swift new file mode 100644 index 000000000..2e9f94e4c --- /dev/null +++ b/RileyLinkKit/UI/CommandResponseViewController.swift @@ -0,0 +1,63 @@ +// +// CommandResponseViewController.swift +// Naterade +// +// Created by Nathan Racklyeft on 3/5/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit + +class CommandResponseViewController: UIViewController, UIActivityItemSource { + typealias Command = (completionHandler: (responseText: String) -> Void) -> String + + init(command: Command) { + self.command = command + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private let command: Command + + private lazy var textView = UITextView() + + override func loadView() { + self.view = textView + } + + override func viewDidLoad() { + super.viewDidLoad() + + textView.font = UIFont(name: "Menlo-Regular", size: 14) + textView.text = command { [weak self] (responseText) -> Void in + self?.textView.text = responseText + } + textView.editable = false + + navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: #selector(shareText(_:))) + } + + @objc func shareText(_: AnyObject?) { + let activityVC = UIActivityViewController(activityItems: [self], applicationActivities: nil) + + presentViewController(activityVC, animated: true, completion: nil) + } + + // MARK: - UIActivityItemSource + + func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject { + return title ?? textView.text + } + + func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? { + return textView.attributedText + } + + func activityViewController(activityViewController: UIActivityViewController, subjectForActivityType activityType: String?) -> String { + return title ?? textView.text + } +} diff --git a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift b/RileyLinkKit/UI/RileyLinkDeviceTableViewCell.swift similarity index 96% rename from RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift rename to RileyLinkKit/UI/RileyLinkDeviceTableViewCell.swift index 6538d7a3a..1cb136c6d 100644 --- a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift +++ b/RileyLinkKit/UI/RileyLinkDeviceTableViewCell.swift @@ -54,5 +54,4 @@ public class RileyLinkDeviceTableViewCell: UITableViewCell { } -extension RileyLinkDeviceTableViewCell: IdentifiableClass { } diff --git a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib b/RileyLinkKit/UI/RileyLinkDeviceTableViewCell.xib similarity index 98% rename from RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib rename to RileyLinkKit/UI/RileyLinkDeviceTableViewCell.xib index 284ad6573..9dd87b441 100644 --- a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib +++ b/RileyLinkKit/UI/RileyLinkDeviceTableViewCell.xib @@ -1,5 +1,5 @@ - + diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/UI/RileyLinkDeviceTableViewController.swift similarity index 87% rename from RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift rename to RileyLinkKit/UI/RileyLinkDeviceTableViewController.swift index 41af1b8d3..4d49db0f4 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/UI/RileyLinkDeviceTableViewController.swift @@ -11,7 +11,7 @@ import MinimedKit let CellIdentifier = "Cell" -public class RileyLinkDeviceTableViewController: UITableViewController { +public class RileyLinkDeviceTableViewController: UITableViewController, TextFieldTableViewControllerDelegate { public var device: RileyLinkDevice! @@ -25,8 +25,35 @@ public class RileyLinkDeviceTableViewController: UITableViewController { super.viewDidLoad() title = device.name + + self.observe() + } + + // References to registered notification center observers + deinit { + deviceObserver = nil } + private var deviceObserver: AnyObject? { + willSet { + if let observer = deviceObserver { + NSNotificationCenter.defaultCenter().removeObserver(observer) + } + } + } + + private func observe() { + let center = NSNotificationCenter.defaultCenter() + + deviceObserver = center.addObserverForName(RileyLinkDeviceManager.NameDidChangeNotification, object: nil, queue: nil) { [weak self = self] (note) -> Void in + + let indexPath = NSIndexPath(forRow: DeviceRow.CustomName.rawValue, inSection: Section.Device.rawValue) + self?.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) + self?.title = self?.device.name + } + } + + public override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) @@ -70,12 +97,13 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } private enum DeviceRow: Int { + case CustomName case Version case RSSI case Connection case IdleStatus - static let count = 4 + static let count = 5 } private enum PumpRow: Int { @@ -131,6 +159,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { switch Section(rawValue: indexPath.section)! { case .Device: switch DeviceRow(rawValue: indexPath.row)! { + case .CustomName: + cell.textLabel?.text = NSLocalizedString("Name", comment: "The title of the cell showing device name") + cell.detailTextLabel?.text = device.name + cell.accessoryType = .DisclosureIndicator case .Version: cell.textLabel?.text = NSLocalizedString("Firmware Version", comment: "The title of the cell showing firmware version") cell.detailTextLabel?.text = device.firmwareVersion @@ -247,7 +279,14 @@ public class RileyLinkDeviceTableViewController: UITableViewController { public override func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool { switch Section(rawValue: indexPath.section)! { - case .Device, .Pump: + case .Device: + switch DeviceRow(rawValue: indexPath.row)! { + case .CustomName: + return true + default: + return false + } + case .Pump: return false case .Commands: return device.peripheral.state == .Connected @@ -256,6 +295,21 @@ public class RileyLinkDeviceTableViewController: UITableViewController { public override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { switch Section(rawValue: indexPath.section)! { + case .Device: + switch DeviceRow(rawValue: indexPath.row)! { + case .CustomName: + let vc = TextFieldTableViewController() + if let cell = tableView.cellForRowAtIndexPath(indexPath) { + vc.title = cell.textLabel?.text + vc.value = device.name + vc.delegate = self + vc.keyboardType = .Default + } + + showViewController(vc, sender: indexPath) + default: + break + } case .Commands: let vc: CommandResponseViewController @@ -414,8 +468,32 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } showViewController(vc, sender: indexPath) - case .Device, .Pump: + case .Pump: break } } + + // MARK: - TextFieldTableViewControllerDelegate + + func textFieldTableViewControllerDidReturn(controller: TextFieldTableViewController) { + navigationController?.popViewControllerAnimated(true) + } + + func textFieldTableViewControllerDidEndEditing(controller: TextFieldTableViewController) { + if let indexPath = tableView.indexPathForSelectedRow { + switch Section(rawValue: indexPath.section)! { + case .Device: + switch DeviceRow(rawValue: indexPath.row)! { + case .CustomName: + device.setCustomName(controller.value!) + default: + break + } + default: + break + + } + } + } + } diff --git a/RileyLinkKit/UI/TextFieldTableViewCell.swift b/RileyLinkKit/UI/TextFieldTableViewCell.swift new file mode 100644 index 000000000..da70589d7 --- /dev/null +++ b/RileyLinkKit/UI/TextFieldTableViewCell.swift @@ -0,0 +1,24 @@ +// +// TextFieldTableViewCell.swift +// Naterade +// +// Created by Nathan Racklyeft on 5/22/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit + +class TextFieldTableViewCell: UITableViewCell { + + @IBOutlet var textField: UITextField! + + static func nib() -> UINib { + return UINib(nibName: className, bundle: NSBundle(forClass: self)) + } + + override func prepareForReuse() { + super.prepareForReuse() + + textField.delegate = nil + } +} diff --git a/RileyLinkKit/UI/TextFieldTableViewCell.xib b/RileyLinkKit/UI/TextFieldTableViewCell.xib new file mode 100644 index 000000000..9084ff9a5 --- /dev/null +++ b/RileyLinkKit/UI/TextFieldTableViewCell.xib @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RileyLinkKit/UI/TextFieldTableViewController.swift b/RileyLinkKit/UI/TextFieldTableViewController.swift new file mode 100644 index 000000000..780d65c63 --- /dev/null +++ b/RileyLinkKit/UI/TextFieldTableViewController.swift @@ -0,0 +1,89 @@ +// +// TextFieldTableViewController.swift +// Naterade +// +// Created by Nathan Racklyeft on 8/30/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import UIKit + + +internal protocol TextFieldTableViewControllerDelegate: class { + func textFieldTableViewControllerDidEndEditing(controller: TextFieldTableViewController) + + func textFieldTableViewControllerDidReturn(controller: TextFieldTableViewController) +} + + +internal class TextFieldTableViewController: UITableViewController, UITextFieldDelegate { + + private weak var textField: UITextField? + + internal var indexPath: NSIndexPath? + + internal var placeholder: String? + + internal var value: String? { + didSet { + delegate?.textFieldTableViewControllerDidEndEditing(self) + } + } + + internal var keyboardType = UIKeyboardType.Default + + internal weak var delegate: TextFieldTableViewControllerDelegate? + + internal convenience init() { + self.init(style: .Grouped) + } + + internal override func viewDidLoad() { + super.viewDidLoad() + + tableView.registerNib(TextFieldTableViewCell.nib(), forCellReuseIdentifier: TextFieldTableViewCell.className) + } + + internal override func viewDidAppear(animated: Bool) { + super.viewDidAppear(animated) + + textField?.becomeFirstResponder() + } + + // MARK: - UITableViewDataSource + + internal override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + internal override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCellWithIdentifier(TextFieldTableViewCell.className, forIndexPath: indexPath) as! TextFieldTableViewCell + + textField = cell.textField + + cell.textField.delegate = self + cell.textField.text = value + cell.textField.keyboardType = keyboardType + cell.textField.placeholder = placeholder + cell.textField.autocapitalizationType = .Words + + return cell + } + + // MARK: - UITextFieldDelegate + + internal func textFieldShouldEndEditing(textField: UITextField) -> Bool { + value = textField.text + + return true + } + + internal func textFieldShouldReturn(textField: UITextField) -> Bool { + value = textField.text + + textField.delegate = nil + delegate?.textFieldTableViewControllerDidReturn(self) + + return false + } +} diff --git a/RileyLinkKit/ViewControllers/CommandResponseViewController.swift b/RileyLinkKit/ViewControllers/CommandResponseViewController.swift deleted file mode 100644 index f0a1b4e59..000000000 --- a/RileyLinkKit/ViewControllers/CommandResponseViewController.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// CommandResponseViewController.swift -// Naterade -// -// Created by Nathan Racklyeft on 3/5/16. -// Copyright © 2016 Nathan Racklyeft. All rights reserved. -// - -import UIKit - -class CommandResponseViewController: UIViewController { - typealias Command = (completionHandler: (responseText: String) -> Void) -> String - - init(command: Command) { - self.command = command - - super.init(nibName: nil, bundle: nil) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private let command: Command - - private lazy var textView = UITextView() - - override func loadView() { - self.view = textView - } - - override func viewDidLoad() { - super.viewDidLoad() - - textView.font = UIFont(name: "Menlo-Regular", size: 14) - textView.text = command { [weak self] (responseText) -> Void in - self?.textView.text = responseText - } - } - -} diff --git a/RileyLinkKitTests/Info.plist b/RileyLinkKitTests/Info.plist index 94b6ed951..87f0ed731 100644 --- a/RileyLinkKitTests/Info.plist +++ b/RileyLinkKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkTests/RileyLinkTests-Info.plist b/RileyLinkTests/RileyLinkTests-Info.plist index f3119ec14..a5d549740 100644 --- a/RileyLinkTests/RileyLinkTests-Info.plist +++ b/RileyLinkTests/RileyLinkTests-Info.plist @@ -13,7 +13,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.5.0 + 0.6.0 CFBundleSignature ???? CFBundleVersion