From dc53d29691970427921d0839cfc371c5cff92d59 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 26 Apr 2016 22:25:17 -0500 Subject: [PATCH 01/40] making nightscoutuploadkit a framework --- .gitignore | 1 + .../BGCheckNightscoutTreatment.swift | 0 .../BolusNightscoutTreatment.swift | 0 .../Extensions/StringCrypto.swift | 0 NightscoutUploadKit/Info.plist | 26 ++ .../MealBolusNightscoutTreatment.swift | 0 .../NightscoutPumpEvents.swift | 0 .../NightscoutTreatment.swift | 0 NightscoutUploadKit/NightscoutUploadKit.h | 19 + .../NightscoutUploader.swift | 5 +- .../TempBasalNightscoutTreatment.swift | 0 NightscoutUploadKitTests/Info.plist | 24 ++ .../NightscoutUploadKitTests.swift | 36 ++ RileyLink.xcodeproj/project.pbxproj | 330 ++++++++++++++++-- .../xcschemes/NightscoutUploadKit.xcscheme | 80 +++++ .../xcshareddata/xcschemes/RileyLink.xcscheme | 10 + RileyLink/Log.m | 3 + 17 files changed, 506 insertions(+), 28 deletions(-) rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/BGCheckNightscoutTreatment.swift (100%) rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/BolusNightscoutTreatment.swift (100%) rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/Extensions/StringCrypto.swift (100%) create mode 100644 NightscoutUploadKit/Info.plist rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/MealBolusNightscoutTreatment.swift (100%) rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/NightscoutPumpEvents.swift (100%) rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/NightscoutTreatment.swift (100%) create mode 100644 NightscoutUploadKit/NightscoutUploadKit.h rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/NightscoutUploader.swift (99%) rename {RileyLink/NightscoutUploadKit => NightscoutUploadKit}/TempBasalNightscoutTreatment.swift (100%) create mode 100644 NightscoutUploadKitTests/Info.plist create mode 100644 NightscoutUploadKitTests/NightscoutUploadKitTests.swift create mode 100644 RileyLink.xcodeproj/xcshareddata/xcschemes/NightscoutUploadKit.xcscheme diff --git a/.gitignore b/.gitignore index 63764e753..f622aaf6b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ DerivedData *.xcuserstate *.xcscmblueprint .DS_Store +*.log # CocoaPods # diff --git a/RileyLink/NightscoutUploadKit/BGCheckNightscoutTreatment.swift b/NightscoutUploadKit/BGCheckNightscoutTreatment.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/BGCheckNightscoutTreatment.swift rename to NightscoutUploadKit/BGCheckNightscoutTreatment.swift diff --git a/RileyLink/NightscoutUploadKit/BolusNightscoutTreatment.swift b/NightscoutUploadKit/BolusNightscoutTreatment.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/BolusNightscoutTreatment.swift rename to NightscoutUploadKit/BolusNightscoutTreatment.swift diff --git a/RileyLink/NightscoutUploadKit/Extensions/StringCrypto.swift b/NightscoutUploadKit/Extensions/StringCrypto.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/Extensions/StringCrypto.swift rename to NightscoutUploadKit/Extensions/StringCrypto.swift diff --git a/NightscoutUploadKit/Info.plist b/NightscoutUploadKit/Info.plist new file mode 100644 index 000000000..d3de8eefb --- /dev/null +++ b/NightscoutUploadKit/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/RileyLink/NightscoutUploadKit/MealBolusNightscoutTreatment.swift b/NightscoutUploadKit/MealBolusNightscoutTreatment.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/MealBolusNightscoutTreatment.swift rename to NightscoutUploadKit/MealBolusNightscoutTreatment.swift diff --git a/RileyLink/NightscoutUploadKit/NightscoutPumpEvents.swift b/NightscoutUploadKit/NightscoutPumpEvents.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/NightscoutPumpEvents.swift rename to NightscoutUploadKit/NightscoutPumpEvents.swift diff --git a/RileyLink/NightscoutUploadKit/NightscoutTreatment.swift b/NightscoutUploadKit/NightscoutTreatment.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/NightscoutTreatment.swift rename to NightscoutUploadKit/NightscoutTreatment.swift diff --git a/NightscoutUploadKit/NightscoutUploadKit.h b/NightscoutUploadKit/NightscoutUploadKit.h new file mode 100644 index 000000000..be643b1b3 --- /dev/null +++ b/NightscoutUploadKit/NightscoutUploadKit.h @@ -0,0 +1,19 @@ +// +// NightscoutUploadKit.h +// NightscoutUploadKit +// +// Created by Pete Schwamb on 4/26/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +#import + +//! Project version number for NightscoutUploadKit. +FOUNDATION_EXPORT double NightscoutUploadKitVersionNumber; + +//! Project version string for NightscoutUploadKit. +FOUNDATION_EXPORT const unsigned char NightscoutUploadKitVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/RileyLink/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift similarity index 99% rename from RileyLink/NightscoutUploadKit/NightscoutUploader.swift rename to NightscoutUploadKit/NightscoutUploader.swift index b0a7ace56..8b3da9797 100644 --- a/RileyLink/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -8,8 +8,8 @@ import UIKit import MinimedKit -import RileyLinkKit -import RileyLinkBLEKit +//import RileyLinkKit +//import RileyLinkBLEKit class NightScoutUploader: NSObject { @@ -120,7 +120,6 @@ class NightScoutUploader: NSObject { } func timerTriggered() { - logMemUsage() if lastHistoryAttempt == nil || lastHistoryAttempt!.timeIntervalSinceNow < (-5 * 60) && !fetchHistoryScheduled { NSLog("No fetchHistory for over five minutes. Triggering one") diff --git a/RileyLink/NightscoutUploadKit/TempBasalNightscoutTreatment.swift b/NightscoutUploadKit/TempBasalNightscoutTreatment.swift similarity index 100% rename from RileyLink/NightscoutUploadKit/TempBasalNightscoutTreatment.swift rename to NightscoutUploadKit/TempBasalNightscoutTreatment.swift diff --git a/NightscoutUploadKitTests/Info.plist b/NightscoutUploadKitTests/Info.plist new file mode 100644 index 000000000..ba72822e8 --- /dev/null +++ b/NightscoutUploadKitTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/NightscoutUploadKitTests/NightscoutUploadKitTests.swift b/NightscoutUploadKitTests/NightscoutUploadKitTests.swift new file mode 100644 index 000000000..a4ecf184a --- /dev/null +++ b/NightscoutUploadKitTests/NightscoutUploadKitTests.swift @@ -0,0 +1,36 @@ +// +// NightscoutUploadKitTests.swift +// NightscoutUploadKitTests +// +// Created by Pete Schwamb on 4/26/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import XCTest +@testable import NightscoutUploadKit + +class NightscoutUploadKitTests: 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() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measureBlock { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 5885c7da8..1fcd1d132 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -105,7 +105,6 @@ C12EA260198B436900309FA4 /* RileyLinkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C12EA25F198B436900309FA4 /* RileyLinkTests.m */; }; C12EA26A198B442100309FA4 /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C12EA269198B442100309FA4 /* Storyboard.storyboard */; }; C12EA26D198B456D00309FA4 /* NightscoutWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12EA26C198B456D00309FA4 /* NightscoutWebView.m */; }; - C12FB2761CC5893C00879B80 /* TempBasalNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12FB2751CC5893C00879B80 /* TempBasalNightscoutTreatment.swift */; }; C139AC241BFD84B500B0518F /* RuntimeUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = C139AC231BFD84B500B0518F /* RuntimeUtils.m */; }; C14303161C97C98000A40450 /* PumpAckMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14303151C97C98000A40450 /* PumpAckMessageBody.swift */; }; C14303181C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14303171C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift */; }; @@ -172,17 +171,24 @@ C1842C231C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BF91C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift */; }; C1842C241C8FA45100DB42AC /* BatteryPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFA1C8FA45100DB42AC /* BatteryPumpEvent.swift */; }; C1842C251C8FA45100DB42AC /* AlarmSensorPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFB1C8FA45100DB42AC /* AlarmSensorPumpEvent.swift */; }; - C1842C291C908A3C00DB42AC /* NightscoutUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */; }; - C1842C2B1C90DFB600DB42AC /* NightscoutPumpEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */; }; - C1842C2F1C90F6D900DB42AC /* NightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C2E1C90F6D900DB42AC /* NightscoutTreatment.swift */; }; - C1842C311C91D56400DB42AC /* BGCheckNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C301C91D56400DB42AC /* BGCheckNightscoutTreatment.swift */; }; - C1842C331C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C321C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift */; }; C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */; }; - C19F94AB1C91DF6E00018F7D /* BolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */; }; C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = C1AA39931AB6804000BC9E33 /* UIAlertView+Blocks.m */; }; + C1B3830E1CD0665D00CE7782 /* NightscoutUploadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C1B3830D1CD0665D00CE7782 /* NightscoutUploadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C1B383151CD0665D00CE7782 /* NightscoutUploadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */; }; + C1B3831C1CD0665D00CE7782 /* NightscoutUploadKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */; }; + C1B383201CD0665D00CE7782 /* NightscoutUploadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */; }; + C1B383211CD0665D00CE7782 /* NightscoutUploadKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + C1B383281CD0668600CE7782 /* NightscoutUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */; }; + C1B383291CD0668600CE7782 /* NightscoutPumpEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */; }; + C1B3832A1CD0668600CE7782 /* NightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C2E1C90F6D900DB42AC /* NightscoutTreatment.swift */; }; + C1B3832B1CD0668600CE7782 /* BGCheckNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C301C91D56400DB42AC /* BGCheckNightscoutTreatment.swift */; }; + C1B3832C1CD0668600CE7782 /* MealBolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C321C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift */; }; + C1B3832D1CD0668600CE7782 /* BolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */; }; + C1B3832E1CD0668600CE7782 /* TempBasalNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12FB2751CC5893C00879B80 /* TempBasalNightscoutTreatment.swift */; }; + C1B3832F1CD0668F00CE7782 /* StringCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C357931C929529009BDD4F /* StringCrypto.swift */; }; + C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; C1C3578F1C927303009BDD4F /* MeterMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C3578E1C927303009BDD4F /* MeterMessage.swift */; }; C1C357911C92733A009BDD4F /* MeterMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C357901C92733A009BDD4F /* MeterMessageTests.swift */; }; - C1C357941C929529009BDD4F /* StringCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C357931C929529009BDD4F /* StringCrypto.swift */; }; C1E535EA1991E36700C2AC49 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535E91991E36700C2AC49 /* NSData+Conversion.m */; }; C1EAD6B31C826B6D006DBA60 /* AlertType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */; }; C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */; }; @@ -269,6 +275,27 @@ remoteGlobalIDString = C12EA236198B436800309FA4; remoteInfo = RileyLink; }; + C1B383161CD0665D00CE7782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C1B3830A1CD0665D00CE7782; + remoteInfo = NightscoutUploadKit; + }; + C1B383181CD0665D00CE7782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C12EA236198B436800309FA4; + remoteInfo = RileyLink; + }; + C1B3831E1CD0665D00CE7782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C1B3830A1CD0665D00CE7782; + remoteInfo = NightscoutUploadKit; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -280,6 +307,7 @@ files = ( 43722FC41CB9F7640038B7F2 /* RileyLinkKit.framework in Embed Frameworks */, C10D9BD71C8269D500378342 /* MinimedKit.framework in Embed Frameworks */, + C1B383211CD0665D00CE7782 /* NightscoutUploadKit.framework in Embed Frameworks */, 430D64E11CB855AB00FCA750 /* RileyLinkBLEKit.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -478,6 +506,12 @@ C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusNightscoutTreatment.swift; sourceTree = ""; }; C1AA39921AB6804000BC9E33 /* UIAlertView+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+Blocks.h"; sourceTree = ""; }; C1AA39931AB6804000BC9E33 /* UIAlertView+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Blocks.m"; sourceTree = ""; }; + C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NightscoutUploadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C1B3830D1CD0665D00CE7782 /* NightscoutUploadKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NightscoutUploadKit.h; sourceTree = ""; }; + C1B3830F1CD0665D00CE7782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C1B383141CD0665D00CE7782 /* NightscoutUploadKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NightscoutUploadKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadKitTests.swift; sourceTree = ""; }; + C1B3831D1CD0665D00CE7782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 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 = ""; }; C1C357931C929529009BDD4F /* StringCrypto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringCrypto.swift; sourceTree = ""; }; @@ -577,6 +611,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C1B383201CD0665D00CE7782 /* NightscoutUploadKit.framework in Frameworks */, 430D64E01CB855AB00FCA750 /* RileyLinkBLEKit.framework in Frameworks */, C12EA23D198B436800309FA4 /* CoreGraphics.framework in Frameworks */, C12EA23F198B436800309FA4 /* UIKit.framework in Frameworks */, @@ -597,6 +632,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C1B383071CD0665D00CE7782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C1B383111CD0665D00CE7782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C1B383151CD0665D00CE7782 /* NightscoutUploadKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -774,6 +825,8 @@ 430D64DA1CB855AB00FCA750 /* RileyLinkBLEKitTests */, 43722FAF1CB9F7630038B7F2 /* RileyLinkKit */, 43722FBD1CB9F7640038B7F2 /* RileyLinkKitTests */, + C1B3830C1CD0665D00CE7782 /* NightscoutUploadKit */, + C1B3831A1CD0665D00CE7782 /* NightscoutUploadKitTests */, C12EA239198B436800309FA4 /* Frameworks */, C12EA238198B436800309FA4 /* Products */, ); @@ -790,6 +843,8 @@ 430D64D41CB855AB00FCA750 /* RileyLinkBLEKitTests.xctest */, 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */, 43722FB71CB9F7640038B7F2 /* RileyLinkKitTests.xctest */, + C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */, + C1B383141CD0665D00CE7782 /* NightscoutUploadKitTests.xctest */, ); name = Products; sourceTree = ""; @@ -863,13 +918,6 @@ name = "Supporting Files"; sourceTree = ""; }; - C12FB2741CC588FB00879B80 /* Treatments */ = { - isa = PBXGroup; - children = ( - ); - name = Treatments; - sourceTree = ""; - }; C1842BB91C8E15C600DB42AC /* PumpEvents */ = { isa = PBXGroup; children = ( @@ -945,6 +993,24 @@ name = Categories; sourceTree = ""; }; + C1B3830C1CD0665D00CE7782 /* NightscoutUploadKit */ = { + isa = PBXGroup; + children = ( + C1B3830D1CD0665D00CE7782 /* NightscoutUploadKit.h */, + C1B3830F1CD0665D00CE7782 /* Info.plist */, + ); + path = NightscoutUploadKit; + sourceTree = ""; + }; + C1B3831A1CD0665D00CE7782 /* NightscoutUploadKitTests */ = { + isa = PBXGroup; + children = ( + C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */, + C1B3831D1CD0665D00CE7782 /* Info.plist */, + ); + path = NightscoutUploadKitTests; + sourceTree = ""; + }; C1C357921C929507009BDD4F /* Extensions */ = { isa = PBXGroup; children = ( @@ -1027,7 +1093,6 @@ C1EF589B1B3FBA5D001C8C80 /* NightscoutUploadKit */ = { isa = PBXGroup; children = ( - C12FB2741CC588FB00879B80 /* Treatments */, C1C357921C929507009BDD4F /* Extensions */, C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */, C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */, @@ -1037,7 +1102,8 @@ C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */, C12FB2751CC5893C00879B80 /* TempBasalNightscoutTreatment.swift */, ); - path = NightscoutUploadKit; + name = NightscoutUploadKit; + path = ../NightscoutUploadKit; sourceTree = ""; }; /* End PBXGroup section */ @@ -1077,6 +1143,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C1B383081CD0665D00CE7782 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C1B3830E1CD0665D00CE7782 /* NightscoutUploadKit.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -1203,6 +1277,7 @@ C10D9BD51C8269D500378342 /* PBXTargetDependency */, 430D64DF1CB855AB00FCA750 /* PBXTargetDependency */, 43722FC21CB9F7640038B7F2 /* PBXTargetDependency */, + C1B3831F1CD0665D00CE7782 /* PBXTargetDependency */, ); name = RileyLink; productName = RileyLink; @@ -1227,6 +1302,43 @@ productReference = C12EA252198B436800309FA4 /* RileyLinkTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + C1B3830A1CD0665D00CE7782 /* NightscoutUploadKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = C1B383221CD0665D00CE7782 /* Build configuration list for PBXNativeTarget "NightscoutUploadKit" */; + buildPhases = ( + C1B383061CD0665D00CE7782 /* Sources */, + C1B383071CD0665D00CE7782 /* Frameworks */, + C1B383081CD0665D00CE7782 /* Headers */, + C1B383091CD0665D00CE7782 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NightscoutUploadKit; + productName = NightscoutUploadKit; + productReference = C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */; + productType = "com.apple.product-type.framework"; + }; + C1B383131CD0665D00CE7782 /* NightscoutUploadKitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = C1B383251CD0665D00CE7782 /* Build configuration list for PBXNativeTarget "NightscoutUploadKitTests" */; + buildPhases = ( + C1B383101CD0665D00CE7782 /* Sources */, + C1B383111CD0665D00CE7782 /* Frameworks */, + C1B383121CD0665D00CE7782 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + C1B383171CD0665D00CE7782 /* PBXTargetDependency */, + C1B383191CD0665D00CE7782 /* PBXTargetDependency */, + ); + name = NightscoutUploadKitTests; + productName = NightscoutUploadKitTests; + productReference = C1B383141CD0665D00CE7782 /* NightscoutUploadKitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1264,6 +1376,14 @@ C12EA251198B436800309FA4 = { TestTargetID = C12EA236198B436800309FA4; }; + C1B3830A1CD0665D00CE7782 = { + CreatedOnToolsVersion = 7.3; + DevelopmentTeam = UY678SP37Q; + }; + C1B383131CD0665D00CE7782 = { + CreatedOnToolsVersion = 7.3; + TestTargetID = C12EA236198B436800309FA4; + }; }; }; buildConfigurationList = C12EA232198B436800309FA4 /* Build configuration list for PBXProject "RileyLink" */; @@ -1286,6 +1406,8 @@ 430D64D31CB855AB00FCA750 /* RileyLinkBLEKitTests */, 43722FAD1CB9F7630038B7F2 /* RileyLinkKit */, 43722FB61CB9F7640038B7F2 /* RileyLinkKitTests */, + C1B3830A1CD0665D00CE7782 /* NightscoutUploadKit */, + C1B383131CD0665D00CE7782 /* NightscoutUploadKitTests */, ); }; /* End PBXProject section */ @@ -1352,6 +1474,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C1B383091CD0665D00CE7782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C1B383121CD0665D00CE7782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1537,9 +1673,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C1842C311C91D56400DB42AC /* BGCheckNightscoutTreatment.swift in Sources */, C12616691B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m in Sources */, - C1842C2B1C90DFB600DB42AC /* NightscoutPumpEvents.swift in Sources */, C12616681B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m in Sources */, C12616321B65F4BC001FAD87 /* RileyLinkListTableViewController.m in Sources */, C1EF58971B3FA462001C8C80 /* MenuController.m in Sources */, @@ -1551,7 +1685,6 @@ C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */, 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */, C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, - C12FB2761CC5893C00879B80 /* TempBasalNightscoutTreatment.swift in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */, @@ -1559,19 +1692,14 @@ C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */, - C1C357941C929529009BDD4F /* StringCrypto.swift in Sources */, - C1842C291C908A3C00DB42AC /* NightscoutUploader.swift in Sources */, - C1842C2F1C90F6D900DB42AC /* NightscoutTreatment.swift in Sources */, C12616571B6A6130001FAD87 /* PacketLogViewController.m in Sources */, C1EF589E1B3FBFE7001C8C80 /* MainAppViewController.m in Sources */, C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */, 43C99C6F1B898B7100BC03D4 /* MenuHeaderTableViewCell.m in Sources */, C126163C1B67CBC2001FAD87 /* RileyLinkTableViewCell.m in Sources */, C1271B071A9A34E900B7C949 /* Log.m in Sources */, - C19F94AB1C91DF6E00018F7D /* BolusNightscoutTreatment.swift in Sources */, C10AB08B1C8519E2000F102E /* MySentryPairViewController.swift in Sources */, C1E535EA1991E36700C2AC49 /* NSData+Conversion.m in Sources */, - C1842C331C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1584,6 +1712,29 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C1B383061CD0665D00CE7782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C1B3832E1CD0668600CE7782 /* TempBasalNightscoutTreatment.swift in Sources */, + C1B3832B1CD0668600CE7782 /* BGCheckNightscoutTreatment.swift in Sources */, + C1B383291CD0668600CE7782 /* NightscoutPumpEvents.swift in Sources */, + C1B3832D1CD0668600CE7782 /* BolusNightscoutTreatment.swift in Sources */, + C1B3832C1CD0668600CE7782 /* MealBolusNightscoutTreatment.swift in Sources */, + C1B3832F1CD0668F00CE7782 /* StringCrypto.swift in Sources */, + C1B383281CD0668600CE7782 /* NightscoutUploader.swift in Sources */, + C1B3832A1CD0668600CE7782 /* NightscoutTreatment.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C1B383101CD0665D00CE7782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C1B3831C1CD0665D00CE7782 /* NightscoutUploadKitTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1622,6 +1773,21 @@ target = C12EA236198B436800309FA4 /* RileyLink */; targetProxy = C12EA257198B436900309FA4 /* PBXContainerItemProxy */; }; + C1B383171CD0665D00CE7782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C1B3830A1CD0665D00CE7782 /* NightscoutUploadKit */; + targetProxy = C1B383161CD0665D00CE7782 /* PBXContainerItemProxy */; + }; + C1B383191CD0665D00CE7782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C12EA236198B436800309FA4 /* RileyLink */; + targetProxy = C1B383181CD0665D00CE7782 /* PBXContainerItemProxy */; + }; + C1B3831F1CD0665D00CE7782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C1B3830A1CD0665D00CE7782 /* NightscoutUploadKit */; + targetProxy = C1B3831E1CD0665D00CE7782 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -2080,6 +2246,102 @@ }; name = Release; }; + C1B383231CD0665D00CE7782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = NightscoutUploadKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.NightscoutUploadKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C1B383241CD0665D00CE7782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = NightscoutUploadKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.NightscoutUploadKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + C1B383261CD0665D00CE7782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = NightscoutUploadKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.NightscoutUploadKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; + }; + name = Debug; + }; + C1B383271CD0665D00CE7782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = NightscoutUploadKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.NightscoutUploadKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -2164,6 +2426,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + C1B383221CD0665D00CE7782 /* Build configuration list for PBXNativeTarget "NightscoutUploadKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C1B383231CD0665D00CE7782 /* Debug */, + C1B383241CD0665D00CE7782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C1B383251CD0665D00CE7782 /* Build configuration list for PBXNativeTarget "NightscoutUploadKitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C1B383261CD0665D00CE7782 /* Debug */, + C1B383271CD0665D00CE7782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ diff --git a/RileyLink.xcodeproj/xcshareddata/xcschemes/NightscoutUploadKit.xcscheme b/RileyLink.xcodeproj/xcshareddata/xcschemes/NightscoutUploadKit.xcscheme new file mode 100644 index 000000000..b0486d60b --- /dev/null +++ b/RileyLink.xcodeproj/xcshareddata/xcschemes/NightscoutUploadKit.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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"> + + + + Date: Thu, 28 Apr 2016 16:20:17 -0500 Subject: [PATCH 02/40] extracting app concerns from NightscoutUploadKit into DeviceDataManager --- .gitignore | 2 + Cartfile | 1 + Cartfile.resolved | 1 + .../Extensions/StringCrypto.swift | 20 -- NightscoutUploadKit/NightscoutUploadKit.h | 2 - NightscoutUploadKit/NightscoutUploader.swift | 217 +-------------- RileyLink.xcodeproj/project.pbxproj | 61 ++-- RileyLink/Config.h | 2 + RileyLink/Config.m | 97 +++++-- RileyLink/DeviceDataManager.swift | 263 ++++++++++++++++++ RileyLink/MainAppViewController.m | 28 -- RileyLinkKit/RileyLinkKit.h | 2 - .../NightscoutPumpEventsTests.swift | 2 +- 13 files changed, 384 insertions(+), 314 deletions(-) create mode 100644 Cartfile create mode 100644 Cartfile.resolved delete mode 100644 NightscoutUploadKit/Extensions/StringCrypto.swift create mode 100644 RileyLink/DeviceDataManager.swift diff --git a/.gitignore b/.gitignore index f622aaf6b..15e0e61d3 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ DerivedData # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # # Pods/ + +Carthage/ diff --git a/Cartfile b/Cartfile new file mode 100644 index 000000000..dfa8f09ff --- /dev/null +++ b/Cartfile @@ -0,0 +1 @@ +github "krzyzanowskim/CryptoSwift" diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 000000000..2d1ab2d92 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1 @@ +github "krzyzanowskim/CryptoSwift" "0.4" diff --git a/NightscoutUploadKit/Extensions/StringCrypto.swift b/NightscoutUploadKit/Extensions/StringCrypto.swift deleted file mode 100644 index 9e325afc6..000000000 --- a/NightscoutUploadKit/Extensions/StringCrypto.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// StringCrypto.swift -// RileyLink -// -// Created by Pete Schwamb on 3/10/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -import Foundation - - -extension String { - func sha1() -> String { - let data = self.dataUsingEncoding(NSUTF8StringEncoding)! - var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0) - CC_SHA1(data.bytes, CC_LONG(data.length), &digest) - let hexBytes = digest.map { String(format: "%02hhx", $0) } - return hexBytes.joinWithSeparator("") - } -} diff --git a/NightscoutUploadKit/NightscoutUploadKit.h b/NightscoutUploadKit/NightscoutUploadKit.h index be643b1b3..f5a66044a 100644 --- a/NightscoutUploadKit/NightscoutUploadKit.h +++ b/NightscoutUploadKit/NightscoutUploadKit.h @@ -15,5 +15,3 @@ FOUNDATION_EXPORT double NightscoutUploadKitVersionNumber; FOUNDATION_EXPORT const unsigned char NightscoutUploadKitVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index 8b3da9797..1dffb73ee 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -1,5 +1,5 @@ // -// NightScoutUploader.swift +// NightscoutUploader.swift // RileyLink // // Created by Pete Schwamb on 3/9/16. @@ -8,11 +8,9 @@ import UIKit import MinimedKit -//import RileyLinkKit -//import RileyLinkBLEKit +import CryptoSwift - -class NightScoutUploader: NSObject { +public class NightscoutUploader: NSObject { enum DexcomSensorError: UInt8 { case SensorNotActive = 1 @@ -20,8 +18,8 @@ class NightScoutUploader: NSObject { case BadRF = 12 } - var siteURL: String = "" - var APISecret: String = "" + public var siteURL: String = "" + public var APISecret: String = "" var fetchHistoryScheduled: Bool = false var lastHistoryAttempt: NSDate? @@ -30,19 +28,14 @@ class NightScoutUploader: NSObject { var treatmentsQueue: [AnyObject] var lastMeterMessageRxTime: NSDate? - var activeRileyLink: RileyLinkBLEDevice? - var getHistoryTimer: NSTimer? - // TODO: since some treatments update, we should instead keep track of the time - // of the most recent non-mutating event, and send all events newer than that. - //var sentTreatments: [AnyObject] var observingPumpEventsSince: NSDate let defaultNightscoutEntriesPath = "/api/v1/entries.json" let defaultNightscoutTreatmentPath = "/api/v1/treatments.json" let defaultNightscoutDeviceStatusPath = "/api/v1/devicestatus.json" - override init() { + public override init() { entries = [AnyObject]() treatmentsQueue = [AnyObject]() deviceStatuses = [AnyObject]() @@ -51,143 +44,8 @@ class NightScoutUploader: NSObject { observingPumpEventsSince = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: [])! super.init() - - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NightScoutUploader.packetReceived(_:)), name: RILEYLINK_EVENT_PACKET_RECEIVED, object: nil) - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NightScoutUploader.deviceConnected(_:)), name: RILEYLINK_EVENT_DEVICE_CONNECTED, object: nil) - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NightScoutUploader.deviceDisconnected(_:)), name: RILEYLINK_EVENT_DEVICE_DISCONNECTED, object: nil) - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(NightScoutUploader.rileyLinkAdded(_:)), name: RILEYLINK_EVENT_DEVICE_ADDED, object: nil) - - UIDevice.currentDevice().batteryMonitoringEnabled = true - lastHistoryAttempt = nil - - getHistoryTimer = NSTimer.scheduledTimerWithTimeInterval(5.0 * 60, target:self, selector:#selector(NightScoutUploader.timerTriggered), userInfo:nil, repeats:true) - - // This triggers one history fetch right away (in 10s) - //performSelector(#selector(NightScoutUploader.fetchHistory), withObject: nil, afterDelay: 10) - - // This is to just test decoding history - //performSelector(Selector("testDecodeHistory"), withObject: nil, afterDelay: 1) - - // Test storing MySentry packet: - //[self performSelector:@selector(testHandleMySentry) withObject:nil afterDelay:10]; - } - - deinit { - NSNotificationCenter.defaultCenter().removeObserver(self) } - - // MARK: - Testing - - func testHandleMySentry() { - let data = NSData(hexadecimalString: "a259705504e9401334001001050000000001d7040205e4000000000054000001240000000000000000dd")! - let mySentryPacket = PumpMessage(rxData: data)! - handlePumpStatus(mySentryPacket, device:"testData", rssi:1) - flushAll() - } - - func testDecodeHistory() { - let pageData = NSData(hexadecimalString: "7b0100de080a101122007b0200c0160a102c1c007b0000c0000b1000160007000002be2a900000006e2a90050000000000000002be02be640000000000000000000000000000000000000000000000000000000000000000000000007b0100de080b101122007b0200c0160b102c1c007b0000c0000c1000160007000002be2b900000006e2b90050000000000000002be02be640000000000000000000000000000000000000000000000000000000000000000000000007b0100de080c10112200346418d3110c107b0200c0160c102c1c00343233db170c107b0000c0000d1000160007000002be2c900000006e2c90050000000000000002be02be640000000000000000000000000000000000000000000000000000000000000000000000007b0100de080d101122007b0200c0160d102c1c007b0000c0000e1000160007000002be2d900000006e2d90050000000000000002be02be640000000000000000000000000000000000000000000000000000000000000000000000007b0100de080e10112200063e033303c74f4e100c3e28d7100e1021001ce2150e1003000000202ce4350e101a000ae5150e101a0120e5150e107b0214c0160e102c1c00030001000112c0160e107b0000c0000f1000160007000001d32e900000006e2e90050000000000000001d301d3640000000000000000000000000000000000000000000000000000000000000000000000007b0100de080f10112200820108db150f1000a2ce8aa0810134e0150f1000a2ce8aa07d0134e0150f1000a2ce8aa0000000000000000000000000000000000000000000000000007b0200c0160f102c1c007b0000c000101000160007000002be2f900000006e2f90050000000000000002be02be640000000000000000000000000000000000000000000000000000000000000000000000007b0100de0810101122007b0200c01610102c1c000a5e36d03670103f0b36d0d67010c228060a5b0cd43670103f0b0cd4767010c228067b0000c000111000160007000002be30900000006e309005005d5b5e02000002be02be640000000000000000000000000000000000000000000000000000000000000000000000007b0100de0811101122000a600ada3171103f0c0ada117110c2280601002200220000001dea521110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e35")! - do { - let pumpModel = PumpModel.Model523 - let page = try HistoryPage(pageData: pageData, pumpModel: pumpModel) - let source = "testing/\(pumpModel)" - self.processPumpEvents(page.events, source: source, pumpModel: pumpModel) - } catch _ { - - } - } - - - // MARK: - Device updates - - func deviceConnected(note: NSNotification) - { - activeRileyLink = note.object as? RileyLinkBLEDevice - } - - func deviceDisconnected(note: NSNotification) - { - if activeRileyLink == (note.object as? RileyLinkBLEDevice) { - activeRileyLink = nil - } - } - - func rileyLinkAdded(note: NSNotification) - { - if let device = note.object as? RileyLinkBLEDevice { - device.enableIdleListeningOnChannel(0) - } - } - - func timerTriggered() { - - if lastHistoryAttempt == nil || lastHistoryAttempt!.timeIntervalSinceNow < (-5 * 60) && !fetchHistoryScheduled { - NSLog("No fetchHistory for over five minutes. Triggering one") - fetchHistory() - } - flushAll() - } - - - func packetReceived(note: NSNotification) { - let attrs = note.userInfo! - let packet = attrs["packet"] as! RFPacket - let device = note.object as! RileyLinkBLEDevice - if let data = packet.data { - - if let msg = PumpMessage(rxData: data) { - handlePumpMessage(msg, device:device, rssi: Int(packet.rssi)) - //TODO: tell RL to sleep for 4 mins to save on RL battery? - - } else if let msg = MeterMessage(rxData: data) { - handleMeterMessage(msg) - } - - } - } - - // MARK: - Polling - - func fetchHistory() { - lastHistoryAttempt = NSDate() - - fetchHistoryScheduled = false - if let device = activeRileyLink where device.state != .Connected { - activeRileyLink = nil - } - - if (self.activeRileyLink == nil) { - for item in RileyLinkBLEManager.sharedManager().rileyLinkList { - if let device = item as? RileyLinkBLEDevice where device.state == .Connected { - activeRileyLink = device - break - } - } - } - - if let rl = activeRileyLink { - NSLog("Using RileyLink \"%@\" to fetchHistory.", rl.name!) - - let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate - let pumpOps = PumpOps(pumpState: appDelegate.pump, device:rl) - pumpOps.getHistoryEventsSinceDate(observingPumpEventsSince) { (response) -> Void in - switch response { - case .Success(let (events, pumpModel)): - NSLog("fetchHistory succeeded.") - let source = "rileylink://medtronic/\(pumpModel)" - self.processPumpEvents(events, source: source, pumpModel: pumpModel) - case .Failure(let error): - // TODO: Check for HistoryPage.Error.UnknownEventType, and let users submit - // back to us to discover new history events. - NSLog("History fetch failed: %@", String(error)) - } - } - } else { - NSLog("fetchHistory failed: No connected rileylinks to attempt to pull history with.") - } - } - // MARK: - Decoding Treatments func processPumpEvents(events: [PumpEvent], source: String, pumpModel: PumpModel) { @@ -252,24 +110,6 @@ class NightScoutUploader: NSObject { } -// - (NSString*)trendToDirection:(GlucoseTrend)trend { -// switch (trend) { -// case GLUCOSE_TREND_NONE: -// return @""; -// case GLUCOSE_TREND_UP: -// return @"SingleUp"; -// case GLUCOSE_TREND_DOUBLE_UP: -// return @"DoubleUp"; -// case GLUCOSE_TREND_DOWN: -// return @"SingleDown"; -// case GLUCOSE_TREND_DOUBLE_DOWN: -// return @"DoubleDown"; -// default: -// return @"NOT COMPUTABLE"; -// break; -// } -// } - // Entries [ { sgv: 375, // date: 1432421525000, // dateString: '2015-05-23T22:52:05.000Z', @@ -278,31 +118,8 @@ class NightScoutUploader: NSObject { // device: 'share2', // type: 'sgv' } ] - func handlePumpMessage(msg: PumpMessage, device: RileyLinkBLEDevice, rssi: Int) { - - if (msg.packetType == .MySentry && - msg.messageType == .PumpStatus && - (msg.address.hexadecimalString == Config.sharedInstance().pumpID)) { - // Make this RL the active one, for history dumping. - activeRileyLink = device - handlePumpStatus(msg, device:device.deviceURI, rssi:rssi) - // Just got a MySentry packet; in 11s would be a good time to poll. - if !fetchHistoryScheduled { - performSelector(#selector(NightScoutUploader.fetchHistory), withObject:nil, afterDelay:11) - fetchHistoryScheduled = true - } - // TODO: send ack. also, we can probably wait less than 25s if we ack; the 25s - // above is mainly to avoid colliding with subsequent packets. - } - flushAll() - } - - func handlePumpStatus(msg: PumpMessage, device: String, rssi: Int) { + func handlePumpStatus(status: MySentryPumpStatusMessageBody, device: String, rssi: Int) { - let status: MySentryPumpStatusMessageBody = msg.messageBody as! MySentryPumpStatusMessageBody - - if msg.address.hexadecimalString == Config.sharedInstance().pumpID { - enum DexcomSensorErrorType: Int { case DX_SENSOR_NOT_ACTIVE = 1 case DX_SENSOR_NOT_CALIBRATED = 5 @@ -398,12 +215,9 @@ class NightScoutUploader: NSObject { } }() entries.append(entry) - } else { - NSLog("Dropping mysentry packet for pump: %@", msg.address.hexadecimalString); - } } - func handleMeterMessage(msg: MeterMessage) { + public func handleMeterMessage(msg: MeterMessage) { // TODO: Should only accept meter messages from specified meter ids. // Need to add an interface to allow user to specify linked meters. @@ -433,21 +247,6 @@ class NightScoutUploader: NSObject { func flushAll() { - let logEntries = Log.popLogEntries() - - if logEntries.count > 0 { - let date = NSDate() - let epochTime = date.timeIntervalSince1970 * 1000 - - let entry = [ - "date": epochTime, - "dateString": TimeFormat.timestampStrFromDate(date), - "entries": logEntries, - "type": "logs" - ] - entries.append(entry) - } - flushDeviceStatuses() flushEntries() flushTreatments() diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 1fcd1d132..4823305fc 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -185,8 +185,10 @@ C1B3832C1CD0668600CE7782 /* MealBolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842C321C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift */; }; C1B3832D1CD0668600CE7782 /* BolusNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */; }; C1B3832E1CD0668600CE7782 /* TempBasalNightscoutTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12FB2751CC5893C00879B80 /* TempBasalNightscoutTreatment.swift */; }; - C1B3832F1CD0668F00CE7782 /* StringCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C357931C929529009BDD4F /* StringCrypto.swift */; }; C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; + C1B383311CD068C300CE7782 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 430D64CB1CB855AB00FCA750 /* RileyLinkBLEKit.framework */; }; + C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */; }; + C1B383381CD1BECD00CE7782 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1B383371CD1BECD00CE7782 /* CryptoSwift.framework */; }; 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 */; }; @@ -434,7 +436,7 @@ C14303151C97C98000A40450 /* PumpAckMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpAckMessageBody.swift; sourceTree = ""; }; C14303171C97CC6B00A40450 /* GetPumpModelCarelinkMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetPumpModelCarelinkMessageBodyTests.swift; sourceTree = ""; }; C14303191C9A610B00A40450 /* GetBatteryCarelinkMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetBatteryCarelinkMessageBodyTests.swift; sourceTree = ""; }; - C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutPumpEventsTests.swift; sourceTree = ""; }; + C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NightscoutPumpEventsTests.swift; path = ../RileyLinkTests/NightscoutPumpEventsTests.swift; sourceTree = ""; }; C14D2B041C9F5D5800C98E4C /* TempBasalDurationPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TempBasalDurationPumpEvent.swift; sourceTree = ""; }; C14D2B081C9F5EDA00C98E4C /* ChangeTempBasalTypePumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeTempBasalTypePumpEvent.swift; sourceTree = ""; }; C1711A551C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonPressCarelinkMessageBody.swift; sourceTree = ""; }; @@ -512,9 +514,10 @@ C1B383141CD0665D00CE7782 /* NightscoutUploadKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NightscoutUploadKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadKitTests.swift; sourceTree = ""; }; 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 = ""; }; + C1B383371CD1BECD00CE7782 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; 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 = ""; }; - C1C357931C929529009BDD4F /* StringCrypto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringCrypto.swift; sourceTree = ""; }; C1E535E81991E36700C2AC49 /* NSData+Conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Conversion.h"; sourceTree = ""; }; C1E535E91991E36700C2AC49 /* NSData+Conversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Conversion.m"; sourceTree = ""; }; C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertType.swift; sourceTree = ""; }; @@ -636,7 +639,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C1B383311CD068C300CE7782 /* RileyLinkBLEKit.framework in Frameworks */, C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */, + C1B383381CD1BECD00CE7782 /* CryptoSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -852,6 +857,7 @@ C12EA239198B436800309FA4 /* Frameworks */ = { isa = PBXGroup; children = ( + C1B383371CD1BECD00CE7782 /* CryptoSwift.framework */, 43CA93241CB8BB33000026B5 /* CoreBluetooth.framework */, C12616431B685F0A001FAD87 /* CoreData.framework */, C12EA23A198B436800309FA4 /* Foundation.framework */, @@ -865,9 +871,9 @@ C12EA240198B436800309FA4 /* RileyLink */ = { isa = PBXGroup; children = ( + C1B383341CD1BA6700CE7782 /* Managers */, C1AA398B1AB67F6A00BC9E33 /* Categories */, C12616451B685F35001FAD87 /* CoreData */, - C1EF589B1B3FBA5D001C8C80 /* NightscoutUploadKit */, C12EA241198B436800309FA4 /* Supporting Files */, C1EF58891B3F9730001C8C80 /* SWRevealViewController */, C12616391B67CB9C001FAD87 /* TableViewCells */, @@ -903,7 +909,6 @@ isa = PBXGroup; children = ( C12EA25F198B436900309FA4 /* RileyLinkTests.m */, - C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */, C12EA25A198B436900309FA4 /* Supporting Files */, ); path = RileyLinkTests; @@ -996,6 +1001,13 @@ C1B3830C1CD0665D00CE7782 /* NightscoutUploadKit */ = { isa = PBXGroup; children = ( + C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */, + C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */, + C1842C2E1C90F6D900DB42AC /* NightscoutTreatment.swift */, + C1842C301C91D56400DB42AC /* BGCheckNightscoutTreatment.swift */, + C1842C321C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift */, + C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */, + C12FB2751CC5893C00879B80 /* TempBasalNightscoutTreatment.swift */, C1B3830D1CD0665D00CE7782 /* NightscoutUploadKit.h */, C1B3830F1CD0665D00CE7782 /* Info.plist */, ); @@ -1005,18 +1017,19 @@ C1B3831A1CD0665D00CE7782 /* NightscoutUploadKitTests */ = { isa = PBXGroup; children = ( + C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */, C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */, C1B3831D1CD0665D00CE7782 /* Info.plist */, ); path = NightscoutUploadKitTests; sourceTree = ""; }; - C1C357921C929507009BDD4F /* Extensions */ = { + C1B383341CD1BA6700CE7782 /* Managers */ = { isa = PBXGroup; children = ( - C1C357931C929529009BDD4F /* StringCrypto.swift */, + C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */, ); - path = Extensions; + name = Managers; sourceTree = ""; }; C1EAD6B81C826B92006DBA60 /* Extensions */ = { @@ -1090,22 +1103,6 @@ name = ViewControllers; sourceTree = ""; }; - C1EF589B1B3FBA5D001C8C80 /* NightscoutUploadKit */ = { - isa = PBXGroup; - children = ( - C1C357921C929507009BDD4F /* Extensions */, - C1842C281C908A3C00DB42AC /* NightscoutUploader.swift */, - C1842C2A1C90DFB600DB42AC /* NightscoutPumpEvents.swift */, - C1842C2E1C90F6D900DB42AC /* NightscoutTreatment.swift */, - C1842C301C91D56400DB42AC /* BGCheckNightscoutTreatment.swift */, - C1842C321C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift */, - C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */, - C12FB2751CC5893C00879B80 /* TempBasalNightscoutTreatment.swift */, - ); - name = NightscoutUploadKit; - path = ../NightscoutUploadKit; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1696,6 +1693,7 @@ C1EF589E1B3FBFE7001C8C80 /* MainAppViewController.m in Sources */, C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */, 43C99C6F1B898B7100BC03D4 /* MenuHeaderTableViewCell.m in Sources */, + C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */, C126163C1B67CBC2001FAD87 /* RileyLinkTableViewCell.m in Sources */, C1271B071A9A34E900B7C949 /* Log.m in Sources */, C10AB08B1C8519E2000F102E /* MySentryPairViewController.swift in Sources */, @@ -1721,7 +1719,6 @@ C1B383291CD0668600CE7782 /* NightscoutPumpEvents.swift in Sources */, C1B3832D1CD0668600CE7782 /* BolusNightscoutTreatment.swift in Sources */, C1B3832C1CD0668600CE7782 /* MealBolusNightscoutTreatment.swift in Sources */, - C1B3832F1CD0668F00CE7782 /* StringCrypto.swift in Sources */, C1B383281CD0668600CE7782 /* NightscoutUploader.swift in Sources */, C1B3832A1CD0668600CE7782 /* NightscoutTreatment.swift in Sources */, ); @@ -2249,6 +2246,7 @@ C1B383231CD0665D00CE7782 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -2260,10 +2258,14 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = NightscoutUploadKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.NightscoutUploadKit; @@ -2277,6 +2279,7 @@ C1B383241CD0665D00CE7782 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -2289,10 +2292,14 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = NightscoutUploadKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.NightscoutUploadKit; diff --git a/RileyLink/Config.h b/RileyLink/Config.h index 4c5e0361b..23ca17a41 100644 --- a/RileyLink/Config.h +++ b/RileyLink/Config.h @@ -17,6 +17,8 @@ @property (nonatomic, nullable, strong) NSString *nightscoutURL; @property (nonatomic, nullable, strong) NSString *nightscoutAPISecret; @property (nonatomic, nullable, strong) NSString *pumpID; +@property (nonatomic, nullable, strong) NSTimeZone *pumpTimeZone; +@property (nonatomic, nullable, strong) NSSet *autoConnectIds; @property (nonatomic, readonly) BOOL hasValidConfiguration; diff --git a/RileyLink/Config.m b/RileyLink/Config.m index 4365b3f9c..d2ee9511f 100644 --- a/RileyLink/Config.m +++ b/RileyLink/Config.m @@ -6,62 +6,109 @@ // Copyright (c) 2015 Pete Schwamb. All rights reserved. // +@import CoreData; #import "Config.h" +#import "RileyLinkRecord.h" +#import "RileyLink-Swift.h" +#import @implementation Config + (Config *)sharedInstance { - // structure used to test whether the block has completed or not - static dispatch_once_t p = 0; - - // initialize sharedObject as nil (first call only) - __strong static Config * _sharedObject = nil; - - // executes a block object once and only once for the lifetime of an application - dispatch_once(&p, ^{ - _sharedObject = [[self alloc] init]; - }); - - // returns the same object each time - return _sharedObject; + // structure used to test whether the block has completed or not + static dispatch_once_t p = 0; + + // initialize sharedObject as nil (first call only) + __strong static Config * _sharedObject = nil; + + // executes a block object once and only once for the lifetime of an application + dispatch_once(&p, ^{ + _sharedObject = [[self alloc] init]; + }); + + // returns the same object each time + return _sharedObject; } - (instancetype)init { - if (self = [super init]) { - _defaults = [NSUserDefaults standardUserDefaults]; - } - - return self; + if (self = [super init]) { + _defaults = [NSUserDefaults standardUserDefaults]; + } + + return self; } - (void) setNightscoutURL:(NSString *)nightscoutURL { - [_defaults setValue:nightscoutURL forKey:@"nightscoutURL"]; + [_defaults setValue:nightscoutURL forKey:@"nightscoutURL"]; } - (NSString*) nightscoutURL { - return [_defaults stringForKey:@"nightscoutURL"]; + return [_defaults stringForKey:@"nightscoutURL"]; } - (void) setNightscoutAPISecret:(NSString *)nightscoutAPISecret { - [_defaults setValue:nightscoutAPISecret forKey:@"nightscoutAPISecret"]; + [_defaults setValue:nightscoutAPISecret forKey:@"nightscoutAPISecret"]; } - (NSString*) nightscoutAPISecret { - return [_defaults stringForKey:@"nightscoutAPISecret"]; + return [_defaults stringForKey:@"nightscoutAPISecret"]; } - (void) setPumpID:(NSString *)pumpID { - [_defaults setValue:pumpID forKey:@"pumpID"]; + [_defaults setValue:pumpID forKey:@"pumpID"]; } - (NSString*) pumpID { - return [_defaults stringForKey:@"pumpID"]; + return [_defaults stringForKey:@"pumpID"]; +} + +- (void) setPumpTimeZone:(NSTimeZone *)pumpTimeZone { + + if (pumpTimeZone) { + NSNumber *rawValue = [NSNumber numberWithInteger:pumpTimeZone.secondsFromGMT]; + [_defaults setObject:rawValue forKey:@"pumpTimeZone"]; + } else { + [_defaults removeObjectForKey:@"pumpTimeZone"]; + } +} + +- (NSTimeZone*) pumpTimeZone { + NSNumber *offset = (NSNumber*)[_defaults objectForKey:@"pumpTimeZone"]; + if (offset) { + return [NSTimeZone timeZoneForSecondsFromGMT: offset.integerValue]; + } else { + return nil; + } } - (BOOL) hasValidConfiguration { - return self.nightscoutURL != NULL && ![self.nightscoutURL isEqualToString:@""]; + return self.nightscoutURL != NULL && ![self.nightscoutURL isEqualToString:@""]; +} + +- (NSSet*) autoConnectIds { + AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; + NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext; + + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription entityForName:@"RileyLinkRecord" + inManagedObjectContext:managedObjectContext]; + fetchRequest.entity = entity; + NSError *error; + NSMutableSet *autoConnectIds = [[NSMutableSet alloc] init]; + NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; + for (RileyLinkRecord *record in fetchedObjects) { + NSLog(@"Loaded: %@ from db", record.name); + if ((record.autoConnect).boolValue) { + [autoConnectIds addObject:record.peripheralId]; + } + } + return autoConnectIds; +} + +- (void) setAutoConnectIds:(NSSet *)autoConnectIds { + } diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift new file mode 100644 index 000000000..619c98f08 --- /dev/null +++ b/RileyLink/DeviceDataManager.swift @@ -0,0 +1,263 @@ +// +// DeviceDataManager.swift +// RileyLink +// +// Created by Pete Schwamb on 4/27/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation +import RileyLinkKit +import RileyLinkBLEKit +import MinimedKit +import NightscoutUploadKit + +class DeviceDataManager { + + static let PumpEventsUpdatedNotification = "com.rileylink.notification.PumpEventsUpdated" + + var getHistoryTimer: NSTimer? + + let rileyLinkManager: RileyLinkDeviceManager + + var connectedPeripheralIDs: Set = Config.sharedInstance().autoConnectIds as! Set + + var latestPumpStatus: MySentryPumpStatusMessageBody? + + private var observingPumpEventsSince: NSDate + + var nightscoutUploader: NightscoutUploader + + var pumpTimeZone: NSTimeZone? = Config.sharedInstance().pumpTimeZone { + didSet { + Config.sharedInstance().pumpTimeZone = pumpTimeZone + + if let pumpTimeZone = pumpTimeZone { + + if let pumpState = rileyLinkManager.pumpState { + pumpState.timeZone = pumpTimeZone + } + } + } + } + + var pumpID: String? = Config.sharedInstance().pumpID { + didSet { + if pumpID?.characters.count != 6 { + pumpID = nil + } + + if let pumpID = pumpID { + let pumpState = PumpState(pumpID: pumpID) + + if let timeZone = pumpTimeZone { + pumpState.timeZone = timeZone + } + + rileyLinkManager.pumpState = pumpState + } else { + rileyLinkManager.pumpState = nil + } + + Config.sharedInstance().pumpID = pumpID + } + } + + var lastHistoryAttempt: NSDate? = nil + + var lastRileyLinkHeardFrom: RileyLinkDevice? = nil + + + var rileyLinkManagerObserver: AnyObject? { + willSet { + if let observer = rileyLinkManagerObserver { + NSNotificationCenter.defaultCenter().removeObserver(observer) + } + } + } + + var rileyLinkDevicePacketObserver: AnyObject? { + willSet { + if let observer = rileyLinkDevicePacketObserver { + NSNotificationCenter.defaultCenter().removeObserver(observer) + } + } + } + + func receivedRileyLinkManagerNotification(note: NSNotification) { + NSNotificationCenter.defaultCenter().postNotificationName(note.name, object: self, userInfo: note.userInfo) + } + + func preferredRileyLink() -> RileyLinkDevice? { + if let device = lastRileyLinkHeardFrom { + return device + } + return self.rileyLinkManager.firstConnectedDevice + } + + func receivedRileyLinkPacketNotification(note: NSNotification) { + if let + device = note.object as? RileyLinkDevice, + data = note.userInfo?[RileyLinkDevice.IdleMessageDataKey] as? NSData, + message = PumpMessage(rxData: data) + { + lastRileyLinkHeardFrom = device + switch message.packetType { + case .MySentry: + switch message.messageBody { + case let body as MySentryPumpStatusMessageBody: + updatePumpStatus(body, fromDevice: device) + case is MySentryAlertMessageBody: + break + // TODO: de-dupe + // logger?.addMessage(body.dictionaryRepresentation, toCollection: "sentryAlert") + case is MySentryAlertClearedMessageBody: + break + // TODO: de-dupe + // logger?.addMessage(body.dictionaryRepresentation, toCollection: "sentryAlert") + case is UnknownMessageBody: + break + //logger?.addMessage(body.dictionaryRepresentation, toCollection: "sentryOther") + default: + break + } + default: + break + } + } + } + + func connectToRileyLink(device: RileyLinkDevice) { + connectedPeripheralIDs.insert(device.peripheral.identifier.UUIDString) + + rileyLinkManager.connectDevice(device) + } + + func disconnectFromRileyLink(device: RileyLinkDevice) { + connectedPeripheralIDs.remove(device.peripheral.identifier.UUIDString) + + rileyLinkManager.disconnectDevice(device) + } + + private func updatePumpStatus(status: MySentryPumpStatusMessageBody, fromDevice device: RileyLinkDevice) { + status.pumpDateComponents.timeZone = pumpTimeZone + + if status != latestPumpStatus { + latestPumpStatus = status + + if status.batteryRemainingPercent == 0 { + //NotificationManager.sendPumpBatteryLowNotification() + } + + // Sentry packets are sent in groups of 3, 5s apart. Wait 11s to avoid conflicting comms. + let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(11 * NSEC_PER_SEC)) + dispatch_after(delay, dispatch_get_main_queue()) { + self.getPumpHistory(device) + } + } + } + + private func getPumpHistory(device: RileyLinkDevice) { + device.ops!.getHistoryEventsSinceDate(observingPumpEventsSince) { (response) -> Void in + switch response { + case .Success(let (events, pumpModel)): + NSLog("fetchHistory succeeded.") + self.handleNewHistoryEvents(events, pumpModel: pumpModel) + NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.PumpEventsUpdatedNotification, object: self) + + case .Failure(let error): + NSLog("History fetch failed: %@", String(error)) + } + } + } + + private func handleNewHistoryEvents(events: [PumpEvent], pumpModel: PumpModel) { + // TODO: get insulin doses from history + // TODO: upload events to Nightscout + let source = "rileylink://medtronic/\(pumpModel)" + } + + // MARK: - Initialization + + static let sharedManager = DeviceDataManager() + + init() { + + let pumpState: PumpState? + + if let pumpID = pumpID { + pumpState = PumpState(pumpID: pumpID) + + if let timeZone = pumpTimeZone { + pumpState?.timeZone = timeZone + } + } else { + pumpState = nil + } + + rileyLinkManager = RileyLinkDeviceManager( + pumpState: pumpState, + autoConnectIDs: connectedPeripheralIDs + ) + + nightscoutUploader = NightscoutUploader() + nightscoutUploader.siteURL = Config.sharedInstance().nightscoutURL! + nightscoutUploader.APISecret = Config.sharedInstance().nightscoutAPISecret! + + + let calendar = NSCalendar.currentCalendar() + observingPumpEventsSince = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: [])! + + getHistoryTimer = NSTimer.scheduledTimerWithTimeInterval(5.0 * 60, target:self, selector:#selector(DeviceDataManager.timerTriggered), userInfo:nil, repeats:true) + + // This triggers one history fetch right away (in 10s) + //performSelector(#selector(DeviceDataManager.fetchHistory), withObject: nil, afterDelay: 10) + + // This is to just test decoding history + //performSelector(Selector("testDecodeHistory"), withObject: nil, afterDelay: 1) + + // Test storing MySentry packet: + //[self performSelector:@selector(testHandleMySentry) withObject:nil afterDelay:10]; + + UIDevice.currentDevice().batteryMonitoringEnabled = true + + rileyLinkManager.timerTickEnabled = false + rileyLinkManagerObserver = NSNotificationCenter.defaultCenter().addObserverForName(nil, object: rileyLinkManager, queue: nil) { [weak self] (note) -> Void in + self?.receivedRileyLinkManagerNotification(note) + } + + // TODO: Use delegation instead. + rileyLinkDevicePacketObserver = NSNotificationCenter.defaultCenter().addObserverForName(RileyLinkDevice.DidReceiveIdleMessageNotification, object: nil, queue: nil) { [weak self] (note) -> Void in + self?.receivedRileyLinkPacketNotification(note) + } + + + } + + deinit { + rileyLinkManagerObserver = nil + rileyLinkDevicePacketObserver = nil + } + + // MARK: - Device updates + + func rileyLinkAdded(note: NSNotification) + { + if let device = note.object as? RileyLinkBLEDevice { + device.enableIdleListeningOnChannel(0) + } + } + + @objc func timerTriggered() { + logMemUsage() + + if lastHistoryAttempt == nil || lastHistoryAttempt!.timeIntervalSinceNow < (-5 * 60) { + NSLog("No fetchHistory for over five minutes. Triggering one") + if let device = preferredRileyLink() { + getPumpHistory(device) + } else { + NSLog("No RileyLink available to fetch history with!") + } + } + } +} \ No newline at end of file diff --git a/RileyLink/MainAppViewController.m b/RileyLink/MainAppViewController.m index d45c6fcca..28be59e66 100644 --- a/RileyLink/MainAppViewController.m +++ b/RileyLink/MainAppViewController.m @@ -19,8 +19,6 @@ @interface MainAppViewController () { NSDictionary *lastStatus; } -@property (strong, nonatomic) NightScoutUploader *uploader; - @end @implementation MainAppViewController @@ -34,14 +32,8 @@ - (void)viewDidLoad { // Looks like switching NightscoutWebView to WKWebView should help. Until then: [UIView setAnimationsEnabled:NO]; - self.uploader = [[NightScoutUploader alloc] init]; - self.uploader.siteURL = [Config sharedInstance].nightscoutURL; - self.uploader.APISecret = [Config sharedInstance].nightscoutAPISecret; - AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; self.managedObjectContext = appDelegate.managedObjectContext; - - [self setupAutoConnect]; } - (void)viewDidDisappear:(BOOL)animated { @@ -51,26 +43,6 @@ - (void)viewDidDisappear:(BOOL)animated { [RileyLinkBLEManager sharedManager].scanningEnabled = NO; } -- (void)setupAutoConnect { - - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; - NSEntityDescription *entity = [NSEntityDescription entityForName:@"RileyLinkRecord" - inManagedObjectContext:self.managedObjectContext]; - fetchRequest.entity = entity; - NSError *error; - NSMutableSet *autoConnectIds = [[NSMutableSet alloc] init]; - NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; - for (RileyLinkRecord *record in fetchedObjects) { - NSLog(@"Loaded: %@ from db", record.name); - if ((record.autoConnect).boolValue) { - [autoConnectIds addObject:record.peripheralId]; - } - } - [RileyLinkBLEManager sharedManager].autoConnectIds = autoConnectIds; -} - - - - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. diff --git a/RileyLinkKit/RileyLinkKit.h b/RileyLinkKit/RileyLinkKit.h index c46804f33..472a86e7f 100644 --- a/RileyLinkKit/RileyLinkKit.h +++ b/RileyLinkKit/RileyLinkKit.h @@ -15,5 +15,3 @@ FOUNDATION_EXPORT double RileyLinkKitVersionNumber; FOUNDATION_EXPORT const unsigned char RileyLinkKitVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/RileyLinkTests/NightscoutPumpEventsTests.swift b/RileyLinkTests/NightscoutPumpEventsTests.swift index c0ec2e992..4ed1d6a94 100644 --- a/RileyLinkTests/NightscoutPumpEventsTests.swift +++ b/RileyLinkTests/NightscoutPumpEventsTests.swift @@ -8,7 +8,7 @@ import XCTest @testable import MinimedKit -@testable import RileyLink +@testable import NightscoutUploadKit class NightscoutPumpEventsTests: XCTestCase { From 263a32ff2b4affacfaacbfe0d334436491a77d34 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 28 Apr 2016 16:34:51 -0500 Subject: [PATCH 03/40] Add CryptoSwift to embed frameworks --- RileyLink.xcodeproj/project.pbxproj | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 4823305fc..7c2b7566d 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -117,6 +117,7 @@ C1711A5C1C953F3000CB25BD /* GetBatteryCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A5B1C953F3000CB25BD /* GetBatteryCarelinkMessageBody.swift */; }; C1711A5E1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */; }; C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C17E147D1CD2B92800851C67 /* CryptoSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C17E147C1CD2B92800851C67 /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C1842BBB1C8E184300DB42AC /* PumpModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBA1C8E184300DB42AC /* PumpModel.swift */; }; C1842BBD1C8E7C6E00DB42AC /* PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */; }; C1842BBF1C8E855A00DB42AC /* PumpEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */; }; @@ -311,6 +312,7 @@ C10D9BD71C8269D500378342 /* MinimedKit.framework in Embed Frameworks */, C1B383211CD0665D00CE7782 /* NightscoutUploadKit.framework in Embed Frameworks */, 430D64E11CB855AB00FCA750 /* RileyLinkBLEKit.framework in Embed Frameworks */, + C17E147D1CD2B92800851C67 /* CryptoSwift.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -445,6 +447,7 @@ C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetHistoryPageCarelinkMessageBody.swift; sourceTree = ""; }; C174F26919EB824D00398C72 /* ISO8601DateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISO8601DateFormatter.h; sourceTree = ""; }; C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ISO8601DateFormatter.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + C17E147C1CD2B92800851C67 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; sourceTree = ""; }; C1842BBA1C8E184300DB42AC /* PumpModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpModel.swift; sourceTree = ""; }; C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEvent.swift; sourceTree = ""; }; C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEventType.swift; sourceTree = ""; }; @@ -822,6 +825,7 @@ C12EA22E198B436800309FA4 = { isa = PBXGroup; children = ( + C17E147C1CD2B92800851C67 /* CryptoSwift.framework */, C12EA240198B436800309FA4 /* RileyLink */, C12EA259198B436900309FA4 /* RileyLinkTests */, C10D9BC21C8269D500378342 /* MinimedKit */, @@ -2168,6 +2172,10 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -2188,6 +2196,10 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; From 2d88a66f4fc055dcb1f1eaea2f548244baff17bc Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 28 Apr 2016 16:48:43 -0500 Subject: [PATCH 04/40] add carthage to travis confi, call processPumpEvents on nightscout uploader --- .travis.yml | 2 ++ NightscoutUploadKit/NightscoutUploader.swift | 2 +- RileyLink/AppDelegate.swift | 7 ++----- RileyLink/DeviceDataManager.swift | 3 ++- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9f58ce62c..b3464debb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,7 @@ xcode_sdk: xcode_project: RileyLink.xcodeproj xcode_scheme: - RileyLink +before_script: + - carthage bootstrap script: - xcodebuild -project RileyLink.xcodeproj -scheme RileyLink -sdk iphonesimulator9.3 test diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index 1dffb73ee..f88f059ff 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -48,7 +48,7 @@ public class NightscoutUploader: NSObject { // MARK: - Decoding Treatments - func processPumpEvents(events: [PumpEvent], source: String, pumpModel: PumpModel) { + public func processPumpEvents(events: [PumpEvent], source: String, pumpModel: PumpModel) { // Find valid event times var validEventTimes = [NSDate]() diff --git a/RileyLink/AppDelegate.swift b/RileyLink/AppDelegate.swift index 4a323ae98..80ed500a2 100644 --- a/RileyLink/AppDelegate.swift +++ b/RileyLink/AppDelegate.swift @@ -15,8 +15,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - var pump: PumpState! - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let logFileURL = applicationDocumentsDirectory().URLByAppendingPathComponent("logfile.txt") @@ -26,9 +24,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { NSLog("Could not remove file at path: \(logFileURL): \(error)") } - if let pumpID = Config.sharedInstance().pumpID { - pump = PumpState(pumpID: pumpID) - } + // Just instantiate the DeviceDataManager + DeviceDataManager.sharedManager return true } diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index 619c98f08..6d7581328 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -1,4 +1,4 @@ -// +create// // DeviceDataManager.swift // RileyLink // @@ -175,6 +175,7 @@ class DeviceDataManager { // TODO: get insulin doses from history // TODO: upload events to Nightscout let source = "rileylink://medtronic/\(pumpModel)" + nightscoutUploader.processPumpEvents(events, source: source, pumpModel: pumpModel) } // MARK: - Initialization From 76e15af6227c021ee1fd2321b3b4d8120010dd9f Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 28 Apr 2016 16:49:19 -0500 Subject: [PATCH 05/40] Fix typo --- RileyLink/DeviceDataManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index 6d7581328..d109c19f7 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -1,4 +1,4 @@ -create// +// // DeviceDataManager.swift // RileyLink // From 53c109e1306bf7dd496c1a7179b81618d6ead8d7 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 28 Apr 2016 21:30:34 -0500 Subject: [PATCH 06/40] have viewcontrollers use RileyLinkDevice over RileyLinkBLEDevice --- RileyLink.xcodeproj/project.pbxproj | 16 +- RileyLink/MySentryPairViewController.swift | 6 +- RileyLink/PacketGeneratorViewController.h | 16 -- RileyLink/PacketGeneratorViewController.m | 107 ------------ RileyLink/PacketLogViewController.h | 16 -- RileyLink/PacketLogViewController.m | 116 ------------- RileyLink/PumpChatViewController.swift | 156 ++++++++--------- RileyLink/Storyboard.storyboard | 186 +-------------------- RileyLinkDeviceViewController.swift | 43 +++++ RileyLinkKit/PumpOps.swift | 2 + 10 files changed, 137 insertions(+), 527 deletions(-) delete mode 100644 RileyLink/PacketGeneratorViewController.h delete mode 100644 RileyLink/PacketGeneratorViewController.m delete mode 100644 RileyLink/PacketLogViewController.h delete mode 100644 RileyLink/PacketLogViewController.m create mode 100644 RileyLinkDeviceViewController.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 7c2b7566d..967cb8637 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -85,9 +85,7 @@ C12616441B685F0A001FAD87 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12616431B685F0A001FAD87 /* CoreData.framework */; }; C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C12616491B685F93001FAD87 /* RileyLink.xcdatamodeld */; }; C12616541B6892DB001FAD87 /* RileyLinkRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616531B6892DB001FAD87 /* RileyLinkRecord.m */; }; - C12616571B6A6130001FAD87 /* PacketLogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616561B6A6130001FAD87 /* PacketLogViewController.m */; }; C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */; }; - C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */; }; C12616671B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616601B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m */; }; C12616681B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616621B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m */; }; C12616691B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616641B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m */; }; @@ -118,6 +116,7 @@ C1711A5E1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */; }; C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C17E147D1CD2B92800851C67 /* CryptoSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C17E147C1CD2B92800851C67 /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + C17E14811CD2F46800851C67 /* RileyLinkDeviceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17E14801CD2F46800851C67 /* RileyLinkDeviceViewController.swift */; }; C1842BBB1C8E184300DB42AC /* PumpModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBA1C8E184300DB42AC /* PumpModel.swift */; }; C1842BBD1C8E7C6E00DB42AC /* PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */; }; C1842BBF1C8E855A00DB42AC /* PumpEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */; }; @@ -401,12 +400,8 @@ 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 = ""; }; - C12616551B6A6130001FAD87 /* PacketLogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketLogViewController.h; sourceTree = ""; }; - C12616561B6A6130001FAD87 /* PacketLogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketLogViewController.m; sourceTree = ""; }; C12616581B6B2D20001FAD87 /* PacketTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketTableViewCell.h; sourceTree = ""; }; C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketTableViewCell.m; sourceTree = ""; }; - C126165B1B6C8076001FAD87 /* PacketGeneratorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketGeneratorViewController.h; sourceTree = ""; }; - C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketGeneratorViewController.m; sourceTree = ""; }; C126165F1B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingCollectionView.h; sourceTree = ""; }; C12616601B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingCollectionView.m; sourceTree = ""; }; C12616611B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingScrollView.h; sourceTree = ""; }; @@ -448,6 +443,7 @@ C174F26919EB824D00398C72 /* ISO8601DateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISO8601DateFormatter.h; sourceTree = ""; }; C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ISO8601DateFormatter.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; C17E147C1CD2B92800851C67 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; sourceTree = ""; }; + C17E14801CD2F46800851C67 /* RileyLinkDeviceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceViewController.swift; sourceTree = SOURCE_ROOT; }; C1842BBA1C8E184300DB42AC /* PumpModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpModel.swift; sourceTree = ""; }; C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEvent.swift; sourceTree = ""; }; C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEventType.swift; sourceTree = ""; }; @@ -1094,13 +1090,10 @@ C10AB08A1C8519E2000F102E /* MySentryPairViewController.swift */, C12EA26B198B456D00309FA4 /* NightscoutWebView.h */, C12EA26C198B456D00309FA4 /* NightscoutWebView.m */, - C126165B1B6C8076001FAD87 /* PacketGeneratorViewController.h */, - C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */, - C12616551B6A6130001FAD87 /* PacketLogViewController.h */, - C12616561B6A6130001FAD87 /* PacketLogViewController.m */, C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */, C126162A1B65E9BF001FAD87 /* RileyLinkDeviceViewController.h */, C126162B1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m */, + C17E14801CD2F46800851C67 /* RileyLinkDeviceViewController.swift */, C12616301B65F4BC001FAD87 /* RileyLinkListTableViewController.h */, C12616311B65F4BC001FAD87 /* RileyLinkListTableViewController.m */, ); @@ -1686,14 +1679,13 @@ C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */, 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */, C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, + C17E14811CD2F46800851C67 /* RileyLinkDeviceViewController.swift in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */, C126162C1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, - C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */, - C12616571B6A6130001FAD87 /* PacketLogViewController.m in Sources */, C1EF589E1B3FBFE7001C8C80 /* MainAppViewController.m in Sources */, C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */, 43C99C6F1B898B7100BC03D4 /* MenuHeaderTableViewCell.m in Sources */, diff --git a/RileyLink/MySentryPairViewController.swift b/RileyLink/MySentryPairViewController.swift index 579af4bcd..c17544e5a 100644 --- a/RileyLink/MySentryPairViewController.swift +++ b/RileyLink/MySentryPairViewController.swift @@ -8,9 +8,9 @@ import UIKit import MinimedKit +import RileyLinkKit import RileyLinkBLEKit - class MySentryPairViewController: UIViewController, UITextFieldDelegate { enum PairingState { @@ -22,7 +22,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { case ReceivedLinkPacket } - var device: RileyLinkBLEDevice! + var device: RileyLinkDevice! var wasDismissed = false @IBOutlet var instructionLabel: UILabel! @@ -218,7 +218,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { } func runCommand(cmd: ReceivingPacketCmd) { - device.runSession { + device.device runSession { (session: RileyLinkCmdSession) -> Void in if (session.doCmd(cmd, withTimeoutMs: 31000)) { dispatch_async(dispatch_get_main_queue(), { () -> Void in diff --git a/RileyLink/PacketGeneratorViewController.h b/RileyLink/PacketGeneratorViewController.h deleted file mode 100644 index 98d9f94c5..000000000 --- a/RileyLink/PacketGeneratorViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// TestPacketSenderViewController.h -// RileyLink -// -// Created by Pete Schwamb on 7/31/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import -#import "RileyLinkBLEDevice.h" - -@interface PacketGeneratorViewController : UIViewController - -@property (nonatomic, strong) RileyLinkBLEDevice *device; - -@end diff --git a/RileyLink/PacketGeneratorViewController.m b/RileyLink/PacketGeneratorViewController.m deleted file mode 100644 index aa326dc52..000000000 --- a/RileyLink/PacketGeneratorViewController.m +++ /dev/null @@ -1,107 +0,0 @@ -// -// TestPacketSenderViewController.m -// RileyLink -// -// Created by Pete Schwamb on 7/31/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import "PacketGeneratorViewController.h" -#import "NSData+Conversion.h" -#import "SendPacketCmd.h" - -@interface PacketGeneratorViewController () { - int testPacketNum; - int txChannel; - IBOutlet UILabel *testPacketNumberLabel; - IBOutlet UISwitch *continuousSendSwitch; - IBOutlet UISwitch *encodeDataSwitch; - IBOutlet UITextField *channelNumberTextField; - IBOutlet UILabel *packetData; - NSTimer *timer; -} - - -@end - -@implementation PacketGeneratorViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - [self updatePacketNumberLabel]; - - UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)]; - numberToolbar.barStyle = UIBarStyleBlackTranslucent; - numberToolbar.items = @[[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], - [[UIBarButtonItem alloc]initWithTitle:@"Apply" style:UIBarButtonItemStyleDone target:self action:@selector(doneChangingChannel)]]; - [numberToolbar sizeToFit]; - channelNumberTextField.inputAccessoryView = numberToolbar; -} - -- (void)doneChangingChannel { - txChannel = (channelNumberTextField.text).intValue; - [channelNumberTextField resignFirstResponder]; -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (void)updatePacketNumberLabel { - testPacketNumberLabel.text = [NSString stringWithFormat:@"Test Packet Number: %03d", testPacketNum]; -} - -- (void)incrementPacketNum { - testPacketNum += 1; - if (testPacketNum > 255) { - testPacketNum = 0; - } - [self updatePacketNumberLabel]; -} - -- (void)sendTestPacket { - NSString *packetStr = [@"614C05E077" stringByAppendingFormat:@"%02x", testPacketNum]; - NSData *data = [NSData dataWithHexadecimalString:packetStr]; -// if (encodeDataSwitch.on) { -// data = [MinimedPacket encodeData:data]; -// } - packetData.text = data.hexadecimalString; - SendPacketCmd *cmd = [[SendPacketCmd alloc] init]; - cmd.sendChannel = txChannel; - cmd.repeatCount = 0; - cmd.msBetweenPackets = 0; - [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { - [session doCmd:cmd withTimeoutMs:1000]; - }]; -} - -- (IBAction)sendPacketButtonPressed:(id)sender { - [self sendTestPacket]; - [self incrementPacketNum]; -} - -- (void)timerFired:(id)sender { - [self sendTestPacket]; - [self incrementPacketNum]; -} - -- (IBAction)continuousSendSwitchToggled:(id)sender { - [timer invalidate]; - if (continuousSendSwitch.on) { - timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES]; - } -} - - -/* -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. -} -*/ - -@end diff --git a/RileyLink/PacketLogViewController.h b/RileyLink/PacketLogViewController.h deleted file mode 100644 index 13ce14cd2..000000000 --- a/RileyLink/PacketLogViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// PacketLogViewController.h -// RileyLink -// -// Created by Pete Schwamb on 7/30/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import -#import "RileyLinkBLEDevice.h" - -@interface PacketLogViewController : UITableViewController - -@property (nonatomic, strong) RileyLinkBLEDevice *device; - -@end diff --git a/RileyLink/PacketLogViewController.m b/RileyLink/PacketLogViewController.m deleted file mode 100644 index 246d119c4..000000000 --- a/RileyLink/PacketLogViewController.m +++ /dev/null @@ -1,116 +0,0 @@ -// -// PacketLogViewController.m -// RileyLink -// -// Created by Pete Schwamb on 7/30/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import "PacketLogViewController.h" -#import "PacketTableViewCell.h" -#import "RFPacket.h" -#import "RileyLinkBLEManager.h" - -@interface PacketLogViewController () { - NSMutableArray *packets; -} - -@end - -@implementation PacketLogViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - packets = [NSMutableArray array]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(packetReceived:) - name:RILEYLINK_EVENT_PACKET_RECEIVED - object:self.device]; - -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (void)packetReceived:(NSNotification*)notification { - [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic]; -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - // Return the number of sections. - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - // Return the number of rows in the section. - return packets.count; -} - -- (RFPacket *)packetForIndex:(NSInteger) idx { - return packets[packets.count - idx - 1]; -} - -- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - PacketTableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:@"packet" forIndexPath:indexPath]; - RFPacket *packet = [self packetForIndex:indexPath.row]; - cell.packet = packet; - return cell; -} - -/* - // Override to support conditional editing of the table view. - - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - // Return NO if you do not want the specified item to be editable. - return YES; - } - */ - -/* - // Override to support editing the table view. - - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - if (editingStyle == UITableViewCellEditingStyleDelete) { - // Delete the row from the data source - [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; - } else if (editingStyle == UITableViewCellEditingStyleInsert) { - // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view - } - } - */ - -/* - // Override to support rearranging the table view. - - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { - } - */ - -/* - // Override to support conditional rearranging of the table view. - - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { - // Return NO if you do not want the item to be re-orderable. - return YES; - } - */ - -/* - #pragma mark - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. - } - */ - - -@end diff --git a/RileyLink/PumpChatViewController.swift b/RileyLink/PumpChatViewController.swift index 0a8099692..fe46b3e48 100644 --- a/RileyLink/PumpChatViewController.swift +++ b/RileyLink/PumpChatViewController.swift @@ -13,87 +13,91 @@ import RileyLinkBLEKit class PumpChatViewController: UIViewController { - - @IBOutlet var output: UITextView! - @IBOutlet var batteryVoltage: UILabel! - @IBOutlet var pumpIdLabel: UILabel! - - var pumpOps: PumpOps! - var device: RileyLinkBLEDevice! - - override func viewDidLoad() { - super.viewDidLoad() - - pumpIdLabel.text = "PumpID: \(Config.sharedInstance().pumpID ?? "nil")" - let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate - pumpOps = PumpOps(pumpState:appDelegate.pump, device:device) - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - func addOutputMessage(msg: String) - { - output.text = output.text.stringByAppendingFormat("%@\n", msg) - NSLog("addOutputMessage: %@", msg) - } - - @IBAction func dumpHistoryButtonPressed(sender: UIButton) { - let calendar = NSCalendar.currentCalendar() - let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) - pumpOps.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in - switch response { - case .Success(let (events, _)): - self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) - for event in events { - self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) - NSLog("Event: %@", event.dictionaryRepresentation) + @IBOutlet var output: UITextView! + @IBOutlet var batteryVoltage: UILabel! + @IBOutlet var pumpIdLabel: UILabel! + + var device: RileyLinkDevice! + + override func viewDidLoad() { + super.viewDidLoad() + + pumpIdLabel.text = "PumpID: \(device.pumpState?.pumpID ?? "nil")" + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func addOutputMessage(msg: String) + { + output.text = output.text.stringByAppendingFormat("%@\n", msg) + NSLog("addOutputMessage: %@", msg) + } + + @IBAction func dumpHistoryButtonPressed(sender: UIButton) { + let calendar = NSCalendar.currentCalendar() + let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) + if let ops = device.ops { + ops.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in + switch response { + case .Success(let (events, _)): + self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) + for event in events { + self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) + NSLog("Event: %@", event.dictionaryRepresentation) + } + case .Failure(let error): + let errorMsg = String(format:"History fetch failed: %@", String(error)) + self.addOutputMessage(errorMsg) + } + } } - case .Failure(let error): - let errorMsg = String(format:"History fetch failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } } - } - - @IBAction func pressDownButtonPressed(sender: UIButton) { - pumpOps.pressButton() - } - - @IBAction func queryPumpButtonPressed(sender: UIButton) { - pumpOps.getPumpModel { (model) -> Void in - if let model = model { - self.addOutputMessage(String(format:"Pump Model: %@", model)) - } else { - self.addOutputMessage("Get pump model failed.") - } + + @IBAction func pressDownButtonPressed(sender: UIButton) { + if let pumpOps = device.ops { + pumpOps.pressButton() + } } - - pumpOps.getBatteryVoltage { (results) -> Void in - if let results = results { - self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) - } else { - self.addOutputMessage("Get battery voltage failed.") - } + + @IBAction func queryPumpButtonPressed(sender: UIButton) { + if let pumpOps = device.ops { + pumpOps.getPumpModel { (model) -> Void in + if let model = model { + self.addOutputMessage(String(format:"Pump Model: %@", model)) + } else { + self.addOutputMessage("Get pump model failed.") + } + } + + pumpOps.getBatteryVoltage { (results) -> Void in + if let results = results { + self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) + } else { + self.addOutputMessage("Get battery voltage failed.") + } + } + } } - } - - - @IBAction func tuneButtonPressed(sender: UIButton) { - pumpOps.tunePump { (result) -> Void in - switch result { - case .Success(let scanResults): - for trial in scanResults.trials { - self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) + + + @IBAction func tuneButtonPressed(sender: UIButton) { + if let pumpOps = device.ops { + pumpOps.tunePump { (result) -> Void in + switch result { + case .Success(let scanResults): + for trial in scanResults.trials { + self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) + } + self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) + case .Failure(let error): + let errorMsg = String(format:"Tune failed: %@", String(error)) + self.addOutputMessage(errorMsg) + } + } } - self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) - case .Failure(let error): - let errorMsg = String(format:"Tune failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } } - } } diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index f5fc0d9b4..9c03964c4 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -1,8 +1,8 @@ - + - + @@ -347,7 +347,7 @@ - + - - - - - - - - - - - - - - - @@ -737,7 +561,7 @@ - + @@ -841,7 +665,7 @@ - + diff --git a/RileyLinkDeviceViewController.swift b/RileyLinkDeviceViewController.swift new file mode 100644 index 000000000..228e2a50b --- /dev/null +++ b/RileyLinkDeviceViewController.swift @@ -0,0 +1,43 @@ +// +// RileyLinkDeviceViewController.swift +// RileyLink +// +// Created by Pete Schwamb on 4/28/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation +import UIKit +import RileyLinkKit + +class RileyLinkDeviceViewController : UIViewController { + + @IBOutlet var deviceIDLabel: UILabel! + @IBOutlet var nameView: UITextField! + @IBOutlet var autoConnectSwitch: UISwitch! + @IBOutlet var connectingIndicator: UIActivityIndicatorView! + + var device: RileyLinkDevice! + + var pumpTimeZone: NSTimeZone? + + + override func viewDidLoad() { + super.viewDidLoad() + + deviceIDLabel.text = device.peripheral.identifier.UUIDString + nameView.text = device.name + } + + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { + super.prepareForSegue(segue, sender: sender) + + switch segue.destinationViewController { + case let vc as MySentryPairViewController: + vc.device = device + case let vc as PumpChatViewController: + vc.device = device + } + } + +} \ No newline at end of file diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index 8a7c7e65b..768fc7543 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -161,4 +161,6 @@ public class PumpOps: NSObject { } } + + } From c67db3eb6f73777499903b661fbf307fd56f4356 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 28 Apr 2016 21:56:02 -0500 Subject: [PATCH 07/40] Revert "have viewcontrollers use RileyLinkDevice over RileyLinkBLEDevice" This reverts commit 53c109e1306bf7dd496c1a7179b81618d6ead8d7. --- RileyLink.xcodeproj/project.pbxproj | 16 +- RileyLink/MySentryPairViewController.swift | 6 +- RileyLink/PacketGeneratorViewController.h | 16 ++ RileyLink/PacketGeneratorViewController.m | 107 ++++++++++++ RileyLink/PacketLogViewController.h | 16 ++ RileyLink/PacketLogViewController.m | 116 +++++++++++++ RileyLink/PumpChatViewController.swift | 156 +++++++++-------- RileyLink/Storyboard.storyboard | 186 ++++++++++++++++++++- RileyLinkDeviceViewController.swift | 43 ----- RileyLinkKit/PumpOps.swift | 2 - 10 files changed, 527 insertions(+), 137 deletions(-) create mode 100644 RileyLink/PacketGeneratorViewController.h create mode 100644 RileyLink/PacketGeneratorViewController.m create mode 100644 RileyLink/PacketLogViewController.h create mode 100644 RileyLink/PacketLogViewController.m delete mode 100644 RileyLinkDeviceViewController.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 967cb8637..7c2b7566d 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -85,7 +85,9 @@ C12616441B685F0A001FAD87 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12616431B685F0A001FAD87 /* CoreData.framework */; }; C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C12616491B685F93001FAD87 /* RileyLink.xcdatamodeld */; }; C12616541B6892DB001FAD87 /* RileyLinkRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616531B6892DB001FAD87 /* RileyLinkRecord.m */; }; + C12616571B6A6130001FAD87 /* PacketLogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616561B6A6130001FAD87 /* PacketLogViewController.m */; }; C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */; }; + C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */; }; C12616671B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616601B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m */; }; C12616681B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616621B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m */; }; C12616691B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616641B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m */; }; @@ -116,7 +118,6 @@ C1711A5E1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */; }; C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C17E147D1CD2B92800851C67 /* CryptoSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C17E147C1CD2B92800851C67 /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C17E14811CD2F46800851C67 /* RileyLinkDeviceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17E14801CD2F46800851C67 /* RileyLinkDeviceViewController.swift */; }; C1842BBB1C8E184300DB42AC /* PumpModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBA1C8E184300DB42AC /* PumpModel.swift */; }; C1842BBD1C8E7C6E00DB42AC /* PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */; }; C1842BBF1C8E855A00DB42AC /* PumpEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */; }; @@ -400,8 +401,12 @@ 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 = ""; }; + C12616551B6A6130001FAD87 /* PacketLogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketLogViewController.h; sourceTree = ""; }; + C12616561B6A6130001FAD87 /* PacketLogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketLogViewController.m; sourceTree = ""; }; C12616581B6B2D20001FAD87 /* PacketTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketTableViewCell.h; sourceTree = ""; }; C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketTableViewCell.m; sourceTree = ""; }; + C126165B1B6C8076001FAD87 /* PacketGeneratorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketGeneratorViewController.h; sourceTree = ""; }; + C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketGeneratorViewController.m; sourceTree = ""; }; C126165F1B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingCollectionView.h; sourceTree = ""; }; C12616601B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingCollectionView.m; sourceTree = ""; }; C12616611B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPKeyboardAvoidingScrollView.h; sourceTree = ""; }; @@ -443,7 +448,6 @@ C174F26919EB824D00398C72 /* ISO8601DateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISO8601DateFormatter.h; sourceTree = ""; }; C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ISO8601DateFormatter.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; C17E147C1CD2B92800851C67 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; sourceTree = ""; }; - C17E14801CD2F46800851C67 /* RileyLinkDeviceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceViewController.swift; sourceTree = SOURCE_ROOT; }; C1842BBA1C8E184300DB42AC /* PumpModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpModel.swift; sourceTree = ""; }; C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEvent.swift; sourceTree = ""; }; C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEventType.swift; sourceTree = ""; }; @@ -1090,10 +1094,13 @@ C10AB08A1C8519E2000F102E /* MySentryPairViewController.swift */, C12EA26B198B456D00309FA4 /* NightscoutWebView.h */, C12EA26C198B456D00309FA4 /* NightscoutWebView.m */, + C126165B1B6C8076001FAD87 /* PacketGeneratorViewController.h */, + C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */, + C12616551B6A6130001FAD87 /* PacketLogViewController.h */, + C12616561B6A6130001FAD87 /* PacketLogViewController.m */, C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */, C126162A1B65E9BF001FAD87 /* RileyLinkDeviceViewController.h */, C126162B1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m */, - C17E14801CD2F46800851C67 /* RileyLinkDeviceViewController.swift */, C12616301B65F4BC001FAD87 /* RileyLinkListTableViewController.h */, C12616311B65F4BC001FAD87 /* RileyLinkListTableViewController.m */, ); @@ -1679,13 +1686,14 @@ C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */, 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */, C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, - C17E14811CD2F46800851C67 /* RileyLinkDeviceViewController.swift in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */, C126162C1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, + C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */, + C12616571B6A6130001FAD87 /* PacketLogViewController.m in Sources */, C1EF589E1B3FBFE7001C8C80 /* MainAppViewController.m in Sources */, C1EF588C1B3F9748001C8C80 /* SWRevealViewController.m in Sources */, 43C99C6F1B898B7100BC03D4 /* MenuHeaderTableViewCell.m in Sources */, diff --git a/RileyLink/MySentryPairViewController.swift b/RileyLink/MySentryPairViewController.swift index c17544e5a..579af4bcd 100644 --- a/RileyLink/MySentryPairViewController.swift +++ b/RileyLink/MySentryPairViewController.swift @@ -8,9 +8,9 @@ import UIKit import MinimedKit -import RileyLinkKit import RileyLinkBLEKit + class MySentryPairViewController: UIViewController, UITextFieldDelegate { enum PairingState { @@ -22,7 +22,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { case ReceivedLinkPacket } - var device: RileyLinkDevice! + var device: RileyLinkBLEDevice! var wasDismissed = false @IBOutlet var instructionLabel: UILabel! @@ -218,7 +218,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { } func runCommand(cmd: ReceivingPacketCmd) { - device.device runSession { + device.runSession { (session: RileyLinkCmdSession) -> Void in if (session.doCmd(cmd, withTimeoutMs: 31000)) { dispatch_async(dispatch_get_main_queue(), { () -> Void in diff --git a/RileyLink/PacketGeneratorViewController.h b/RileyLink/PacketGeneratorViewController.h new file mode 100644 index 000000000..98d9f94c5 --- /dev/null +++ b/RileyLink/PacketGeneratorViewController.h @@ -0,0 +1,16 @@ +// +// TestPacketSenderViewController.h +// RileyLink +// +// Created by Pete Schwamb on 7/31/15. +// Copyright (c) 2015 Pete Schwamb. All rights reserved. +// + +#import +#import "RileyLinkBLEDevice.h" + +@interface PacketGeneratorViewController : UIViewController + +@property (nonatomic, strong) RileyLinkBLEDevice *device; + +@end diff --git a/RileyLink/PacketGeneratorViewController.m b/RileyLink/PacketGeneratorViewController.m new file mode 100644 index 000000000..aa326dc52 --- /dev/null +++ b/RileyLink/PacketGeneratorViewController.m @@ -0,0 +1,107 @@ +// +// TestPacketSenderViewController.m +// RileyLink +// +// Created by Pete Schwamb on 7/31/15. +// Copyright (c) 2015 Pete Schwamb. All rights reserved. +// + +#import "PacketGeneratorViewController.h" +#import "NSData+Conversion.h" +#import "SendPacketCmd.h" + +@interface PacketGeneratorViewController () { + int testPacketNum; + int txChannel; + IBOutlet UILabel *testPacketNumberLabel; + IBOutlet UISwitch *continuousSendSwitch; + IBOutlet UISwitch *encodeDataSwitch; + IBOutlet UITextField *channelNumberTextField; + IBOutlet UILabel *packetData; + NSTimer *timer; +} + + +@end + +@implementation PacketGeneratorViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self updatePacketNumberLabel]; + + UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)]; + numberToolbar.barStyle = UIBarStyleBlackTranslucent; + numberToolbar.items = @[[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], + [[UIBarButtonItem alloc]initWithTitle:@"Apply" style:UIBarButtonItemStyleDone target:self action:@selector(doneChangingChannel)]]; + [numberToolbar sizeToFit]; + channelNumberTextField.inputAccessoryView = numberToolbar; +} + +- (void)doneChangingChannel { + txChannel = (channelNumberTextField.text).intValue; + [channelNumberTextField resignFirstResponder]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)updatePacketNumberLabel { + testPacketNumberLabel.text = [NSString stringWithFormat:@"Test Packet Number: %03d", testPacketNum]; +} + +- (void)incrementPacketNum { + testPacketNum += 1; + if (testPacketNum > 255) { + testPacketNum = 0; + } + [self updatePacketNumberLabel]; +} + +- (void)sendTestPacket { + NSString *packetStr = [@"614C05E077" stringByAppendingFormat:@"%02x", testPacketNum]; + NSData *data = [NSData dataWithHexadecimalString:packetStr]; +// if (encodeDataSwitch.on) { +// data = [MinimedPacket encodeData:data]; +// } + packetData.text = data.hexadecimalString; + SendPacketCmd *cmd = [[SendPacketCmd alloc] init]; + cmd.sendChannel = txChannel; + cmd.repeatCount = 0; + cmd.msBetweenPackets = 0; + [_device runSession:^(RileyLinkCmdSession * _Nonnull session) { + [session doCmd:cmd withTimeoutMs:1000]; + }]; +} + +- (IBAction)sendPacketButtonPressed:(id)sender { + [self sendTestPacket]; + [self incrementPacketNum]; +} + +- (void)timerFired:(id)sender { + [self sendTestPacket]; + [self incrementPacketNum]; +} + +- (IBAction)continuousSendSwitchToggled:(id)sender { + [timer invalidate]; + if (continuousSendSwitch.on) { + timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES]; + } +} + + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/RileyLink/PacketLogViewController.h b/RileyLink/PacketLogViewController.h new file mode 100644 index 000000000..13ce14cd2 --- /dev/null +++ b/RileyLink/PacketLogViewController.h @@ -0,0 +1,16 @@ +// +// PacketLogViewController.h +// RileyLink +// +// Created by Pete Schwamb on 7/30/15. +// Copyright (c) 2015 Pete Schwamb. All rights reserved. +// + +#import +#import "RileyLinkBLEDevice.h" + +@interface PacketLogViewController : UITableViewController + +@property (nonatomic, strong) RileyLinkBLEDevice *device; + +@end diff --git a/RileyLink/PacketLogViewController.m b/RileyLink/PacketLogViewController.m new file mode 100644 index 000000000..246d119c4 --- /dev/null +++ b/RileyLink/PacketLogViewController.m @@ -0,0 +1,116 @@ +// +// PacketLogViewController.m +// RileyLink +// +// Created by Pete Schwamb on 7/30/15. +// Copyright (c) 2015 Pete Schwamb. All rights reserved. +// + +#import "PacketLogViewController.h" +#import "PacketTableViewCell.h" +#import "RFPacket.h" +#import "RileyLinkBLEManager.h" + +@interface PacketLogViewController () { + NSMutableArray *packets; +} + +@end + +@implementation PacketLogViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + packets = [NSMutableArray array]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(packetReceived:) + name:RILEYLINK_EVENT_PACKET_RECEIVED + object:self.device]; + +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)packetReceived:(NSNotification*)notification { + [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic]; +} + +#pragma mark - Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // Return the number of sections. + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + // Return the number of rows in the section. + return packets.count; +} + +- (RFPacket *)packetForIndex:(NSInteger) idx { + return packets[packets.count - idx - 1]; +} + +- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + PacketTableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:@"packet" forIndexPath:indexPath]; + RFPacket *packet = [self packetForIndex:indexPath.row]; + cell.packet = packet; + return cell; +} + +/* + // Override to support conditional editing of the table view. + - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; + } + */ + +/* + // Override to support editing the table view. + - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete the row from the data source + [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } + } + */ + +/* + // Override to support rearranging the table view. + - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { + } + */ + +/* + // Override to support conditional rearranging of the table view. + - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; + } + */ + +/* + #pragma mark - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. + } + */ + + +@end diff --git a/RileyLink/PumpChatViewController.swift b/RileyLink/PumpChatViewController.swift index fe46b3e48..0a8099692 100644 --- a/RileyLink/PumpChatViewController.swift +++ b/RileyLink/PumpChatViewController.swift @@ -13,91 +13,87 @@ import RileyLinkBLEKit class PumpChatViewController: UIViewController { + + @IBOutlet var output: UITextView! + @IBOutlet var batteryVoltage: UILabel! + @IBOutlet var pumpIdLabel: UILabel! + + var pumpOps: PumpOps! + var device: RileyLinkBLEDevice! + + override func viewDidLoad() { + super.viewDidLoad() + + pumpIdLabel.text = "PumpID: \(Config.sharedInstance().pumpID ?? "nil")" - @IBOutlet var output: UITextView! - @IBOutlet var batteryVoltage: UILabel! - @IBOutlet var pumpIdLabel: UILabel! - - var device: RileyLinkDevice! - - override func viewDidLoad() { - super.viewDidLoad() - - pumpIdLabel.text = "PumpID: \(device.pumpState?.pumpID ?? "nil")" - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - func addOutputMessage(msg: String) - { - output.text = output.text.stringByAppendingFormat("%@\n", msg) - NSLog("addOutputMessage: %@", msg) - } - - @IBAction func dumpHistoryButtonPressed(sender: UIButton) { - let calendar = NSCalendar.currentCalendar() - let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) - if let ops = device.ops { - ops.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in - switch response { - case .Success(let (events, _)): - self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) - for event in events { - self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) - NSLog("Event: %@", event.dictionaryRepresentation) - } - case .Failure(let error): - let errorMsg = String(format:"History fetch failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } - } + let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate + pumpOps = PumpOps(pumpState:appDelegate.pump, device:device) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func addOutputMessage(msg: String) + { + output.text = output.text.stringByAppendingFormat("%@\n", msg) + NSLog("addOutputMessage: %@", msg) + } + + @IBAction func dumpHistoryButtonPressed(sender: UIButton) { + let calendar = NSCalendar.currentCalendar() + let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) + pumpOps.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in + switch response { + case .Success(let (events, _)): + self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) + for event in events { + self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) + NSLog("Event: %@", event.dictionaryRepresentation) } + case .Failure(let error): + let errorMsg = String(format:"History fetch failed: %@", String(error)) + self.addOutputMessage(errorMsg) + } } - - @IBAction func pressDownButtonPressed(sender: UIButton) { - if let pumpOps = device.ops { - pumpOps.pressButton() - } + } + + @IBAction func pressDownButtonPressed(sender: UIButton) { + pumpOps.pressButton() + } + + @IBAction func queryPumpButtonPressed(sender: UIButton) { + pumpOps.getPumpModel { (model) -> Void in + if let model = model { + self.addOutputMessage(String(format:"Pump Model: %@", model)) + } else { + self.addOutputMessage("Get pump model failed.") + } } - - @IBAction func queryPumpButtonPressed(sender: UIButton) { - if let pumpOps = device.ops { - pumpOps.getPumpModel { (model) -> Void in - if let model = model { - self.addOutputMessage(String(format:"Pump Model: %@", model)) - } else { - self.addOutputMessage("Get pump model failed.") - } - } - - pumpOps.getBatteryVoltage { (results) -> Void in - if let results = results { - self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) - } else { - self.addOutputMessage("Get battery voltage failed.") - } - } - } + + pumpOps.getBatteryVoltage { (results) -> Void in + if let results = results { + self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) + } else { + self.addOutputMessage("Get battery voltage failed.") + } } - - - @IBAction func tuneButtonPressed(sender: UIButton) { - if let pumpOps = device.ops { - pumpOps.tunePump { (result) -> Void in - switch result { - case .Success(let scanResults): - for trial in scanResults.trials { - self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) - } - self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) - case .Failure(let error): - let errorMsg = String(format:"Tune failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } - } + } + + + @IBAction func tuneButtonPressed(sender: UIButton) { + pumpOps.tunePump { (result) -> Void in + switch result { + case .Success(let scanResults): + for trial in scanResults.trials { + self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) } + self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) + case .Failure(let error): + let errorMsg = String(format:"Tune failed: %@", String(error)) + self.addOutputMessage(errorMsg) + } } + } } diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 9c03964c4..f5fc0d9b4 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -1,8 +1,8 @@ - + - + @@ -347,7 +347,7 @@ - + + + + + + + + + + + + + + + + @@ -561,7 +737,7 @@ - + @@ -665,7 +841,7 @@ - + diff --git a/RileyLinkDeviceViewController.swift b/RileyLinkDeviceViewController.swift deleted file mode 100644 index 228e2a50b..000000000 --- a/RileyLinkDeviceViewController.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// RileyLinkDeviceViewController.swift -// RileyLink -// -// Created by Pete Schwamb on 4/28/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -import Foundation -import UIKit -import RileyLinkKit - -class RileyLinkDeviceViewController : UIViewController { - - @IBOutlet var deviceIDLabel: UILabel! - @IBOutlet var nameView: UITextField! - @IBOutlet var autoConnectSwitch: UISwitch! - @IBOutlet var connectingIndicator: UIActivityIndicatorView! - - var device: RileyLinkDevice! - - var pumpTimeZone: NSTimeZone? - - - override func viewDidLoad() { - super.viewDidLoad() - - deviceIDLabel.text = device.peripheral.identifier.UUIDString - nameView.text = device.name - } - - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { - super.prepareForSegue(segue, sender: sender) - - switch segue.destinationViewController { - case let vc as MySentryPairViewController: - vc.device = device - case let vc as PumpChatViewController: - vc.device = device - } - } - -} \ No newline at end of file diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index 768fc7543..8a7c7e65b 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -161,6 +161,4 @@ public class PumpOps: NSObject { } } - - } From 2b33333dba64bcf77069f0907ecaf687ad6202af Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 28 Apr 2016 22:09:02 -0500 Subject: [PATCH 08/40] use pump ops from preferredRileyLink --- NightscoutUploadKit/NightscoutUploader.swift | 10 ++++++---- RileyLink/DeviceDataManager.swift | 4 ++-- RileyLink/PumpChatViewController.swift | 4 +--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index f88f059ff..922df4786 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -18,8 +18,8 @@ public class NightscoutUploader: NSObject { case BadRF = 12 } - public var siteURL: String = "" - public var APISecret: String = "" + public var siteURL: String? + public var APISecret: String? var fetchHistoryScheduled: Bool = false var lastHistoryAttempt: NSDate? @@ -258,7 +258,9 @@ public class NightscoutUploader: NSObject { return } - if let uploadURL = NSURL(string: endpoint, relativeToURL: NSURL(string: siteURL)) { + if let siteURL = siteURL, + let APISecret = APISecret, + let uploadURL = NSURL(string: endpoint, relativeToURL: NSURL(string: siteURL)) { let request = NSMutableURLRequest(URL: uploadURL) do { let sendData = try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted) @@ -266,7 +268,7 @@ public class NightscoutUploader: NSObject { request.setValue("application/json", forHTTPHeaderField:"Content-Type") request.setValue("application/json", forHTTPHeaderField:"Accept") - request.setValue(self.APISecret.sha1(), forHTTPHeaderField:"api-secret") + request.setValue(APISecret.sha1(), forHTTPHeaderField:"api-secret") request.HTTPBody = sendData let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index d109c19f7..a868bebc3 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -202,8 +202,8 @@ class DeviceDataManager { ) nightscoutUploader = NightscoutUploader() - nightscoutUploader.siteURL = Config.sharedInstance().nightscoutURL! - nightscoutUploader.APISecret = Config.sharedInstance().nightscoutAPISecret! + nightscoutUploader.siteURL = Config.sharedInstance().nightscoutURL + nightscoutUploader.APISecret = Config.sharedInstance().nightscoutAPISecret let calendar = NSCalendar.currentCalendar() diff --git a/RileyLink/PumpChatViewController.swift b/RileyLink/PumpChatViewController.swift index 0a8099692..c2ec2d64d 100644 --- a/RileyLink/PumpChatViewController.swift +++ b/RileyLink/PumpChatViewController.swift @@ -25,9 +25,7 @@ class PumpChatViewController: UIViewController { super.viewDidLoad() pumpIdLabel.text = "PumpID: \(Config.sharedInstance().pumpID ?? "nil")" - - let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate - pumpOps = PumpOps(pumpState:appDelegate.pump, device:device) + pumpOps = DeviceDataManager.sharedManager.preferredRileyLink()?.ops } override func didReceiveMemoryWarning() { From bef9494e4ede8c740861126798b762dbc0da88b1 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 4 May 2016 22:41:22 -0500 Subject: [PATCH 09/40] handleDeviceStatus --- NightscoutUploadKit/NightscoutUploader.swift | 576 ++++++++++--------- RileyLink/DeviceDataManager.swift | 2 + 2 files changed, 292 insertions(+), 286 deletions(-) diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index 922df4786..39af8007e 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -11,318 +11,322 @@ import MinimedKit import CryptoSwift public class NightscoutUploader: NSObject { - - enum DexcomSensorError: UInt8 { - case SensorNotActive = 1 - case SensorNotCalibrated = 5 - case BadRF = 12 - } - - public var siteURL: String? - public var APISecret: String? - - var fetchHistoryScheduled: Bool = false - var lastHistoryAttempt: NSDate? - var entries: [AnyObject] - var deviceStatuses: [AnyObject] - var treatmentsQueue: [AnyObject] - - var lastMeterMessageRxTime: NSDate? - - var observingPumpEventsSince: NSDate - - let defaultNightscoutEntriesPath = "/api/v1/entries.json" - let defaultNightscoutTreatmentPath = "/api/v1/treatments.json" - let defaultNightscoutDeviceStatusPath = "/api/v1/devicestatus.json" - public override init() { - entries = [AnyObject]() - treatmentsQueue = [AnyObject]() - deviceStatuses = [AnyObject]() + enum DexcomSensorError: UInt8 { + case SensorNotActive = 1 + case SensorNotCalibrated = 5 + case BadRF = 12 + } + + public var siteURL: String? + public var APISecret: String? - let calendar = NSCalendar.currentCalendar() - observingPumpEventsSince = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: [])! + var fetchHistoryScheduled: Bool = false + var lastHistoryAttempt: NSDate? + var entries: [AnyObject] + var deviceStatuses: [AnyObject] + var treatmentsQueue: [AnyObject] - super.init() - } + var lastMeterMessageRxTime: NSDate? - // MARK: - Decoding Treatments - - public func processPumpEvents(events: [PumpEvent], source: String, pumpModel: PumpModel) { + var observingPumpEventsSince: NSDate - // Find valid event times - var validEventTimes = [NSDate]() - for event in events { - if event is TimestampedPumpEvent { - let timestamp = (event as! TimestampedPumpEvent).timestamp - if let date = TimeFormat.timestampAsLocalDate(timestamp) { - validEventTimes.append(date) - } - } + let defaultNightscoutEntriesPath = "/api/v1/entries.json" + let defaultNightscoutTreatmentPath = "/api/v1/treatments.json" + let defaultNightscoutDeviceStatusPath = "/api/v1/devicestatus.json" + + public override init() { + entries = [AnyObject]() + treatmentsQueue = [AnyObject]() + deviceStatuses = [AnyObject]() + + let calendar = NSCalendar.currentCalendar() + observingPumpEventsSince = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: [])! + + super.init() } - let newestEventTime = validEventTimes.last + // MARK: - Decoding Treatments - // Find the oldest event that might still be updated. - var oldestUpdatingEventDate: NSDate? - let cal = NSCalendar.currentCalendar() - for event in events { - switch event { - case is BolusNormalPumpEvent: - let event = event as! BolusNormalPumpEvent - if let date = TimeFormat.timestampAsLocalDate(event.timestamp) { - let duration = NSDateComponents() - duration.minute = event.duration - let deliveryFinishDate = cal.dateByAddingComponents(duration, toDate: date, options: NSCalendarOptions(rawValue:0)) - if newestEventTime == nil || deliveryFinishDate?.compare(newestEventTime!) == .OrderedDescending { - // This event might still be updated. - oldestUpdatingEventDate = date - break - } + public func processPumpEvents(events: [PumpEvent], source: String, pumpModel: PumpModel) { + + // Find valid event times + var validEventTimes = [NSDate]() + for event in events { + if event is TimestampedPumpEvent { + let timestamp = (event as! TimestampedPumpEvent).timestamp + if let date = TimeFormat.timestampAsLocalDate(timestamp) { + validEventTimes.append(date) + } + } } - default: - continue - } + let newestEventTime = validEventTimes.last + + + // Find the oldest event that might still be updated. + var oldestUpdatingEventDate: NSDate? + let cal = NSCalendar.currentCalendar() + for event in events { + switch event { + case is BolusNormalPumpEvent: + let event = event as! BolusNormalPumpEvent + if let date = TimeFormat.timestampAsLocalDate(event.timestamp) { + let duration = NSDateComponents() + duration.minute = event.duration + let deliveryFinishDate = cal.dateByAddingComponents(duration, toDate: date, options: NSCalendarOptions(rawValue:0)) + if newestEventTime == nil || deliveryFinishDate?.compare(newestEventTime!) == .OrderedDescending { + // This event might still be updated. + oldestUpdatingEventDate = date + break + } + } + default: + continue + } + } + + if oldestUpdatingEventDate != nil { + observingPumpEventsSince = oldestUpdatingEventDate! + } else if newestEventTime != nil { + observingPumpEventsSince = newestEventTime! + } + NSLog("Updated fetch start time to %@", observingPumpEventsSince) + + for treatment in NightscoutPumpEvents.translate(events, eventSource: source) { + addTreatment(treatment, pumpModel:pumpModel) + } + self.flushAll() } - if oldestUpdatingEventDate != nil { - observingPumpEventsSince = oldestUpdatingEventDate! - } else if newestEventTime != nil { - observingPumpEventsSince = newestEventTime! + func addTreatment(treatment:NightscoutTreatment, pumpModel:PumpModel) { + var rep = treatment.dictionaryRepresentation + if rep["created_at"] == nil && rep["timestamp"] != nil { + rep["created_at"] = rep["timestamp"] + } + if rep["created_at"] == nil { + rep["created_at"] = TimeFormat.timestampStrFromDate(NSDate()) + } + treatmentsQueue.append(rep) } - NSLog("Updated fetch start time to %@", observingPumpEventsSince) - for treatment in NightscoutPumpEvents.translate(events, eventSource: source) { - addTreatment(treatment, pumpModel:pumpModel) - } - self.flushAll() - } - - func addTreatment(treatment:NightscoutTreatment, pumpModel:PumpModel) { - var rep = treatment.dictionaryRepresentation - if rep["created_at"] == nil && rep["timestamp"] != nil { - rep["created_at"] = rep["timestamp"] - } - if rep["created_at"] == nil { - rep["created_at"] = TimeFormat.timestampStrFromDate(NSDate()) - } - treatmentsQueue.append(rep) - } - - - // Entries [ { sgv: 375, - // date: 1432421525000, - // dateString: '2015-05-23T22:52:05.000Z', - // trend: 1, - // direction: 'DoubleUp', - // device: 'share2', - // type: 'sgv' } ] - - func handlePumpStatus(status: MySentryPumpStatusMessageBody, device: String, rssi: Int) { - enum DexcomSensorErrorType: Int { - case DX_SENSOR_NOT_ACTIVE = 1 - case DX_SENSOR_NOT_CALIBRATED = 5 - case DX_BAD_RF = 12 - } - - let glucose: Int = { - switch status.glucose { - case .Active(glucose: let glucose): - return glucose - case .HighBG: - return 401 - case .WeakSignal: - return DexcomSensorErrorType.DX_BAD_RF.rawValue - case .MeterBGNow, .CalError: - return DexcomSensorErrorType.DX_SENSOR_NOT_CALIBRATED.rawValue - case .Lost, .Missing, .Ended, .Unknown, .Off, .Warmup: - return DexcomSensorErrorType.DX_SENSOR_NOT_ACTIVE.rawValue + // Entries [ { sgv: 375, + // date: 1432421525000, + // dateString: '2015-05-23T22:52:05.000Z', + // trend: 1, + // direction: 'DoubleUp', + // device: 'share2', + // type: 'sgv' } ] + + 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 } - }() - - // Create deviceStatus record from this mysentry packet - - var nsStatus = [String: AnyObject]() - - nsStatus["device"] = device - nsStatus["created_at"] = TimeFormat.timestampStrFromDate(NSDate()) - - // TODO: use battery monitoring to post updates if we're not hearing from pump? - - let uploaderDevice = UIDevice.currentDevice() - - if uploaderDevice.batteryMonitoringEnabled { - nsStatus["uploader"] = ["battery":uploaderDevice.batteryLevel * 100] - } - - let pumpDate = TimeFormat.timestampStr(status.pumpDateComponents) - - nsStatus["pump"] = [ - "clock": pumpDate, - "iob": [ - "timestamp": pumpDate, - "bolusiob": status.iob, - ], - "reservoir": status.reservoirRemainingUnits, - "battery": [ - "percent": status.batteryRemainingPercent - ] - ] - - switch status.glucose { - case .Active(glucose: _): - nsStatus["sensor"] = [ - "sensorAge": status.sensorAgeHours, - "sensorRemaining": status.sensorRemainingHours, + + var recordSGV = true + + let glucose: Int = { + switch status.glucose { + case .Active(glucose: let glucose): + return glucose + case .HighBG: + return 401 + case .WeakSignal: + return DexcomSensorErrorType.DX_BAD_RF.rawValue + case .MeterBGNow, .CalError: + return DexcomSensorErrorType.DX_SENSOR_NOT_CALIBRATED.rawValue + case .Lost, .Missing, .Ended, .Unknown, .Off, .Warmup: + recordSGV = false + return DexcomSensorErrorType.DX_SENSOR_NOT_ACTIVE.rawValue + } + }() + + // Create deviceStatus record from this mysentry packet + + var nsStatus = [String: AnyObject]() + + nsStatus["device"] = device + nsStatus["created_at"] = TimeFormat.timestampStrFromDate(NSDate()) + + // TODO: use battery monitoring to post updates if we're not hearing from pump? + + let uploaderDevice = UIDevice.currentDevice() + + if uploaderDevice.batteryMonitoringEnabled { + nsStatus["uploader"] = ["battery":uploaderDevice.batteryLevel * 100] + } + + let pumpDate = TimeFormat.timestampStr(status.pumpDateComponents) + + nsStatus["pump"] = [ + "clock": pumpDate, + "iob": [ + "timestamp": pumpDate, + "bolusiob": status.iob, + ], + "reservoir": status.reservoirRemainingUnits, + "battery": [ + "percent": status.batteryRemainingPercent + ] ] - default: - nsStatus["sensorNotActive"] = true - } - deviceStatuses.append(nsStatus) - - - // Create SGV entry from this mysentry packet - var entry: [String: AnyObject] = [ - "sgv": glucose, - "device": device, - "rssi": rssi, - "type": "sgv" - ] - if let sensorDateComponents = status.glucoseDateComponents, - let sensorDate = TimeFormat.timestampAsLocalDate(sensorDateComponents) { - entry["date"] = sensorDate.timeIntervalSince1970 * 1000 - entry["dateString"] = TimeFormat.timestampStr(sensorDateComponents) - } - switch status.previousGlucose { - case .Active(glucose: let previousGlucose): - entry["previousSGV"] = previousGlucose - default: - entry["previousSGVNotActive"] = true - } - entry["direction"] = { - switch status.glucoseTrend { - case .Up: - return "SingleUp" - case .UpUp: - return "DoubleUp" - case .Down: - return "SingleDown" - case .DownDown: - return "DoubleDown" - case .Flat: - return "Flat" + + switch status.glucose { + case .Active(glucose: _): + nsStatus["sensor"] = [ + "sensorAge": status.sensorAgeHours, + "sensorRemaining": status.sensorRemainingHours, + ] + default: + nsStatus["sensorNotActive"] = true + } + deviceStatuses.append(nsStatus) + + + // Create SGV entry from this mysentry packet + if (recordSGV) { + var entry: [String: AnyObject] = [ + "sgv": glucose, + "device": device, + "type": "sgv" + ] + if let sensorDateComponents = status.glucoseDateComponents, + let sensorDate = TimeFormat.timestampAsLocalDate(sensorDateComponents) { + entry["date"] = sensorDate.timeIntervalSince1970 * 1000 + entry["dateString"] = TimeFormat.timestampStr(sensorDateComponents) + } + switch status.previousGlucose { + case .Active(glucose: let previousGlucose): + entry["previousSGV"] = previousGlucose + default: + entry["previousSGVNotActive"] = true + } + entry["direction"] = { + switch status.glucoseTrend { + case .Up: + return "SingleUp" + case .UpUp: + return "DoubleUp" + case .Down: + return "SingleDown" + case .DownDown: + return "DoubleDown" + case .Flat: + return "Flat" + } + }() + entries.append(entry) } - }() - entries.append(entry) - } - - public func handleMeterMessage(msg: MeterMessage) { - - // TODO: Should only accept meter messages from specified meter ids. - // Need to add an interface to allow user to specify linked meters. - - if msg.ackFlag { - return } - let date = NSDate() - let epochTime = date.timeIntervalSince1970 * 1000 - let entry = [ - "date": epochTime, - "dateString": TimeFormat.timestampStrFromDate(date), - "mbg": msg.glucose, - "device": "Contour Next Link", - "type": "mbg" - ] - - // Skip duplicates - if lastMeterMessageRxTime == nil || lastMeterMessageRxTime!.timeIntervalSinceNow < -3 * 60 { - entries.append(entry) - lastMeterMessageRxTime = NSDate() + public func handleMeterMessage(msg: MeterMessage) { + + // TODO: Should only accept meter messages from specified meter ids. + // Need to add an interface to allow user to specify linked meters. + + if msg.ackFlag { + return + } + + let date = NSDate() + let epochTime = date.timeIntervalSince1970 * 1000 + let entry = [ + "date": epochTime, + "dateString": TimeFormat.timestampStrFromDate(date), + "mbg": msg.glucose, + "device": "Contour Next Link", + "type": "mbg" + ] + + // Skip duplicates + if lastMeterMessageRxTime == nil || lastMeterMessageRxTime!.timeIntervalSinceNow < -3 * 60 { + entries.append(entry) + lastMeterMessageRxTime = NSDate() + } } - } - - // MARK: - Uploading - - func flushAll() { - flushDeviceStatuses() - flushEntries() - flushTreatments() - } - - func uploadToNS(json: [AnyObject], endpoint:String, completion: (String?) -> Void) { - if json.count == 0 { - completion(nil) - return - } + // MARK: - Uploading - if let siteURL = siteURL, - let APISecret = APISecret, - let uploadURL = NSURL(string: endpoint, relativeToURL: NSURL(string: siteURL)) { - let request = NSMutableURLRequest(URL: uploadURL) - do { - let sendData = try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted) - request.HTTPMethod = "POST" + func flushAll() { - request.setValue("application/json", forHTTPHeaderField:"Content-Type") - request.setValue("application/json", forHTTPHeaderField:"Accept") - request.setValue(APISecret.sha1(), forHTTPHeaderField:"api-secret") - request.HTTPBody = sendData - - let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in - let httpResponse = response as! NSHTTPURLResponse - if let error = error { - completion(error.description) - } else if httpResponse.statusCode != 200 { - completion(String(data: data!, encoding: NSUTF8StringEncoding)!) - } else { + flushDeviceStatuses() + flushEntries() + flushTreatments() + } + + func uploadToNS(json: [AnyObject], endpoint:String, completion: (String?) -> Void) { + if json.count == 0 { completion(nil) - } - }) - task.resume() - } catch { - completion("Couldn't encode data to json.") - } - } else { - completion("Invalid URL: \(siteURL), \(endpoint)") + return + } + + if let siteURL = siteURL, + let APISecret = APISecret, + let uploadURL = NSURL(string: endpoint, relativeToURL: NSURL(string: siteURL)) { + let request = NSMutableURLRequest(URL: uploadURL) + do { + let sendData = try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted) + request.HTTPMethod = "POST" + + request.setValue("application/json", forHTTPHeaderField:"Content-Type") + request.setValue("application/json", forHTTPHeaderField:"Accept") + request.setValue(APISecret.sha1(), forHTTPHeaderField:"api-secret") + request.HTTPBody = sendData + + let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in + let httpResponse = response as! NSHTTPURLResponse + if let error = error { + completion(error.description) + } else if httpResponse.statusCode != 200 { + completion(String(data: data!, encoding: NSUTF8StringEncoding)!) + } else { + completion(nil) + } + }) + task.resume() + } catch { + completion("Couldn't encode data to json.") + } + } else { + completion("Invalid URL: \(siteURL), \(endpoint)") + } } - } - - func flushDeviceStatuses() { - let inFlight = deviceStatuses - deviceStatuses = [AnyObject]() - uploadToNS(inFlight, endpoint: defaultNightscoutDeviceStatusPath) { (error) in - if error != nil { - NSLog("Uploading device status to nightscout failed: %@", error!) - // Requeue - self.deviceStatuses.appendContentsOf(inFlight) - } + + func flushDeviceStatuses() { + let inFlight = deviceStatuses + deviceStatuses = [AnyObject]() + uploadToNS(inFlight, endpoint: defaultNightscoutDeviceStatusPath) { (error) in + if error != nil { + NSLog("Uploading device status to nightscout failed: %@", error!) + // Requeue + self.deviceStatuses.appendContentsOf(inFlight) + } + } } - } - - func flushEntries() { - let inFlight = entries - entries = [AnyObject]() - uploadToNS(inFlight, endpoint: defaultNightscoutEntriesPath) { (error) in - if error != nil { - NSLog("Uploading nightscout entries failed: %@", error!) - // Requeue - self.entries.appendContentsOf(inFlight) - } + + func flushEntries() { + let inFlight = entries + entries = [AnyObject]() + uploadToNS(inFlight, endpoint: defaultNightscoutEntriesPath) { (error) in + if error != nil { + NSLog("Uploading nightscout entries failed: %@", error!) + // Requeue + self.entries.appendContentsOf(inFlight) + } + } } - } - - func flushTreatments() { - let inFlight = treatmentsQueue - treatmentsQueue = [AnyObject]() - uploadToNS(inFlight, endpoint: defaultNightscoutTreatmentPath) { (error) in - if error != nil { - NSLog("Uploading nightscout treatment records failed: %@", error!) - // Requeue - self.treatmentsQueue.appendContentsOf(inFlight) - } + + func flushTreatments() { + let inFlight = treatmentsQueue + treatmentsQueue = [AnyObject]() + uploadToNS(inFlight, endpoint: defaultNightscoutTreatmentPath) { (error) in + if error != nil { + NSLog("Uploading nightscout treatment records failed: %@", error!) + // Requeue + self.treatmentsQueue.appendContentsOf(inFlight) + } + } } - } } diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index a868bebc3..a6fc1b935 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -148,6 +148,8 @@ class DeviceDataManager { if status.batteryRemainingPercent == 0 { //NotificationManager.sendPumpBatteryLowNotification() } + let source = "rileylink://medtronic/\(device.name)" + nightscoutUploader.handlePumpStatus(status, device: source) // Sentry packets are sent in groups of 3, 5s apart. Wait 11s to avoid conflicting comms. let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(11 * NSEC_PER_SEC)) From d9dd2bcaeb5e1ddde67d204151f008ad4e94cb1d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 4 May 2016 23:23:01 -0500 Subject: [PATCH 10/40] Use loudnate/Crypto --- Cartfile | 2 +- Cartfile.resolved | 2 +- NightscoutUploadKit/NightscoutUploader.swift | 4 ++-- RileyLink.xcodeproj/project.pbxproj | 12 ++++-------- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Cartfile b/Cartfile index dfa8f09ff..60e2dcc01 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "krzyzanowskim/CryptoSwift" +github "loudnate/Crypto" diff --git a/Cartfile.resolved b/Cartfile.resolved index 2d1ab2d92..31788b5b5 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "krzyzanowskim/CryptoSwift" "0.4" +github "loudnate/Crypto" "v0.3.0" diff --git a/NightscoutUploadKit/NightscoutUploader.swift b/NightscoutUploadKit/NightscoutUploader.swift index 39af8007e..723ac2f79 100644 --- a/NightscoutUploadKit/NightscoutUploader.swift +++ b/NightscoutUploadKit/NightscoutUploader.swift @@ -8,7 +8,7 @@ import UIKit import MinimedKit -import CryptoSwift +import Crypto public class NightscoutUploader: NSObject { @@ -272,7 +272,7 @@ public class NightscoutUploader: NSObject { request.setValue("application/json", forHTTPHeaderField:"Content-Type") request.setValue("application/json", forHTTPHeaderField:"Accept") - request.setValue(APISecret.sha1(), forHTTPHeaderField:"api-secret") + request.setValue(APISecret.SHA1, forHTTPHeaderField:"api-secret") request.HTTPBody = sendData let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 8405a36e0..5a76ebc62 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -90,6 +90,7 @@ C12616681B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616621B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m */; }; C12616691B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616641B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m */; }; C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616661B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m */; }; + C12618461CDB019C0064A849 /* Crypto.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C12618451CDB019C0064A849 /* Crypto.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C1271B071A9A34E900B7C949 /* Log.m in Sources */ = {isa = PBXBuildFile; fileRef = C1271B061A9A34E900B7C949 /* Log.m */; }; C12EA23B198B436800309FA4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23A198B436800309FA4 /* Foundation.framework */; }; C12EA23D198B436800309FA4 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12EA23C198B436800309FA4 /* CoreGraphics.framework */; }; @@ -115,7 +116,6 @@ C1711A5C1C953F3000CB25BD /* GetBatteryCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A5B1C953F3000CB25BD /* GetBatteryCarelinkMessageBody.swift */; }; C1711A5E1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */; }; C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - C17E147D1CD2B92800851C67 /* CryptoSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C17E147C1CD2B92800851C67 /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C1842BBB1C8E184300DB42AC /* PumpModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBA1C8E184300DB42AC /* PumpModel.swift */; }; C1842BBD1C8E7C6E00DB42AC /* PumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */; }; C1842BBF1C8E855A00DB42AC /* PumpEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */; }; @@ -187,7 +187,6 @@ C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; C1B383311CD068C300CE7782 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 430D64CB1CB855AB00FCA750 /* RileyLinkBLEKit.framework */; }; C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */; }; - C1B383381CD1BECD00CE7782 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1B383371CD1BECD00CE7782 /* CryptoSwift.framework */; }; 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 */; }; @@ -310,7 +309,7 @@ C10D9BD71C8269D500378342 /* MinimedKit.framework in Embed Frameworks */, C1B383211CD0665D00CE7782 /* NightscoutUploadKit.framework in Embed Frameworks */, 430D64E11CB855AB00FCA750 /* RileyLinkBLEKit.framework in Embed Frameworks */, - C17E147D1CD2B92800851C67 /* CryptoSwift.framework in Embed Frameworks */, + C12618461CDB019C0064A849 /* Crypto.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -412,6 +411,7 @@ C12616641B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPKeyboardAvoidingTableView.m; sourceTree = ""; }; C12616651B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+TPKeyboardAvoidingAdditions.h"; sourceTree = ""; }; C12616661B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = "UIScrollView+TPKeyboardAvoidingAdditions.m"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + C12618451CDB019C0064A849 /* Crypto.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crypto.framework; path = Carthage/Build/iOS/Crypto.framework; 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 = ""; }; C12EA237198B436800309FA4 /* RileyLink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RileyLink.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -444,7 +444,6 @@ C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetHistoryPageCarelinkMessageBody.swift; sourceTree = ""; }; C174F26919EB824D00398C72 /* ISO8601DateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISO8601DateFormatter.h; sourceTree = ""; }; C174F26A19EB824D00398C72 /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ISO8601DateFormatter.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - C17E147C1CD2B92800851C67 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; sourceTree = ""; }; C1842BBA1C8E184300DB42AC /* PumpModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpModel.swift; sourceTree = ""; }; C1842BBC1C8E7C6E00DB42AC /* PumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEvent.swift; sourceTree = ""; }; C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpEventType.swift; sourceTree = ""; }; @@ -515,7 +514,6 @@ C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadKitTests.swift; sourceTree = ""; }; 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 = ""; }; - C1B383371CD1BECD00CE7782 /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; 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 = ""; }; @@ -641,7 +639,6 @@ files = ( C1B383311CD068C300CE7782 /* RileyLinkBLEKit.framework in Frameworks */, C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */, - C1B383381CD1BECD00CE7782 /* CryptoSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -821,7 +818,6 @@ C12EA22E198B436800309FA4 = { isa = PBXGroup; children = ( - C17E147C1CD2B92800851C67 /* CryptoSwift.framework */, C12EA240198B436800309FA4 /* RileyLink */, C12EA259198B436900309FA4 /* RileyLinkTests */, C10D9BC21C8269D500378342 /* MinimedKit */, @@ -857,7 +853,7 @@ C12EA239198B436800309FA4 /* Frameworks */ = { isa = PBXGroup; children = ( - C1B383371CD1BECD00CE7782 /* CryptoSwift.framework */, + C12618451CDB019C0064A849 /* Crypto.framework */, 43CA93241CB8BB33000026B5 /* CoreBluetooth.framework */, C12616431B685F0A001FAD87 /* CoreData.framework */, C12EA23A198B436800309FA4 /* Foundation.framework */, From 2f7912a2b6653c1e1fc722712935306ed72424f7 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 13 May 2016 23:29:19 -0500 Subject: [PATCH 11/40] devicedatamanager --- RileyLink.xcodeproj/project.pbxproj | 34 +- RileyLink/AppDelegate.swift | 5 +- RileyLink/Config.m | 22 +- RileyLink/DeviceDataManager.swift | 6 +- RileyLink/IdentifiableClass.swift | 21 + RileyLink/MainAppViewController.m | 7 - RileyLink/MySentryPairViewController.swift | 492 +++++++++--------- RileyLink/PumpChatViewController.swift | 148 +++--- RileyLink/RileyLink-Bridging-Header.h | 1 + RileyLink/RileyLinkDeviceTableViewCell.swift | 51 ++ RileyLink/RileyLinkDeviceViewController.h | 19 - RileyLink/RileyLinkDeviceViewController.m | 134 ----- RileyLink/RileyLinkDeviceViewController.swift | 33 ++ RileyLink/RileyLinkListTableViewController.h | 15 - RileyLink/RileyLinkListTableViewController.m | 211 -------- .../RileyLinkListTableViewController.swift | 168 ++++++ RileyLink/Storyboard.storyboard | 120 ++--- RileyLinkBLEKit/RileyLinkBLEDevice.m | 4 +- RileyLinkBLEKit/RileyLinkBLEManager.m | 4 + RileyLinkKit/PumpOpsSynchronous.swift | 3 +- 20 files changed, 676 insertions(+), 822 deletions(-) create mode 100644 RileyLink/IdentifiableClass.swift create mode 100644 RileyLink/RileyLinkDeviceTableViewCell.swift delete mode 100644 RileyLink/RileyLinkDeviceViewController.h delete mode 100644 RileyLink/RileyLinkDeviceViewController.m create mode 100644 RileyLink/RileyLinkDeviceViewController.swift delete mode 100644 RileyLink/RileyLinkListTableViewController.h delete mode 100644 RileyLink/RileyLinkListTableViewController.m create mode 100644 RileyLink/RileyLinkListTableViewController.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 5a76ebc62..db9504069 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -77,8 +77,6 @@ C12198AF1C8F46FF00BC374C /* TimeFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12198AE1C8F46FF00BC374C /* TimeFormat.swift */; }; C12198B11C8F6DD800BC374C /* TimeFormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12198B01C8F6DD800BC374C /* TimeFormatTests.swift */; }; C12198B31C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12198B21C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift */; }; - C126162C1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C126162B1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m */; }; - C12616321B65F4BC001FAD87 /* RileyLinkListTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C12616311B65F4BC001FAD87 /* RileyLinkListTableViewController.m */; }; C126163C1B67CBC2001FAD87 /* RileyLinkTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = C126163B1B67CBC2001FAD87 /* RileyLinkTableViewCell.m */; }; C12616441B685F0A001FAD87 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C12616431B685F0A001FAD87 /* CoreData.framework */; }; C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C12616491B685F93001FAD87 /* RileyLink.xcdatamodeld */; }; @@ -187,6 +185,10 @@ C1B383301CD0680800CE7782 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; C1B383311CD068C300CE7782 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 430D64CB1CB855AB00FCA750 /* RileyLinkBLEKit.framework */; }; C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */; }; + C1C2EB541CE35BDC0070E259 /* RileyLinkListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C2EB531CE35BDC0070E259 /* RileyLinkListTableViewController.swift */; }; + C1C2EB561CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */; }; + C1C2EB581CE585250070E259 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C2EB571CE585250070E259 /* IdentifiableClass.swift */; }; + C1C2EB5A1CE588350070E259 /* RileyLinkDeviceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C2EB591CE588350070E259 /* RileyLinkDeviceViewController.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 */; }; @@ -387,10 +389,6 @@ C12198AE1C8F46FF00BC374C /* TimeFormat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeFormat.swift; sourceTree = ""; }; C12198B01C8F6DD800BC374C /* TimeFormatTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeFormatTests.swift; sourceTree = ""; }; C12198B21C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BolusWizardEstimatePumpEvent.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C126162A1B65E9BF001FAD87 /* RileyLinkDeviceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RileyLinkDeviceViewController.h; sourceTree = ""; }; - C126162B1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RileyLinkDeviceViewController.m; sourceTree = ""; }; - C12616301B65F4BC001FAD87 /* RileyLinkListTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RileyLinkListTableViewController.h; sourceTree = ""; }; - C12616311B65F4BC001FAD87 /* RileyLinkListTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RileyLinkListTableViewController.m; sourceTree = ""; }; C126163A1B67CBC2001FAD87 /* RileyLinkTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RileyLinkTableViewCell.h; sourceTree = ""; }; C126163B1B67CBC2001FAD87 /* RileyLinkTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RileyLinkTableViewCell.m; sourceTree = ""; }; C12616431B685F0A001FAD87 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; @@ -514,6 +512,10 @@ C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadKitTests.swift; sourceTree = ""; }; 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 = ""; }; + C1C2EB531CE35BDC0070E259 /* RileyLinkListTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkListTableViewController.swift; sourceTree = ""; }; + C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; + C1C2EB571CE585250070E259 /* IdentifiableClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifiableClass.swift; sourceTree = ""; }; + C1C2EB591CE588350070E259 /* RileyLinkDeviceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceViewController.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 = ""; }; @@ -786,6 +788,7 @@ C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */, C126163A1B67CBC2001FAD87 /* RileyLinkTableViewCell.h */, C126163B1B67CBC2001FAD87 /* RileyLinkTableViewCell.m */, + C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */, ); name = TableViewCells; sourceTree = ""; @@ -868,7 +871,7 @@ isa = PBXGroup; children = ( C1B383341CD1BA6700CE7782 /* Managers */, - C1AA398B1AB67F6A00BC9E33 /* Categories */, + C1AA398B1AB67F6A00BC9E33 /* Extensions */, C12616451B685F35001FAD87 /* CoreData */, C12EA241198B436800309FA4 /* Supporting Files */, C1EF58891B3F9730001C8C80 /* SWRevealViewController */, @@ -983,15 +986,16 @@ path = PumpEvents; sourceTree = ""; }; - C1AA398B1AB67F6A00BC9E33 /* Categories */ = { + C1AA398B1AB67F6A00BC9E33 /* Extensions */ = { isa = PBXGroup; children = ( C1E535E81991E36700C2AC49 /* NSData+Conversion.h */, C1E535E91991E36700C2AC49 /* NSData+Conversion.m */, C1AA39921AB6804000BC9E33 /* UIAlertView+Blocks.h */, C1AA39931AB6804000BC9E33 /* UIAlertView+Blocks.m */, + C1C2EB571CE585250070E259 /* IdentifiableClass.swift */, ); - name = Categories; + name = Extensions; sourceTree = ""; }; C1B3830C1CD0665D00CE7782 /* NightscoutUploadKit */ = { @@ -1091,10 +1095,8 @@ C12616551B6A6130001FAD87 /* PacketLogViewController.h */, C12616561B6A6130001FAD87 /* PacketLogViewController.m */, C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */, - C126162A1B65E9BF001FAD87 /* RileyLinkDeviceViewController.h */, - C126162B1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m */, - C12616301B65F4BC001FAD87 /* RileyLinkListTableViewController.h */, - C12616311B65F4BC001FAD87 /* RileyLinkListTableViewController.m */, + C1C2EB591CE588350070E259 /* RileyLinkDeviceViewController.swift */, + C1C2EB531CE35BDC0070E259 /* RileyLinkListTableViewController.swift */, ); name = ViewControllers; sourceTree = ""; @@ -1664,22 +1666,24 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C1C2EB5A1CE588350070E259 /* RileyLinkDeviceViewController.swift in Sources */, C12616691B76E8DC001FAD87 /* TPKeyboardAvoidingTableView.m in Sources */, C12616681B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m in Sources */, - C12616321B65F4BC001FAD87 /* RileyLinkListTableViewController.m in Sources */, C1EF58971B3FA462001C8C80 /* MenuController.m in Sources */, C139AC241BFD84B500B0518F /* RuntimeUtils.m in Sources */, + C1C2EB561CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift in Sources */, C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */, C12EA26D198B456D00309FA4 /* NightscoutWebView.m in Sources */, C12616541B6892DB001FAD87 /* RileyLinkRecord.m in Sources */, C12616671B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m in Sources */, C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */, + C1C2EB581CE585250070E259 /* IdentifiableClass.swift in Sources */, 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */, C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, + C1C2EB541CE35BDC0070E259 /* RileyLinkListTableViewController.swift in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */, - C126162C1B65E9BF001FAD87 /* RileyLinkDeviceViewController.m in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */, diff --git a/RileyLink/AppDelegate.swift b/RileyLink/AppDelegate.swift index 80ed500a2..e18a8c925 100644 --- a/RileyLink/AppDelegate.swift +++ b/RileyLink/AppDelegate.swift @@ -25,7 +25,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } // Just instantiate the DeviceDataManager - DeviceDataManager.sharedManager + let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))) + dispatch_after(delayTime, dispatch_get_main_queue()) { + DeviceDataManager.sharedManager + } return true } diff --git a/RileyLink/Config.m b/RileyLink/Config.m index d2ee9511f..b3b271d4a 100644 --- a/RileyLink/Config.m +++ b/RileyLink/Config.m @@ -88,27 +88,15 @@ - (BOOL) hasValidConfiguration { } - (NSSet*) autoConnectIds { - AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; - NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext; - - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; - NSEntityDescription *entity = [NSEntityDescription entityForName:@"RileyLinkRecord" - inManagedObjectContext:managedObjectContext]; - fetchRequest.entity = entity; - NSError *error; - NSMutableSet *autoConnectIds = [[NSMutableSet alloc] init]; - NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; - for (RileyLinkRecord *record in fetchedObjects) { - NSLog(@"Loaded: %@ from db", record.name); - if ((record.autoConnect).boolValue) { - [autoConnectIds addObject:record.peripheralId]; - } + NSSet *set = [[NSUserDefaults standardUserDefaults] objectForKey:@"autoConnectIds"]; + if (!set) { + set = [NSSet set]; } - return autoConnectIds; + return set; } - (void) setAutoConnectIds:(NSSet *)autoConnectIds { - + [[NSUserDefaults standardUserDefaults] setObject:[autoConnectIds allObjects] forKey:@"autoConnectIds"]; } diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index a6fc1b935..af67ba909 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -20,7 +20,11 @@ class DeviceDataManager { let rileyLinkManager: RileyLinkDeviceManager - var connectedPeripheralIDs: Set = Config.sharedInstance().autoConnectIds as! Set + var connectedPeripheralIDs: Set = Config.sharedInstance().autoConnectIds as! Set { + didSet { + Config.sharedInstance().autoConnectIds = connectedPeripheralIDs + } + } var latestPumpStatus: MySentryPumpStatusMessageBody? diff --git a/RileyLink/IdentifiableClass.swift b/RileyLink/IdentifiableClass.swift new file mode 100644 index 000000000..c5e48080b --- /dev/null +++ b/RileyLink/IdentifiableClass.swift @@ -0,0 +1,21 @@ +// +// IdentifiableClass.swift +// Naterade +// +// Created by Nathan Racklyeft on 2/9/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public protocol IdentifiableClass: class { + static var className: String { get } +} + + +extension IdentifiableClass { + public static var className: String { + return NSStringFromClass(self).componentsSeparatedByString(".").last! + } +} \ No newline at end of file diff --git a/RileyLink/MainAppViewController.m b/RileyLink/MainAppViewController.m index 28be59e66..7162e5327 100644 --- a/RileyLink/MainAppViewController.m +++ b/RileyLink/MainAppViewController.m @@ -36,13 +36,6 @@ - (void)viewDidLoad { self.managedObjectContext = appDelegate.managedObjectContext; } -- (void)viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; - - NSLog(@"Stopping scan"); - [RileyLinkBLEManager sharedManager].scanningEnabled = NO; -} - - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. diff --git a/RileyLink/MySentryPairViewController.swift b/RileyLink/MySentryPairViewController.swift index 579af4bcd..0a1860c3b 100644 --- a/RileyLink/MySentryPairViewController.swift +++ b/RileyLink/MySentryPairViewController.swift @@ -8,277 +8,265 @@ import UIKit import MinimedKit +import RileyLinkKit import RileyLinkBLEKit class MySentryPairViewController: UIViewController, UITextFieldDelegate { - - enum PairingState { - case Complete - case NeedsConfig - case Ready - case Started - case ReceivedFindPacket - case ReceivedLinkPacket - } - - var device: RileyLinkBLEDevice! - var wasDismissed = false - - @IBOutlet var instructionLabel: UILabel! - @IBOutlet var deviceIDTextField: UITextField! - @IBOutlet var startButton: UIButton! - @IBOutlet var progressView: UIProgressView! - - lazy var flailGestureRecognizer: UITapGestureRecognizer = { - let r = UITapGestureRecognizer(target: self, action: #selector(MySentryPairViewController.closeKeyboard(_:))) - r.cancelsTouchesInView = false; - r.enabled = false; - return r - }() - - var sendCounter: UInt8 = 0 - - override func viewDidLoad() { - super.viewDidLoad() - deviceIDTextField.text = (device.peripheral.identifier.UUIDString as NSString).substringToIndex(6); - deviceIDTextField.delegate = self + enum PairingState { + case Complete + case NeedsConfig + case Ready + case Started + case ReceivedFindPacket + case ReceivedLinkPacket + } - view.addGestureRecognizer(flailGestureRecognizer) - - textFieldDidEndEditing(deviceIDTextField) - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - override func viewDidDisappear(animated: Bool) { - wasDismissed = true - } - - - // MARK: - UITextFieldDelegate - - func textFieldDidBeginEditing(textField: UITextField) { - flailGestureRecognizer.enabled = true - } - - func textFieldDidEndEditing(textField: UITextField) { - flailGestureRecognizer.enabled = false - - if textField.text?.characters.count == 6 { - state = .Ready - } else if .Ready == self.state { - state = .NeedsConfig + var device: RileyLinkDevice! + var wasDismissed = false + + @IBOutlet var instructionLabel: UILabel! + @IBOutlet var deviceIDTextField: UITextField! + @IBOutlet var startButton: UIButton! + @IBOutlet var progressView: UIProgressView! + + lazy var flailGestureRecognizer: UITapGestureRecognizer = { + let r = UITapGestureRecognizer(target: self, action: #selector(MySentryPairViewController.closeKeyboard(_:))) + r.cancelsTouchesInView = false; + r.enabled = false; + return r + }() + + var sendCounter: UInt8 = 0 + + override func viewDidLoad() { + super.viewDidLoad() + + deviceIDTextField.text = (device.peripheral.identifier.UUIDString as NSString).substringToIndex(6); + deviceIDTextField.delegate = self + + view.addGestureRecognizer(flailGestureRecognizer) + + textFieldDidEndEditing(deviceIDTextField) } - } - - func textField(textField: UITextField, - shouldChangeCharactersInRange range: NSRange, - replacementString string: String) -> Bool { - let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString:string) - - if newString.characters.count > 6 { - return false - } else if newString.characters.count == 6 { - textField.text = newString - textField.resignFirstResponder() - return false - } else if .Ready == self.state { - state = .NeedsConfig - } - - return true - } - - func textFieldShouldReturn(textField: UITextField) -> Bool { - return true - } - - // MARK: - Other - - func listenForPairing() { - if wasDismissed { - return + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + override func viewDidDisappear(animated: Bool) { + wasDismissed = true + } + + + // MARK: - UITextFieldDelegate + + func textFieldDidBeginEditing(textField: UITextField) { + flailGestureRecognizer.enabled = true } - let cmd = GetPacketCmd() - cmd.listenChannel = 0; - cmd.timeoutMS = 30000; - runCommand(cmd) - } - - var state: PairingState = .NeedsConfig { - didSet { - if (oldValue == state) { - return - } - switch state { - case .NeedsConfig: - startButton.enabled = false - startButton.hidden = true - instructionLabel.text = NSLocalizedString( - "Enter a 6-digit numeric value to identify your MySentry.", - comment: "Device ID instruction") - instructionLabel.hidden = false - case .Ready: - startButton.enabled = true - startButton.hidden = false - progressView.progress = 0 + func textFieldDidEndEditing(textField: UITextField) { + flailGestureRecognizer.enabled = false - instructionLabel.hidden = true - case .Started: - startButton.enabled = false - startButton.hidden = true - deviceIDTextField.enabled = false - progressView.setProgress(1.0 / 4.0, animated:true) + if textField.text?.characters.count == 6 { + state = .Ready + } else if .Ready == self.state { + state = .NeedsConfig + } + } + + func textField(textField: UITextField, + shouldChangeCharactersInRange range: NSRange, + replacementString string: String) -> Bool { + let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString:string) - instructionLabel.text = NSLocalizedString( - "On your pump, go to the Find Device screen and select \"Find Device\"." + - "\n" + - "\nMain Menu >" + - "\nUtilities >" + - "\nConnect Devices >" + - "\nOther Devices >" + - "\nOn >" + - "\nFind Device", - comment: "Pump find device instruction") - instructionLabel.hidden = false - case .ReceivedFindPacket: - progressView.setProgress(2.0 / 4.0, animated:true) + if newString.characters.count > 6 { + return false + } else if newString.characters.count == 6 { + textField.text = newString + textField.resignFirstResponder() + return false + } else if .Ready == self.state { + state = .NeedsConfig + } - instructionLabel.text = NSLocalizedString( - "Pairing in process, please wait.", - comment: "Pairing waiting instruction") - case .ReceivedLinkPacket: - progressView.setProgress(3.0 / 4.0, animated:true) - instructionLabel.text = NSLocalizedString( - "Pump accepted pairing. " + - "Waiting for MySentry update from pump. " + - "This could take up to five minutes...", - comment: "Pairing waiting instruction") - case .Complete: - progressView.setProgress(4.0 / 4.0, animated:true) + return true + } + + func textFieldShouldReturn(textField: UITextField) -> Bool { + return true + } + + // MARK: - Other + + func listenForPairing() { + if wasDismissed { + return + } - instructionLabel.text = NSLocalizedString( - "Congratulations! Pairing is complete.", - comment: "Pairing waiting instruction") - } + let cmd = GetPacketCmd() + cmd.listenChannel = 0; + cmd.timeoutMS = 30000; + runCommand(cmd) } - } - - // MARK: - Actions - - func packetReceived(packet: RFPacket) { - - var handled = false - - if let data = packet.data, msg = PumpMessage(rxData: data) { - if msg.packetType == PacketType.MySentry && - msg.address.hexadecimalString == Config.sharedInstance().pumpID { - switch (msg.messageType) { - case MessageType.FindDevice: - handleFindDevice(msg.messageBody as! FindDeviceMessageBody) - handled = true - case MessageType.DeviceLink: - handleDeviceLink(msg.messageBody as! DeviceLinkMessageBody) - handled = true - case MessageType.PumpStatus: - handlePumpStatus(msg.messageBody as! MySentryPumpStatusMessageBody) - handled = true - default: - NSLog("Unexpected packet received: " + String(msg.messageType)) - } - } + + var state: PairingState = .NeedsConfig { + didSet { + if (oldValue == state) { + return + } + switch state { + case .NeedsConfig: + startButton.enabled = false + startButton.hidden = true + instructionLabel.text = NSLocalizedString( + "Enter a 6-digit numeric value to identify your MySentry.", + comment: "Device ID instruction") + instructionLabel.hidden = false + case .Ready: + startButton.enabled = true + startButton.hidden = false + progressView.progress = 0 + + instructionLabel.hidden = true + case .Started: + startButton.enabled = false + startButton.hidden = true + deviceIDTextField.enabled = false + progressView.setProgress(1.0 / 4.0, animated:true) + + instructionLabel.text = NSLocalizedString( + "On your pump, go to the Find Device screen and select \"Find Device\"." + + "\n" + + "\nMain Menu >" + + "\nUtilities >" + + "\nConnect Devices >" + + "\nOther Devices >" + + "\nOn >" + + "\nFind Device", + comment: "Pump find device instruction") + instructionLabel.hidden = false + case .ReceivedFindPacket: + progressView.setProgress(2.0 / 4.0, animated:true) + + instructionLabel.text = NSLocalizedString( + "Pairing in process, please wait.", + comment: "Pairing waiting instruction") + case .ReceivedLinkPacket: + progressView.setProgress(3.0 / 4.0, animated:true) + instructionLabel.text = NSLocalizedString( + "Pump accepted pairing. " + + "Waiting for MySentry update from pump. " + + "This could take up to five minutes...", + comment: "Pairing waiting instruction") + case .Complete: + progressView.setProgress(4.0 / 4.0, animated:true) + + instructionLabel.text = NSLocalizedString( + "Congratulations! Pairing is complete.", + comment: "Pairing waiting instruction") + } + } } - if (!handled && .Complete != self.state) { - // Other random packet; ignore and start listening again. - performSelector(#selector(MySentryPairViewController.listenForPairing), withObject:nil, afterDelay:0) + + // MARK: - Actions + + func packetReceived(packet: RFPacket) { + + var handled = false + + if let data = packet.data, msg = PumpMessage(rxData: data) { + if msg.packetType == PacketType.MySentry && + msg.address.hexadecimalString == Config.sharedInstance().pumpID { + switch (msg.messageType) { + case MessageType.FindDevice: + handleFindDevice(msg.messageBody as! FindDeviceMessageBody) + handled = true + case MessageType.DeviceLink: + handleDeviceLink(msg.messageBody as! DeviceLinkMessageBody) + handled = true + case MessageType.PumpStatus: + handlePumpStatus(msg.messageBody as! MySentryPumpStatusMessageBody) + handled = true + default: + NSLog("Unexpected packet received: " + String(msg.messageType)) + } + } + } + if (!handled && .Complete != self.state) { + // Other random packet; ignore and start listening again. + performSelector(#selector(MySentryPairViewController.listenForPairing), withObject:nil, afterDelay:0) + } } - } - - func makeCommandForAckAndListen(sequence: UInt8, messageType: MessageType) -> ReceivingPacketCmd { - let replyString = String(format: "%02x%@%02x%02x%@00%02x000000", - PacketType.MySentry.rawValue, - Config.sharedInstance().pumpID!, - MessageType.PumpAck.rawValue, - sequence, - self.deviceIDTextField.text!, - messageType.rawValue) - let data = NSData(hexadecimalString: replyString) - let send = SendAndListenCmd() - send.sendChannel = 0 - send.timeoutMS = 180 - send.listenChannel = 0 - send.packet = RFPacket(data: data!) - return send; - } - - func runCommand(cmd: ReceivingPacketCmd) { - device.runSession { - (session: RileyLinkCmdSession) -> Void in - if (session.doCmd(cmd, withTimeoutMs: 31000)) { - dispatch_async(dispatch_get_main_queue(), { () -> Void in - let rxPacket = cmd.receivedPacket - self.packetReceived(rxPacket) - }) - } else { - // Timed out. Try again - self.performSelector(#selector(MySentryPairViewController.listenForPairing), withObject:nil, afterDelay:0) - } + + func makeCommandForAckAndListen(sequence: UInt8, messageType: MessageType) -> ReceivingPacketCmd { + let replyString = String(format: "%02x%@%02x%02x%@00%02x000000", + PacketType.MySentry.rawValue, + Config.sharedInstance().pumpID!, + MessageType.PumpAck.rawValue, + sequence, + self.deviceIDTextField.text!, + messageType.rawValue) + let data = NSData(hexadecimalString: replyString) + let send = SendAndListenCmd() + send.sendChannel = 0 + send.timeoutMS = 180 + send.listenChannel = 0 + send.packet = RFPacket(data: data!) + return send; } - } - - func handleFindDevice(msg: FindDeviceMessageBody) { - if .Started == self.state { - self.state = .ReceivedFindPacket + + func runCommand(cmd: ReceivingPacketCmd) { + device.ops?.device.runSession { + (session: RileyLinkCmdSession) -> Void in + if (session.doCmd(cmd, withTimeoutMs: 31000)) { + dispatch_async(dispatch_get_main_queue(), { () -> Void in + let rxPacket = cmd.receivedPacket + self.packetReceived(rxPacket) + }) + } else { + // Timed out. Try again + self.performSelector(#selector(MySentryPairViewController.listenForPairing), withObject:nil, afterDelay:0) + } + } } - - let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.FindDevice) - runCommand(cmd) - } - - func handleDeviceLink(msg: DeviceLinkMessageBody) { - if .ReceivedFindPacket == self.state { - self.state = .ReceivedLinkPacket + + func handleFindDevice(msg: FindDeviceMessageBody) { + if .Started == self.state { + self.state = .ReceivedFindPacket + } + + let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.FindDevice) + runCommand(cmd) } - - let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.DeviceLink) - runCommand(cmd) - } - - func handlePumpStatus(msg: MySentryPumpStatusMessageBody) { - if .ReceivedLinkPacket == self.state { - self.state = .Complete; + + func handleDeviceLink(msg: DeviceLinkMessageBody) { + if .ReceivedFindPacket == self.state { + self.state = .ReceivedLinkPacket + } + + let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.DeviceLink) + runCommand(cmd) } - let cmd = makeCommandForAckAndListen(0, messageType: MessageType.PumpStatus) - runCommand(cmd) - } - - func closeKeyboard(recognizer: UITapGestureRecognizer) { - self.view.endEditing(true) - } - - @IBAction func startPairing(sender: UIButton) { - if (.Ready == self.state) { - self.state = .Started - listenForPairing() + + func handlePumpStatus(msg: MySentryPumpStatusMessageBody) { + if .ReceivedLinkPacket == self.state { + self.state = .Complete; + } + let cmd = makeCommandForAckAndListen(0, messageType: MessageType.PumpStatus) + runCommand(cmd) + } + + func closeKeyboard(recognizer: UITapGestureRecognizer) { + self.view.endEditing(true) + } + + @IBAction func startPairing(sender: UIButton) { + if (.Ready == self.state) { + self.state = .Started + listenForPairing() + } } - } - - - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { - // Get the new view controller using segue.destinationViewController. - // Pass the selected object to the new view controller. - } - */ - } diff --git a/RileyLink/PumpChatViewController.swift b/RileyLink/PumpChatViewController.swift index c2ec2d64d..f177f5996 100644 --- a/RileyLink/PumpChatViewController.swift +++ b/RileyLink/PumpChatViewController.swift @@ -13,85 +13,83 @@ import RileyLinkBLEKit class PumpChatViewController: UIViewController { - - @IBOutlet var output: UITextView! - @IBOutlet var batteryVoltage: UILabel! - @IBOutlet var pumpIdLabel: UILabel! - - var pumpOps: PumpOps! - var device: RileyLinkBLEDevice! - - override func viewDidLoad() { - super.viewDidLoad() - - pumpIdLabel.text = "PumpID: \(Config.sharedInstance().pumpID ?? "nil")" - pumpOps = DeviceDataManager.sharedManager.preferredRileyLink()?.ops - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - func addOutputMessage(msg: String) - { - output.text = output.text.stringByAppendingFormat("%@\n", msg) - NSLog("addOutputMessage: %@", msg) - } - - @IBAction func dumpHistoryButtonPressed(sender: UIButton) { - let calendar = NSCalendar.currentCalendar() - let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) - pumpOps.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in - switch response { - case .Success(let (events, _)): - self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) - for event in events { - self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) - NSLog("Event: %@", event.dictionaryRepresentation) + + @IBOutlet var output: UITextView! + @IBOutlet var batteryVoltage: UILabel! + @IBOutlet var pumpIdLabel: UILabel! + + var device: RileyLinkDevice! + + override func viewDidLoad() { + super.viewDidLoad() + + pumpIdLabel.text = "PumpID: \(Config.sharedInstance().pumpID ?? "nil")" + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func addOutputMessage(msg: String) + { + output.text = output.text.stringByAppendingFormat("%@\n", msg) + NSLog("addOutputMessage: %@", msg) + } + + @IBAction func dumpHistoryButtonPressed(sender: UIButton) { + let calendar = NSCalendar.currentCalendar() + let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) + device.ops?.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in + switch response { + case .Success(let (events, _)): + self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) + for event in events { + self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) + NSLog("Event: %@", event.dictionaryRepresentation) + } + case .Failure(let error): + let errorMsg = String(format:"History fetch failed: %@", String(error)) + self.addOutputMessage(errorMsg) + } } - case .Failure(let error): - let errorMsg = String(format:"History fetch failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } } - } - - @IBAction func pressDownButtonPressed(sender: UIButton) { - pumpOps.pressButton() - } - - @IBAction func queryPumpButtonPressed(sender: UIButton) { - pumpOps.getPumpModel { (model) -> Void in - if let model = model { - self.addOutputMessage(String(format:"Pump Model: %@", model)) - } else { - self.addOutputMessage("Get pump model failed.") - } + + @IBAction func pressDownButtonPressed(sender: UIButton) { + device.ops?.pressButton() } - - pumpOps.getBatteryVoltage { (results) -> Void in - if let results = results { - self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) - } else { - self.addOutputMessage("Get battery voltage failed.") - } + + @IBAction func queryPumpButtonPressed(sender: UIButton) { + device.ops?.getPumpModel { (model) -> Void in + if let model = model { + self.addOutputMessage(String(format:"Pump Model: %@", model)) + } else { + self.addOutputMessage("Get pump model failed.") + } + } + + device.ops!.getBatteryVoltage { (results) -> Void in + if let results = results { + self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) + } else { + self.addOutputMessage("Get battery voltage failed.") + } + } } - } - - - @IBAction func tuneButtonPressed(sender: UIButton) { - pumpOps.tunePump { (result) -> Void in - switch result { - case .Success(let scanResults): - for trial in scanResults.trials { - self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) + + + @IBAction func tuneButtonPressed(sender: UIButton) { + device.ops?.tunePump { (result) -> Void in + switch result { + case .Success(let scanResults): + for trial in scanResults.trials { + self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) + } + self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) + case .Failure(let error): + let errorMsg = String(format:"Tune failed: %@", String(error)) + self.addOutputMessage(errorMsg) + } } - self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) - case .Failure(let error): - let errorMsg = String(format:"Tune failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } } - } } diff --git a/RileyLink/RileyLink-Bridging-Header.h b/RileyLink/RileyLink-Bridging-Header.h index 65b734fcf..7d792deea 100644 --- a/RileyLink/RileyLink-Bridging-Header.h +++ b/RileyLink/RileyLink-Bridging-Header.h @@ -6,3 +6,4 @@ #import "Log.h" #import #import "NSData+Conversion.h" +#import "SWRevealViewController.h" diff --git a/RileyLink/RileyLinkDeviceTableViewCell.swift b/RileyLink/RileyLinkDeviceTableViewCell.swift new file mode 100644 index 000000000..4ceba3ef5 --- /dev/null +++ b/RileyLink/RileyLinkDeviceTableViewCell.swift @@ -0,0 +1,51 @@ +// +// RileyLinkDeviceTableViewCell.swift +// Naterade +// +// Created by Nathan Racklyeft on 8/29/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import CoreBluetooth +import UIKit + +class RileyLinkDeviceTableViewCell: UITableViewCell, IdentifiableClass { + + @IBOutlet weak var connectSwitch: UISwitch! + + @IBOutlet weak var nameLabel: UILabel! + + @IBOutlet weak var signalLabel: UILabel! + + func configureCellWithName(name: String?, signal: Int?, peripheralState: CBPeripheralState?) { + nameLabel.text = name + signalLabel.text = signal != nil ? "\(signal!) dB" : nil + + if let state = peripheralState { + switch state { + case .Connected: + connectSwitch.on = true + connectSwitch.enabled = true + case .Connecting: + connectSwitch.on = true + connectSwitch.enabled = false + case .Disconnected: + connectSwitch.on = false + connectSwitch.enabled = true + case .Disconnecting: + connectSwitch.on = false + connectSwitch.enabled = false + } + } else { + connectSwitch.hidden = true + } + + } + + override func prepareForReuse() { + super.prepareForReuse() + + connectSwitch?.removeTarget(nil, action: nil, forControlEvents: .ValueChanged) + } + +} diff --git a/RileyLink/RileyLinkDeviceViewController.h b/RileyLink/RileyLinkDeviceViewController.h deleted file mode 100644 index 8e5321c9a..000000000 --- a/RileyLink/RileyLinkDeviceViewController.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// RileyLinkViewController.h -// RileyLink -// -// Created by Pete Schwamb on 7/26/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import -#import "RileyLinkBLEDevice.h" -#import "RileyLinkRecord.h" - -@interface RileyLinkDeviceViewController : UIViewController - -@property (nonatomic, strong) RileyLinkBLEDevice *rlDevice; -@property (nonatomic, strong) RileyLinkRecord *rlRecord; -@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext; - -@end diff --git a/RileyLink/RileyLinkDeviceViewController.m b/RileyLink/RileyLinkDeviceViewController.m deleted file mode 100644 index 467e68654..000000000 --- a/RileyLink/RileyLinkDeviceViewController.m +++ /dev/null @@ -1,134 +0,0 @@ -// -// RileyLinkViewController.m -// RileyLink -// -// Created by Pete Schwamb on 7/26/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -@import RileyLinkBLEKit; - -#import "RileyLinkDeviceViewController.h" -#import "PacketLogViewController.h" -#import "PacketGeneratorViewController.h" - -@interface RileyLinkDeviceViewController () { - IBOutlet UILabel *deviceIDLabel; - IBOutlet UITextField *nameView; - IBOutlet UISwitch *autoConnectSwitch; - IBOutlet UIActivityIndicatorView *connectingIndicator; -} - -@end - -@implementation RileyLinkDeviceViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - deviceIDLabel.text = self.rlRecord.peripheralId; - nameView.text = self.rlRecord.name; - - [self.rlRecord addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(deviceDisconnected:) - name:RILEYLINK_EVENT_DEVICE_DISCONNECTED - object:self.rlDevice]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(deviceConnected:) - name:RILEYLINK_EVENT_DEVICE_CONNECTED - object:self.rlDevice]; - - - [self updateNameView]; - autoConnectSwitch.on = (self.rlRecord.autoConnect).boolValue; -} - --(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if (object == self.rlRecord && [keyPath isEqualToString:@"name"]) { - [self updateNameView]; - } else { - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } -} - -- (void)dealloc -{ - [self.rlRecord removeObserver:self forKeyPath:@"name"]; - [[NSNotificationCenter defaultCenter] removeObserver: self]; -} - -- (void)updateNameView { - switch (self.rlDevice.state) { - case RileyLinkStateConnecting: - nameView.backgroundColor = [UIColor clearColor]; - nameView.text = @"Connecting..."; - [connectingIndicator startAnimating]; - break; - case RileyLinkStateConnected: - nameView.backgroundColor = [UIColor greenColor]; - nameView.text = self.rlRecord.name; - [connectingIndicator stopAnimating]; - break; - case RileyLinkStateDisconnected: - default: - nameView.backgroundColor = [UIColor clearColor]; - nameView.text = self.rlRecord.name; - [connectingIndicator stopAnimating]; - break; - } -} - -- (void)deviceDisconnected:(NSNotification*)notification { - [self updateNameView]; -} - -- (void)deviceConnected:(NSNotification*)notification { - [self updateNameView]; -} - - -- (IBAction)autoConnectSwitchToggled:(id)sender { - self.rlRecord.autoConnect = @(autoConnectSwitch.isOn); - - NSError *error; - if (![self.managedObjectContext save:&error]) { - NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); - } - - if (self.rlDevice != nil) { - if (autoConnectSwitch.isOn) { - // TODO: Use KVO on a device property instead - [[RileyLinkBLEManager sharedManager] connectPeripheral:self.rlDevice.peripheral]; - } else { - [[RileyLinkBLEManager sharedManager] disconnectPeripheral:self.rlDevice.peripheral]; - } - } - [self updateNameView]; -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (BOOL)textFieldShouldReturn:(UITextField *)field { - [field resignFirstResponder]; - [self.rlDevice setCustomName:nameView.text]; - self.rlRecord.name = nameView.text; - return YES; -} - - -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - if ([segue.destinationViewController respondsToSelector:@selector(setDevice:)]) { - [segue.destinationViewController performSelector:@selector(setDevice:) withObject:self.rlDevice]; - } -} - -@end diff --git a/RileyLink/RileyLinkDeviceViewController.swift b/RileyLink/RileyLinkDeviceViewController.swift new file mode 100644 index 000000000..bdac23fb5 --- /dev/null +++ b/RileyLink/RileyLinkDeviceViewController.swift @@ -0,0 +1,33 @@ +// +// RileyLinkDeviceViewController.swift +// RileyLink +// +// Created by Pete Schwamb on 5/12/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import UIKit +import RileyLinkKit + +class RileyLinkDeviceViewController: UIViewController { + var device: RileyLinkDevice! + + @IBOutlet var nameView: UITextField? + @IBOutlet var connectingIndicator: UIActivityIndicatorView? + + override func viewDidLoad() { + super.viewDidLoad() + nameView!.text = device.name + } + + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { + switch segue.destinationViewController { + case let vc as PumpChatViewController: + vc.device = device + case let vc as MySentryPairViewController: + vc.device = device + default: + break + } + } +} \ No newline at end of file diff --git a/RileyLink/RileyLinkListTableViewController.h b/RileyLink/RileyLinkListTableViewController.h deleted file mode 100644 index 011ea5fe2..000000000 --- a/RileyLink/RileyLinkListTableViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// RileyLinkListTableViewController.h -// RileyLink -// -// Created by Pete Schwamb on 7/27/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import - -@interface RileyLinkListTableViewController : UITableViewController - -@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext; - -@end diff --git a/RileyLink/RileyLinkListTableViewController.m b/RileyLink/RileyLinkListTableViewController.m deleted file mode 100644 index 2051be628..000000000 --- a/RileyLink/RileyLinkListTableViewController.m +++ /dev/null @@ -1,211 +0,0 @@ -// -// RileyLinkListTableViewController.m -// RileyLink -// -// Created by Pete Schwamb on 7/27/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -@import RileyLinkBLEKit; - -#import "RileyLinkListTableViewController.h" -#import "SWRevealViewController.h" -#import "RileyLinkTableViewCell.h" -#import "RileyLinkDeviceViewController.h" -#import "RileyLink-Swift.h" - -@interface RileyLinkListTableViewController () { - NSMutableArray *rileyLinkRecords; - NSMutableDictionary *recordsById; - NSMutableDictionary *devicesById; - IBOutlet UIBarButtonItem *menuButton; -} - -@end - -@implementation RileyLinkListTableViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; - self.managedObjectContext = appDelegate.managedObjectContext; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(listUpdated:) - name:RILEYLINK_EVENT_LIST_UPDATED - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(listUpdated:) - name:RILEYLINK_EVENT_DEVICE_CONNECTED - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(listUpdated:) - name:RILEYLINK_EVENT_DEVICE_DISCONNECTED - object:nil]; - - if (self.revealViewController != nil) { - menuButton.target = self.revealViewController; - menuButton.action = @selector(revealToggle:); - [self.view addGestureRecognizer: self.revealViewController.panGestureRecognizer]; - } - - [self loadRecordsFromDB]; - [self processVisibleDevices]; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - - [RileyLinkBLEManager sharedManager].scanningEnabled = YES; -} - -- (void)viewWillDisappear:(BOOL)animated -{ - [super viewWillDisappear:animated]; - - [RileyLinkBLEManager sharedManager].scanningEnabled = NO; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver: self]; -} - -- (void)processVisibleDevices { - devicesById = [NSMutableDictionary dictionary]; - - for (RileyLinkBLEDevice *device in [RileyLinkBLEManager sharedManager].rileyLinkList) { - devicesById[device.peripheralId] = device; - - RileyLinkRecord *existingRecord = recordsById[device.peripheralId]; - - if (existingRecord == NULL) { - // Haven't seen this device before; add it to Core Data - RileyLinkRecord *record = [NSEntityDescription - insertNewObjectForEntityForName:@"RileyLinkRecord" - inManagedObjectContext:self.managedObjectContext]; - record.name = device.name; - record.peripheralId = device.peripheralId; - record.firstSeenAt = [NSDate date]; - record.autoConnect = @NO; - recordsById[device.peripheralId] = record; - [rileyLinkRecords addObject: record]; - } else { - // Have seen it; update name - existingRecord.name = device.name; - } - } - NSError *error; - if (![self.managedObjectContext save:&error]) { - NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); - } - [self.tableView reloadData]; -} - -- (void)listUpdated:(NSNotification *)notification { - [self processVisibleDevices]; -} - -- (void)loadRecordsFromDB { - rileyLinkRecords = [NSMutableArray array]; - recordsById = [NSMutableDictionary dictionary]; - - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; - NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"firstSeenAt" ascending:YES]; - fetchRequest.sortDescriptors = @[sortDescriptor1]; - NSEntityDescription *entity = [NSEntityDescription entityForName:@"RileyLinkRecord" - inManagedObjectContext:self.managedObjectContext]; - fetchRequest.entity = entity; - NSError *error; - NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; - for (RileyLinkRecord *record in fetchedObjects) { - NSLog(@"Loaded: %@ from db", record.name); - recordsById[record.peripheralId] = record; - [rileyLinkRecords addObject:record]; - } -} - - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - // Return the number of sections. - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - // Return the number of rows in the section. - return rileyLinkRecords.count; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - RileyLinkTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"rileylink" forIndexPath:indexPath]; - RileyLinkRecord *record = rileyLinkRecords[indexPath.row]; - cell.name = record.name; - cell.autoConnect = (record.autoConnect).boolValue; - - RileyLinkBLEDevice *device = devicesById[record.peripheralId]; - if (device) { - cell.visible = YES; - cell.RSSI = device.RSSI; - } else { - cell.visible = NO; - cell.RSSI = nil; - } - return cell; -} - -/* -// Override to support conditional editing of the table view. -- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - // Return NO if you do not want the specified item to be editable. - return YES; -} -*/ - -/* -// Override to support editing the table view. -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - if (editingStyle == UITableViewCellEditingStyleDelete) { - // Delete the row from the data source - [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; - } else if (editingStyle == UITableViewCellEditingStyleInsert) { - // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view - } -} -*/ - -/* -// Override to support rearranging the table view. -- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { -} -*/ - -/* -// Override to support conditional rearranging of the table view. -- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { - // Return NO if you do not want the item to be re-orderable. - return YES; -} -*/ - -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - RileyLinkDeviceViewController *controller = segue.destinationViewController; - NSIndexPath *ip = (self.tableView).indexPathForSelectedRow; - RileyLinkRecord *record = rileyLinkRecords[ip.row]; - controller.rlRecord = record; - controller.rlDevice = devicesById[record.peripheralId]; - controller.managedObjectContext = self.managedObjectContext; -} - -@end diff --git a/RileyLink/RileyLinkListTableViewController.swift b/RileyLink/RileyLinkListTableViewController.swift new file mode 100644 index 000000000..c52de880e --- /dev/null +++ b/RileyLink/RileyLinkListTableViewController.swift @@ -0,0 +1,168 @@ +// +// RileyLinkListTableViewController.swift +// RileyLink +// +// Created by Pete Schwamb on 5/11/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import UIKit +import RileyLinkKit + +class RileyLinkListTableViewController: UITableViewController { + + // Retreive the managedObjectContext from AppDelegate + let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext + + @IBOutlet var menuButton: UIBarButtonItem? + + override func viewDidLoad() { + super.viewDidLoad() + + if (self.revealViewController != nil) { + menuButton!.target = self.revealViewController + menuButton!.action = #selector(SWRevealViewController.revealToggle) + self.view.addGestureRecognizer(self.revealViewController.panGestureRecognizer) + } + + dataManagerObserver = NSNotificationCenter.defaultCenter().addObserverForName(nil, object: dataManager, queue: nil) { [weak self = self] (note) -> Void in + if let deviceManager = self?.dataManager.rileyLinkManager { + 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) + } + default: + break + } + } + } + } + + deinit { + dataManagerObserver = nil + } + + private var dataManagerObserver: AnyObject? { + willSet { + if let observer = dataManagerObserver { + NSNotificationCenter.defaultCenter().removeObserver(observer) + } + } + } + + private var dataManager: DeviceDataManager { + return DeviceDataManager.sharedManager + } + + override func viewDidAppear(animated: Bool) { + super.viewDidAppear(animated) + + dataManager.rileyLinkManager.deviceScanningEnabled = true + } + + override func viewDidDisappear(animated: Bool) { + super.viewDidDisappear(animated) + + dataManager.rileyLinkManager.deviceScanningEnabled = false + } + + // MARK: Table view data source + + override func numberOfSectionsInTableView(tableView: UITableView) -> Int { + return 1 + } + + override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dataManager.rileyLinkManager.devices.count + } + + override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell: UITableViewCell + + let deviceCell = tableView.dequeueReusableCellWithIdentifier(RileyLinkDeviceTableViewCell.className) as! RileyLinkDeviceTableViewCell + + let device = dataManager.rileyLinkManager.devices[indexPath.row] + + deviceCell.configureCellWithName(device.name, + signal: device.RSSI, + peripheralState: device.peripheral.state + ) + + deviceCell.connectSwitch.addTarget(self, action: #selector(deviceConnectionChanged(_:)), forControlEvents: .ValueChanged) + + cell = deviceCell + return cell + } + + func deviceConnectionChanged(connectSwitch: UISwitch) { + let switchOrigin = connectSwitch.convertPoint(.zero, toView: tableView) + + if let indexPath = tableView.indexPathForRowAtPoint(switchOrigin) + { + let device = dataManager.rileyLinkManager.devices[indexPath.row] + + if connectSwitch.on { + dataManager.connectToRileyLink(device) + } else { + dataManager.disconnectFromRileyLink(device) + } + } + } + + + + /* + // Override to support conditional editing of the table view. + - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; + } + */ + + /* + // Override to support editing the table view. + - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete the row from the data source + [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } + } + */ + + /* + // Override to support rearranging the table view. + - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { + } + */ + + /* + // Override to support conditional rearranging of the table view. + - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; + } + */ + + // MARK: Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { + if let + cell = sender as? UITableViewCell, + indexPath = tableView.indexPathForCell(cell) + { + + switch segue.destinationViewController { + case let vc as RileyLinkDeviceViewController: + vc.device = dataManager.rileyLinkManager.devices[indexPath.row] + default: + break + } + } + } +} \ No newline at end of file diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index f5fc0d9b4..6acc2f0e0 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -1,8 +1,8 @@ - + - + @@ -103,7 +103,7 @@ - + @@ -137,7 +137,7 @@ - + @@ -314,7 +314,7 @@ - + @@ -337,37 +337,49 @@ - + - + - - + + - + + + + + + + + - - - + + + + @@ -395,7 +407,7 @@ - + @@ -404,44 +416,8 @@ - - - - - - - - - - - @@ -469,6 +436,15 @@ + @@ -476,9 +452,7 @@ - - @@ -491,7 +465,7 @@ - + @@ -499,7 +473,7 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -633,22 +577,22 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RileyLinkKit/Extensions/CBPeripheralState.swift b/RileyLinkKit/Extensions/CBPeripheralState.swift new file mode 100644 index 000000000..29c23856d --- /dev/null +++ b/RileyLinkKit/Extensions/CBPeripheralState.swift @@ -0,0 +1,25 @@ +// +// CBPeripheralState.swift +// Naterade +// +// Created by Nathan Racklyeft on 3/5/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import CoreBluetooth + + +extension CBPeripheralState: CustomStringConvertible { + public var description: String { + switch self { + case .Connected: + return NSLocalizedString("Connected", comment: "The connected state") + case .Connecting: + return NSLocalizedString("Connecting", comment: "The in-progress connecting state") + case .Disconnected: + return NSLocalizedString("Disconnected", comment: "The disconnected state") + case .Disconnecting: + return NSLocalizedString("Disconnecting", comment: "The in-progress disconnecting state") + } + } +} \ No newline at end of file diff --git a/RileyLink/IdentifiableClass.swift b/RileyLinkKit/Extensions/IdentifiableClass.swift similarity index 100% rename from RileyLink/IdentifiableClass.swift rename to RileyLinkKit/Extensions/IdentifiableClass.swift diff --git a/RileyLinkKit/Extensions/NSDate.swift b/RileyLinkKit/Extensions/NSDate.swift new file mode 100644 index 000000000..de02cc3b7 --- /dev/null +++ b/RileyLinkKit/Extensions/NSDate.swift @@ -0,0 +1,20 @@ +// +// NSDate.swift +// RileyLink +// +// Created by Pete Schwamb on 5/18/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation + + +public func ==(lhs: NSDate, rhs: NSDate) -> Bool { + return lhs === rhs || lhs.compare(rhs) == .OrderedSame +} + +public func <(lhs: NSDate, rhs: NSDate) -> Bool { + return lhs.compare(rhs) == .OrderedAscending +} + +extension NSDate: Comparable { } \ No newline at end of file diff --git a/RileyLinkKit/RileyLinkDeviceManager.swift b/RileyLinkKit/RileyLinkDeviceManager.swift index 7ad51b2a5..d5cb53d61 100644 --- a/RileyLinkKit/RileyLinkDeviceManager.swift +++ b/RileyLinkKit/RileyLinkDeviceManager.swift @@ -105,6 +105,10 @@ public class RileyLinkDeviceManager { let device = _devices[index] NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.ConnectionStateDidChangeNotification, object: self, userInfo: [self.dynamicType.RileyLinkDeviceKey: device]) + + if device.peripheral.state == CBPeripheralState.Connected { + + } } } diff --git a/RileyLinkKit/ViewControllers/CommandResponseViewController.swift b/RileyLinkKit/ViewControllers/CommandResponseViewController.swift new file mode 100644 index 000000000..f0a1b4e59 --- /dev/null +++ b/RileyLinkKit/ViewControllers/CommandResponseViewController.swift @@ -0,0 +1,41 @@ +// +// 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/RileyLink/MySentryPairViewController.swift b/RileyLinkKit/ViewControllers/MySentryPairViewController.swift similarity index 98% rename from RileyLink/MySentryPairViewController.swift rename to RileyLinkKit/ViewControllers/MySentryPairViewController.swift index 72d1014ad..8ef4ada93 100644 --- a/RileyLink/MySentryPairViewController.swift +++ b/RileyLinkKit/ViewControllers/MySentryPairViewController.swift @@ -8,10 +8,8 @@ import UIKit import MinimedKit -import RileyLinkKit import RileyLinkBLEKit - class MySentryPairViewController: UIViewController, UITextFieldDelegate { enum PairingState { @@ -179,7 +177,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { if let data = packet.data, msg = PumpMessage(rxData: data) { if msg.packetType == PacketType.MySentry && - msg.address.hexadecimalString == Config.sharedInstance().pumpID { + msg.address.hexadecimalString == device.pumpState!.pumpID { switch (msg.messageType) { case MessageType.FindDevice: handleFindDevice(msg.messageBody as! FindDeviceMessageBody) @@ -204,7 +202,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { func makeCommandForAckAndListen(sequence: UInt8, messageType: MessageType) -> ReceivingPacketCmd { let replyString = String(format: "%02x%@%02x%02x%@00%02x000000", PacketType.MySentry.rawValue, - Config.sharedInstance().pumpID!, + device.pumpState!.pumpID, MessageType.PumpAck.rawValue, sequence, self.deviceIDTextField.text!, diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift new file mode 100644 index 000000000..56e24ff4d --- /dev/null +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -0,0 +1,286 @@ +// +// RileyLinkDeviceTableViewController.swift +// Naterade +// +// Created by Nathan Racklyeft on 3/5/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit +import MinimedKit + +public class RileyLinkDeviceTableViewController: UITableViewController { + + public var device: RileyLinkDevice! + + private var appeared = false + + public override func viewDidLoad() { + super.viewDidLoad() + + title = device.name + } + + public override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + + if appeared { + tableView.reloadData() + } + + appeared = true + } + + // MARK: - Formatters + + private lazy var dateFormatter: NSDateFormatter = { + let dateFormatter = NSDateFormatter() + + dateFormatter.dateStyle = .MediumStyle + dateFormatter.timeStyle = .MediumStyle + + return dateFormatter + }() + + private lazy var decimalFormatter: NSNumberFormatter = { + let decimalFormatter = NSNumberFormatter() + + decimalFormatter.numberStyle = .DecimalStyle + decimalFormatter.minimumFractionDigits = 2 + decimalFormatter.maximumFractionDigits = 2 + + return decimalFormatter + }() + + // MARK: - Table view data source + + private enum Section: Int { + case Device + case Pump + case Commands + + static let count = 3 + } + + private enum DeviceRow: Int { + case RSSI + case Connection + case IdleStatus + + static let count = 3 + } + + private enum PumpRow: Int { + case ID + case Awake + + static let count = 2 + } + + private enum CommandRow: Int { + case Tune + case ChangeTime + case MySentryPair + + static let count = 3 + } + + public override func numberOfSectionsInTableView(tableView: UITableView) -> Int { + if device.pumpState == nil { + return Section.count - 1 + } else { + return Section.count + } + } + + public override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section(rawValue: section)! { + case .Device: + return DeviceRow.count + case .Pump: + return PumpRow.count + case .Commands: + return CommandRow.count + } + } + + public override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) + + cell.accessoryType = .None + + switch Section(rawValue: indexPath.section)! { + case .Device: + switch DeviceRow(rawValue: indexPath.row)! { + case .Connection: + cell.textLabel?.text = NSLocalizedString("Connection State", comment: "The title of the cell showing connection state") + cell.detailTextLabel?.text = device.peripheral.state.description + case .RSSI: + cell.textLabel?.text = NSLocalizedString("Signal strength", comment: "The title of the cell showing signal strength (RSSI)") + if let RSSI = device.RSSI { + cell.detailTextLabel?.text = "\(RSSI) dB" + } else { + cell.detailTextLabel?.text = "–" + } + case .IdleStatus: + cell.textLabel?.text = NSLocalizedString("On Idle", comment: "The title of the cell showing the last idle") + + if let idleDate = device.lastIdle { + cell.detailTextLabel?.text = dateFormatter.stringFromDate(idleDate) + } else { + cell.detailTextLabel?.text = "–" + } + } + case .Pump: + switch PumpRow(rawValue: indexPath.row)! { + case .ID: + cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title of the cell showing pump ID") + if let pumpID = device.pumpState?.pumpID { + cell.detailTextLabel?.text = pumpID + } else { + cell.detailTextLabel?.text = "–" + } + case .Awake: + switch device.pumpState?.awakeUntil { + case let until? where until < NSDate(): + cell.textLabel?.text = NSLocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") + cell.detailTextLabel?.text = dateFormatter.stringFromDate(until) + case let until?: + cell.textLabel?.text = NSLocalizedString("Awake Until", comment: "The title of the cell describing an awake radio") + cell.detailTextLabel?.text = dateFormatter.stringFromDate(until) + default: + cell.textLabel?.text = NSLocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data") + cell.detailTextLabel?.text = nil + } + } + case .Commands: + switch CommandRow(rawValue: indexPath.row)! { + case .Tune: + switch (device.radioFrequency, device.lastTuned) { + case (let frequency?, let date?): + cell.textLabel?.text = "\(decimalFormatter.stringFromNumber(frequency)!) MHz" + cell.detailTextLabel?.text = dateFormatter.stringFromDate(date) + default: + cell.textLabel?.text = NSLocalizedString("Tune radio frequency", comment: "The title of the cell describing the command to re-tune the radio") + cell.detailTextLabel?.text = nil + } + cell.accessoryType = .DisclosureIndicator + case .ChangeTime: + cell.textLabel?.text = "Change Time" + cell.accessoryType = .DisclosureIndicator + + let localTimeZone = NSTimeZone.defaultTimeZone() + let localTimeZoneName = localTimeZone.abbreviation ?? localTimeZone.name + + if let pumpTimeZone = device.pumpState?.timeZone { + let timeZoneDiff = NSTimeInterval(pumpTimeZone.secondsFromGMT - localTimeZone.secondsFromGMT) + let formatter = NSDateComponentsFormatter() + formatter.allowedUnits = [.Hour, .Minute] + let diffString = timeZoneDiff != 0 ? formatter.stringFromTimeInterval(abs(timeZoneDiff)) ?? String(abs(timeZoneDiff)) : "" + + cell.detailTextLabel?.text = String(format: NSLocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) + } else { + cell.detailTextLabel?.text = localTimeZoneName + } + case .MySentryPair: + cell.textLabel?.text = "MySentry Pair" + cell.detailTextLabel?.text = nil + cell.accessoryType = .DisclosureIndicator + } + } + + return cell + } + + public override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section(rawValue: section)! { + case .Device: + return NSLocalizedString("Bluetooth", comment: "The title of the section describing the device") + case .Pump: + return NSLocalizedString("Pump", comment: "The title of the section describing the pump") + case .Commands: + return NSLocalizedString("Commands", comment: "The title of the section describing commands") + } + } + + // MARK: - UITableViewDelegate + + public override func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool { + switch Section(rawValue: indexPath.section)! { + case .Device, .Pump: + return false + case .Commands: + return true + } + } + + public override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + switch Section(rawValue: indexPath.section)! { + case .Commands: + switch CommandRow(rawValue: indexPath.row)! { + case .Tune: + let vc = CommandResponseViewController(command: { [unowned self] (completionHandler) -> String in + self.device.tunePumpWithResultHandler({ (response) -> Void in + switch response { + case .Success(let scanResult): + var resultDict: [String: AnyObject] = [:] + let decimalFormatter = NSNumberFormatter() + decimalFormatter.minimumSignificantDigits = 5 + + resultDict["Best Frequency"] = scanResult.bestFrequency + resultDict["Trials"] = scanResult.trials.map({ (trial) -> String in + return "\(decimalFormatter.stringFromNumber(trial.frequencyMHz)!) MHz \(trial.successes)/\(trial.tries) \(trial.avgRSSI)" + }) + + var responseText: String + + if let data = try? NSJSONSerialization.dataWithJSONObject(resultDict, options: .PrettyPrinted), string = String(data: data, encoding: NSUTF8StringEncoding) { + responseText = string + } else { + responseText = "No response" + } + + completionHandler(responseText: responseText) + case .Failure(let error): + completionHandler(responseText: String(error)) + } + }) + + return "Tuning radio..." + }) + + vc.title = "Tune device radio" + + self.showViewController(vc, sender: indexPath) + case .ChangeTime: + let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in + self.device.syncPumpTime { (error) -> Void in + dispatch_async(dispatch_get_main_queue()) { + if let error = error { + completionHandler(responseText: "Failed: \(error)") + } else { + completionHandler(responseText: "Succeeded") + } + } + } + + return "Changing time..." + } + + vc.title = "Change Time" + + self.showViewController(vc, sender: indexPath) + case .MySentryPair: + let vc = self.storyboard!.instantiateViewControllerWithIdentifier("mySentryPair") as! MySentryPairViewController + + vc.device = device + + vc.title = "MySentry Pair" + + self.showViewController(vc, sender: indexPath) + } + case .Device, .Pump: + break + } + } +} From 30632e598be33e277d59e6e850062916efb6e523 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 18 May 2016 13:15:11 -0500 Subject: [PATCH 17/40] unused code --- RileyLinkKit/RileyLinkDeviceManager.swift | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/RileyLinkKit/RileyLinkDeviceManager.swift b/RileyLinkKit/RileyLinkDeviceManager.swift index d5cb53d61..469b29519 100644 --- a/RileyLinkKit/RileyLinkDeviceManager.swift +++ b/RileyLinkKit/RileyLinkDeviceManager.swift @@ -104,11 +104,7 @@ public class RileyLinkDeviceManager { index = _devices.indexOf({ $0.peripheral == BLEDevice.peripheral }) { let device = _devices[index] - NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.ConnectionStateDidChangeNotification, object: self, userInfo: [self.dynamicType.RileyLinkDeviceKey: device]) - - if device.peripheral.state == CBPeripheralState.Connected { - - } + NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.ConnectionStateDidChangeNotification, object: self, userInfo: [self.dynamicType.RileyLinkDeviceKey: device]) } } From 2372eb2130cce835543d73ceeb9c46bd792e5cd6 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 18 May 2016 14:01:49 -0500 Subject: [PATCH 18/40] Adding history, model, and press button commands --- RileyLink.xcodeproj/project.pbxproj | 4 - RileyLink/PumpChatViewController.swift | 95 ---------------- RileyLink/Storyboard.storyboard | 104 ------------------ RileyLinkKit/PumpOps.swift | 43 +++++--- .../RileyLinkDeviceTableViewController.swift | 69 +++++++++++- 5 files changed, 97 insertions(+), 218 deletions(-) delete mode 100644 RileyLink/PumpChatViewController.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index af55e5756..48372ac46 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -173,7 +173,6 @@ C1842C231C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BF91C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift */; }; C1842C241C8FA45100DB42AC /* BatteryPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFA1C8FA45100DB42AC /* BatteryPumpEvent.swift */; }; C1842C251C8FA45100DB42AC /* AlarmSensorPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFB1C8FA45100DB42AC /* AlarmSensorPumpEvent.swift */; }; - C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */; }; C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = C1AA39931AB6804000BC9E33 /* UIAlertView+Blocks.m */; }; C1AACC6B1CECD5F500C07049 /* RileyLinkListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1AACC6A1CECD5F500C07049 /* RileyLinkListTableViewController.swift */; }; C1AACC6C1CECD63500C07049 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */; }; @@ -509,7 +508,6 @@ C1842C2E1C90F6D900DB42AC /* NightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutTreatment.swift; sourceTree = ""; }; C1842C301C91D56400DB42AC /* BGCheckNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BGCheckNightscoutTreatment.swift; sourceTree = ""; }; C1842C321C91DAFA00DB42AC /* MealBolusNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MealBolusNightscoutTreatment.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpChatViewController.swift; sourceTree = ""; }; C19F94AA1C91DF6E00018F7D /* BolusNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusNightscoutTreatment.swift; sourceTree = ""; }; C1AA39921AB6804000BC9E33 /* UIAlertView+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+Blocks.h"; sourceTree = ""; }; C1AA39931AB6804000BC9E33 /* UIAlertView+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Blocks.m"; sourceTree = ""; }; @@ -1120,7 +1118,6 @@ C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */, C12616551B6A6130001FAD87 /* PacketLogViewController.h */, C12616561B6A6130001FAD87 /* PacketLogViewController.m */, - C1890B5E1C94B9D9005F7474 /* PumpChatViewController.swift */, C1AACC6A1CECD5F500C07049 /* RileyLinkListTableViewController.swift */, ); name = ViewControllers; @@ -1711,7 +1708,6 @@ C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, - C1890B5F1C94B9D9005F7474 /* PumpChatViewController.swift in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, C126165D1B6C8076001FAD87 /* PacketGeneratorViewController.m in Sources */, diff --git a/RileyLink/PumpChatViewController.swift b/RileyLink/PumpChatViewController.swift deleted file mode 100644 index f177f5996..000000000 --- a/RileyLink/PumpChatViewController.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// PumpChatViewController.swift -// RileyLink -// -// Created by Pete Schwamb on 3/12/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -import UIKit -import MinimedKit -import RileyLinkKit -import RileyLinkBLEKit - - -class PumpChatViewController: UIViewController { - - @IBOutlet var output: UITextView! - @IBOutlet var batteryVoltage: UILabel! - @IBOutlet var pumpIdLabel: UILabel! - - var device: RileyLinkDevice! - - override func viewDidLoad() { - super.viewDidLoad() - - pumpIdLabel.text = "PumpID: \(Config.sharedInstance().pumpID ?? "nil")" - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - func addOutputMessage(msg: String) - { - output.text = output.text.stringByAppendingFormat("%@\n", msg) - NSLog("addOutputMessage: %@", msg) - } - - @IBAction func dumpHistoryButtonPressed(sender: UIButton) { - let calendar = NSCalendar.currentCalendar() - let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) - device.ops?.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in - switch response { - case .Success(let (events, _)): - self.addOutputMessage(String(format:"Found %d events since %@", events.count, oneDayAgo!)) - for event in events { - self.addOutputMessage(String(format:"Event: %@", event.dictionaryRepresentation)) - NSLog("Event: %@", event.dictionaryRepresentation) - } - case .Failure(let error): - let errorMsg = String(format:"History fetch failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } - } - } - - @IBAction func pressDownButtonPressed(sender: UIButton) { - device.ops?.pressButton() - } - - @IBAction func queryPumpButtonPressed(sender: UIButton) { - device.ops?.getPumpModel { (model) -> Void in - if let model = model { - self.addOutputMessage(String(format:"Pump Model: %@", model)) - } else { - self.addOutputMessage("Get pump model failed.") - } - } - - device.ops!.getBatteryVoltage { (results) -> Void in - if let results = results { - self.addOutputMessage(String(format:"Battery Level: %@, %0.02f volts", results.status, results.volts)) - } else { - self.addOutputMessage("Get battery voltage failed.") - } - } - } - - - @IBAction func tuneButtonPressed(sender: UIButton) { - device.ops?.tunePump { (result) -> Void in - switch result { - case .Success(let scanResults): - for trial in scanResults.trials { - self.addOutputMessage(String(format:"Trial: %0.02f - %d, %0.01f", trial.frequencyMHz, trial.successes, trial.avgRSSI)) - } - self.addOutputMessage(String(format:"Best Freq: %0.02f", scanResults.bestFrequency)) - case .Failure(let error): - let errorMsg = String(format:"Tune failed: %@", String(error)) - self.addOutputMessage(errorMsg) - } - } - } -} diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 493fc7d5b..9ddecc4db 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -657,110 +657,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index a0b64f433..8903f7e9e 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -21,35 +21,50 @@ public class PumpOps { self.device = device } - public func pressButton() { + public func pressButton(completion: (Either) -> Void) { device.runSession { (session) -> Void in let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) let message = PumpMessage(packetType: .Carelink, address: self.pumpState.pumpID, messageType: .ButtonPress, messageBody: ButtonPressCarelinkMessageBody(buttonType: .Down)) do { try ops.runCommandWithArguments(message) - } catch { } + completion(.Success("Success.")) + } catch let error { + dispatch_async(dispatch_get_main_queue(), { () -> Void in + completion(.Failure(error)) + }) + } } } - public func getPumpModel(completion: (String?) -> Void) { + public func getPumpModel(completion: (Either) -> Void) { device.runSession { (session) -> Void in let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) - let model = try? ops.getPumpModelNumber() - - dispatch_async(dispatch_get_main_queue(), { () -> Void in - completion(model) - }) + do { + let model = try ops.getPumpModelNumber() + dispatch_async(dispatch_get_main_queue(), { () -> Void in + completion(.Success(model)) + }) + } catch let error { + dispatch_async(dispatch_get_main_queue(), { () -> Void in + completion(.Failure(error)) + }) + } } } - public func getBatteryVoltage(completion: (GetBatteryCarelinkMessageBody?) -> Void) { + public func getBatteryVoltage(completion: (Either) -> Void) { device.runSession { (session) -> Void in let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) - let response: GetBatteryCarelinkMessageBody? = try? ops.getMessageBodyWithType(.GetBattery) - - dispatch_async(dispatch_get_main_queue(), { () -> Void in - completion(response) - }) + do { + let response: GetBatteryCarelinkMessageBody = try ops.getMessageBodyWithType(.GetBattery) + dispatch_async(dispatch_get_main_queue(), { () -> Void in + completion(.Success(response)) + }) + } catch let error { + dispatch_async(dispatch_get_main_queue(), { () -> Void in + completion(.Failure(error)) + }) + } } } diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift index 56e24ff4d..fca9f1593 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -81,8 +81,11 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case Tune case ChangeTime case MySentryPair + case DumpHistory + case GetPumpModel + case PressDownButton - static let count = 3 + static let count = 6 } public override func numberOfSectionsInTableView(tableView: UITableView) -> Int { @@ -186,6 +189,18 @@ public class RileyLinkDeviceTableViewController: UITableViewController { cell.textLabel?.text = "MySentry Pair" cell.detailTextLabel?.text = nil cell.accessoryType = .DisclosureIndicator + case .DumpHistory: + cell.textLabel?.text = "Fetch Recent History" + cell.detailTextLabel?.text = nil + cell.accessoryType = .DisclosureIndicator + case .GetPumpModel: + cell.textLabel?.text = "Get Pump Model" + cell.detailTextLabel?.text = nil + cell.accessoryType = .DisclosureIndicator + case .PressDownButton: + cell.textLabel?.text = "Send Button Press" + cell.detailTextLabel?.text = nil + cell.accessoryType = .DisclosureIndicator } } @@ -277,6 +292,58 @@ public class RileyLinkDeviceTableViewController: UITableViewController { vc.title = "MySentry Pair" + self.showViewController(vc, sender: indexPath) + case .DumpHistory: + let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in + let calendar = NSCalendar.currentCalendar() + let oneDayAgo = calendar.dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: []) + self.device.ops?.getHistoryEventsSinceDate(oneDayAgo!) { (response) -> Void in + switch response { + case .Success(let (events, _)): + var responseText = String(format:"Found %d events since %@", events.count, oneDayAgo!) + for event in events { + responseText += String(format:"\nEvent: %@", event.dictionaryRepresentation) + } + completionHandler(responseText: responseText) + case .Failure(let error): + completionHandler(responseText: String(error)) + } + } + return "Fetching history..." + } + + vc.title = "Fetch History" + + self.showViewController(vc, sender: indexPath) + case .GetPumpModel: + let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in + self.device.ops?.getPumpModel({ (response) in + switch response { + case .Success(let model): + completionHandler(responseText: "Pump Model: " + model) + case .Failure(let error): + completionHandler(responseText: String(error)) + } + }) + return "Fetching pump model..." + } + vc.title = "Fetch Pump Model" + + self.showViewController(vc, sender: indexPath) + case .PressDownButton: + let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in + self.device.ops?.pressButton({ (response) in + switch response { + case .Success(let msg): + completionHandler(responseText: "Result: " + msg) + case .Failure(let error): + completionHandler(responseText: String(error)) + } + }) + return "Sending button press..." + } + vc.title = "Button Press" + self.showViewController(vc, sender: indexPath) } case .Device, .Pump: From ab4fb9443b7a690f35d7f5c9e2f1b4d28026a2a2 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 20 May 2016 13:00:34 -0500 Subject: [PATCH 19/40] NSLocalizedString and fix optional unwrapping --- RileyLinkKit/Extensions/NSDate.swift | 1 - .../MySentryPairViewController.swift | 2 +- .../RileyLinkDeviceTableViewController.swift | 30 +++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/RileyLinkKit/Extensions/NSDate.swift b/RileyLinkKit/Extensions/NSDate.swift index de02cc3b7..4e94e1dd4 100644 --- a/RileyLinkKit/Extensions/NSDate.swift +++ b/RileyLinkKit/Extensions/NSDate.swift @@ -8,7 +8,6 @@ import Foundation - public func ==(lhs: NSDate, rhs: NSDate) -> Bool { return lhs === rhs || lhs.compare(rhs) == .OrderedSame } diff --git a/RileyLinkKit/ViewControllers/MySentryPairViewController.swift b/RileyLinkKit/ViewControllers/MySentryPairViewController.swift index 8ef4ada93..03a4d8e24 100644 --- a/RileyLinkKit/ViewControllers/MySentryPairViewController.swift +++ b/RileyLinkKit/ViewControllers/MySentryPairViewController.swift @@ -177,7 +177,7 @@ class MySentryPairViewController: UIViewController, UITextFieldDelegate { if let data = packet.data, msg = PumpMessage(rxData: data) { if msg.packetType == PacketType.MySentry && - msg.address.hexadecimalString == device.pumpState!.pumpID { + msg.address.hexadecimalString == device.pumpState?.pumpID { switch (msg.messageType) { case MessageType.FindDevice: handleFindDevice(msg.messageBody as! FindDeviceMessageBody) diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift index fca9f1593..a5c9faee7 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -186,19 +186,19 @@ public class RileyLinkDeviceTableViewController: UITableViewController { cell.detailTextLabel?.text = localTimeZoneName } case .MySentryPair: - cell.textLabel?.text = "MySentry Pair" + cell.textLabel?.text = NSLocalizedString("MySentry Pair", comment: "The title of the command to pair with mysentry") cell.detailTextLabel?.text = nil cell.accessoryType = .DisclosureIndicator case .DumpHistory: - cell.textLabel?.text = "Fetch Recent History" + cell.textLabel?.text = NSLocalizedString("Fetch Recent History", comment: "The title of the command to fetch recent history") cell.detailTextLabel?.text = nil cell.accessoryType = .DisclosureIndicator case .GetPumpModel: - cell.textLabel?.text = "Get Pump Model" + cell.textLabel?.text = NSLocalizedString("Get Pump Model", comment: "The title of the command to get pump model") cell.detailTextLabel?.text = nil cell.accessoryType = .DisclosureIndicator case .PressDownButton: - cell.textLabel?.text = "Send Button Press" + cell.textLabel?.text = NSLocalizedString("Send Button Press", comment: "The title of the command to send a button press") cell.detailTextLabel?.text = nil cell.accessoryType = .DisclosureIndicator } @@ -252,7 +252,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { if let data = try? NSJSONSerialization.dataWithJSONObject(resultDict, options: .PrettyPrinted), string = String(data: data, encoding: NSUTF8StringEncoding) { responseText = string } else { - responseText = "No response" + responseText = NSLocalizedString("No response", comment: "Message display when no response from tuning pump") } completionHandler(responseText: responseText) @@ -261,7 +261,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } }) - return "Tuning radio..." + return NSLocalizedString("Tuning radio...", comment: "Progress message for tuning radio") }) vc.title = "Tune device radio" @@ -279,10 +279,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } } - return "Changing time..." + return NSLocalizedString("Changing time...", comment: "Progress message for changing pump time.") } - vc.title = "Change Time" + vc.title = NSLocalizedString("Change Time", comment: "Title of screen for changing pump time.") self.showViewController(vc, sender: indexPath) case .MySentryPair: @@ -290,7 +290,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { vc.device = device - vc.title = "MySentry Pair" + vc.title = NSLocalizedString("MySentry Pair", comment: "Title of screen for pairing with MySentry.") self.showViewController(vc, sender: indexPath) case .DumpHistory: @@ -309,10 +309,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { completionHandler(responseText: String(error)) } } - return "Fetching history..." + return NSLocalizedString("Fetching history...", comment: "Progress message for fetching pump history.") } - vc.title = "Fetch History" + vc.title = NSLocalizedString("Fetch History", comment: "Title of screen for fetching history.") self.showViewController(vc, sender: indexPath) case .GetPumpModel: @@ -325,9 +325,9 @@ public class RileyLinkDeviceTableViewController: UITableViewController { completionHandler(responseText: String(error)) } }) - return "Fetching pump model..." + return NSLocalizedString("Fetching pump model...", comment: "Progress message for fetching pump model.") } - vc.title = "Fetch Pump Model" + vc.title = NSLocalizedString("Fetch Pump Model", comment: "Title of screen for fetching pump model.") self.showViewController(vc, sender: indexPath) case .PressDownButton: @@ -340,9 +340,9 @@ public class RileyLinkDeviceTableViewController: UITableViewController { completionHandler(responseText: String(error)) } }) - return "Sending button press..." + return NSLocalizedString("Sending button press...", comment: "Progress message for sending button press to pump.") } - vc.title = "Button Press" + vc.title = NSLocalizedString("Button Press", comment: "Title of screen for sending button press to pump.") self.showViewController(vc, sender: indexPath) } From 1d8e24204cd2f79e3aa82ffdd650bec3e15ab751 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 20 May 2016 17:50:22 -0500 Subject: [PATCH 20/40] Use className for identifying controller in storyboard --- RileyLink/Storyboard.storyboard | 14 +++++++------- .../MySentryPairViewController.swift | 2 +- .../RileyLinkDeviceTableViewController.swift | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 9ddecc4db..078a01b1f 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -347,7 +347,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - diff --git a/RileyLink/SwitchTableViewCell.swift b/RileyLink/SwitchTableViewCell.swift new file mode 100644 index 000000000..9dafc2308 --- /dev/null +++ b/RileyLink/SwitchTableViewCell.swift @@ -0,0 +1,23 @@ +// +// SwitchTableViewCell.swift +// Naterade +// +// Created by Nathan Racklyeft on 3/13/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit + +class SwitchTableViewCell: UITableViewCell, IdentifiableClass { + + @IBOutlet weak var titleLabel: UILabel! + + @IBOutlet var `switch`: UISwitch? + + override func prepareForReuse() { + super.prepareForReuse() + + `switch`?.removeTarget(nil, action: nil, forControlEvents: .ValueChanged) + } + +} diff --git a/RileyLink/TextFieldTableViewController.swift b/RileyLink/TextFieldTableViewController.swift new file mode 100644 index 000000000..4f129d221 --- /dev/null +++ b/RileyLink/TextFieldTableViewController.swift @@ -0,0 +1,65 @@ +// +// TextFieldTableViewController.swift +// Naterade +// +// Created by Nathan Racklyeft on 8/30/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import UIKit + +protocol TextFieldTableViewControllerDelegate: class { + func textFieldTableViewControllerDidEndEditing(controller: TextFieldTableViewController) +} + + +class TextFieldTableViewController: UITableViewController, IdentifiableClass, UITextFieldDelegate { + + @IBOutlet weak var textField: UITextField! + + var indexPath: NSIndexPath? + + var placeholder: String? + + var value: String? { + didSet { + delegate?.textFieldTableViewControllerDidEndEditing(self) + } + } + + var keyboardType = UIKeyboardType.Default + + weak var delegate: TextFieldTableViewControllerDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + + textField.text = value + textField.keyboardType = keyboardType + textField.placeholder = placeholder + } + + override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + + textField.becomeFirstResponder() + } + + // MARK: - UITextFieldDelegate + + func textFieldShouldEndEditing(textField: UITextField) -> Bool { + value = textField.text + + return true + } + + func textFieldShouldReturn(textField: UITextField) -> Bool { + value = textField.text + + textField.delegate = nil + + navigationController?.popViewControllerAnimated(true) + + return false + } +} diff --git a/log_processing/readlog.rb b/log_processing/readlog.rb deleted file mode 100755 index 6cabc87b3..000000000 --- a/log_processing/readlog.rb +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env ruby - -require 'open-uri' -require 'json' - -if ARGV.count < 2 - puts "Usage: readlog.rb " - exit -1 -end - -entries = JSON.parse(open("#{ARGV[0]}/api/v1/entries.json?find[type]=logs&count=#{ARGV[1]}").read) - -entries = entries.sort_by {|e| e["dateString"]} - -#puts entries.map {|e| e["dateString"]}.inspect - -entries.each do |e| - e["entries"].each do |line| - puts line - end -end From 30fe719e34ffa6ff93969b93f138af1348ed1723 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 20 May 2016 23:11:21 -0500 Subject: [PATCH 23/40] Remove unused file --- RileyLink.xcodeproj/project.pbxproj | 6 -- RileyLink/ConfigureViewController.h | 15 ----- RileyLink/ConfigureViewController.m | 97 ----------------------------- 3 files changed, 118 deletions(-) delete mode 100644 RileyLink/ConfigureViewController.h delete mode 100644 RileyLink/ConfigureViewController.m diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 3bfaf9af7..f01d2f777 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -223,7 +223,6 @@ 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 */; }; - C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */; }; C1EF58881B3F93FE001C8C80 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF58871B3F93FE001C8C80 /* Config.m */; }; /* End PBXBuildFile section */ @@ -549,8 +548,6 @@ 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 = ""; }; - C1EF58831B3E5DA4001C8C80 /* ConfigureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureViewController.h; sourceTree = ""; }; - C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureViewController.m; sourceTree = ""; }; C1EF58861B3F93FE001C8C80 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; C1EF58871B3F93FE001C8C80 /* Config.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Config.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1086,8 +1083,6 @@ children = ( C16843721CF009E600D53CCD /* SettingsTableViewController.swift */, C16843731CF009E600D53CCD /* TextFieldTableViewController.swift */, - C1EF58831B3E5DA4001C8C80 /* ConfigureViewController.h */, - C1EF58841B3E5DA4001C8C80 /* ConfigureViewController.m */, C126165B1B6C8076001FAD87 /* PacketGeneratorViewController.h */, C126165C1B6C8076001FAD87 /* PacketGeneratorViewController.m */, C12616551B6A6130001FAD87 /* PacketLogViewController.h */, @@ -1673,7 +1668,6 @@ C16843751CF009E600D53CCD /* TextFieldTableViewController.swift in Sources */, C12616681B76E8DC001FAD87 /* TPKeyboardAvoidingScrollView.m in Sources */, C139AC241BFD84B500B0518F /* RuntimeUtils.m in Sources */, - C1EF58851B3E5DA4001C8C80 /* ConfigureViewController.m in Sources */, C12616541B6892DB001FAD87 /* RileyLinkRecord.m in Sources */, C12616671B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m in Sources */, C16843791CF0108B00D53CCD /* IdentifiableClass.swift in Sources */, diff --git a/RileyLink/ConfigureViewController.h b/RileyLink/ConfigureViewController.h deleted file mode 100644 index 60babd929..000000000 --- a/RileyLink/ConfigureViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// ConfigureViewController.h -// RileyLink -// -// Created by Pete Schwamb on 6/26/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import - -@interface ConfigureViewController : UIViewController - -- (void)doInitialConfiguration; - -@end diff --git a/RileyLink/ConfigureViewController.m b/RileyLink/ConfigureViewController.m deleted file mode 100644 index 06f61b2f9..000000000 --- a/RileyLink/ConfigureViewController.m +++ /dev/null @@ -1,97 +0,0 @@ -// -// ConfigureViewController.m -// RileyLink -// -// Created by Pete Schwamb on 6/26/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -#import "ConfigureViewController.h" -#import "Config.h" -#import "UIAlertView+Blocks.h" - -@interface ConfigureViewController () { - - IBOutlet UITextField *nightscoutURL; - IBOutlet UITextField *nightscoutAPISecret; - IBOutlet UITextField *pumpId; - IBOutlet UIBarButtonItem *menuButton; - BOOL initialConfig; - IBOutlet UIButton *continueButton; -} - -@end - -@implementation ConfigureViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - if (initialConfig && self.navigationItem != NULL) { - self.navigationItem.leftBarButtonItem = NULL; - } else { - [continueButton setHidden:YES]; - } -} - -- (IBAction)continuePressed:(id)sender { - if ([self validateValues]) { - // TODO: next step would be to connect rileylink - [self.navigationController popToRootViewControllerAnimated:YES]; - } else { - [UIAlertView showWithTitle:@"Invalid Configuration" - message:@"Please set valid values for Nightscout URL and Nightscout API Secret." - cancelButtonTitle:@"OK" - otherButtonTitles:nil - tapBlock:nil]; - - } -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (void)doInitialConfiguration { - initialConfig = YES; -} - -#pragma mark - Navigation - -// In a storyboard-based application, you will often want to do a little preparation before navigation -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - // Get the new view controller using [segue destinationViewController]. - // Pass the selected object to the new view controller. - -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - [self saveValues]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self loadValues]; -} - -- (void) loadValues { - nightscoutURL.text = [Config sharedInstance].nightscoutURL; - nightscoutAPISecret.text = [Config sharedInstance].nightscoutAPISecret; - pumpId.text = [Config sharedInstance].pumpID; -} - -- (void) saveValues { - [Config sharedInstance].nightscoutURL = nightscoutURL.text; - [Config sharedInstance].nightscoutAPISecret = nightscoutAPISecret.text; - [Config sharedInstance].pumpID = pumpId.text; - - -} - -- (BOOL) validateValues { - return ![nightscoutURL.text isEqualToString:@""] && ![nightscoutAPISecret.text isEqualToString:@""]; -} - -@end From ab833116586842753b6d7c8a8bad37a93c04a6bb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Fri, 20 May 2016 23:24:13 -0500 Subject: [PATCH 24/40] reduce visibility of extension --- RileyLinkKit/Extensions/NSDate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RileyLinkKit/Extensions/NSDate.swift b/RileyLinkKit/Extensions/NSDate.swift index 4e94e1dd4..6f8fec0f8 100644 --- a/RileyLinkKit/Extensions/NSDate.swift +++ b/RileyLinkKit/Extensions/NSDate.swift @@ -8,7 +8,7 @@ import Foundation -public func ==(lhs: NSDate, rhs: NSDate) -> Bool { +internal func ==(lhs: NSDate, rhs: NSDate) -> Bool { return lhs === rhs || lhs.compare(rhs) == .OrderedSame } From 0c1a0058dbc514c0d67345bde360ac2e2237bdc8 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 21 May 2016 16:45:23 -0500 Subject: [PATCH 25/40] Send config changes through device data manager --- RileyLink/DeviceDataManager.swift | 29 +++++++++++++++++++-- RileyLink/SettingsTableViewController.swift | 18 ++++++------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index 1deb2038e..1d6257d38 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -67,6 +67,31 @@ class DeviceDataManager { } } + var nightscoutURL: String? = Config.sharedInstance().nightscoutURL { + didSet { + if nightscoutURL?.characters.count == 0 { + nightscoutURL = nil + } + + if let nightscoutURL = nightscoutURL { + nightscoutUploader.siteURL = nightscoutURL + } + } + } + + var nightscoutAPISecret: String? = Config.sharedInstance().nightscoutAPISecret { + didSet { + if nightscoutAPISecret?.characters.count == 0 { + nightscoutAPISecret = nil + } + + if let nightscoutAPISecret = nightscoutAPISecret { + nightscoutUploader.APISecret = nightscoutAPISecret + } + } + } + + var lastHistoryAttempt: NSDate? = nil var lastRileyLinkHeardFrom: RileyLinkDevice? = nil @@ -212,8 +237,8 @@ class DeviceDataManager { ) nightscoutUploader = NightscoutUploader() - nightscoutUploader.siteURL = Config.sharedInstance().nightscoutURL - nightscoutUploader.APISecret = Config.sharedInstance().nightscoutAPISecret + nightscoutUploader.siteURL = nightscoutURL + nightscoutUploader.APISecret = nightscoutAPISecret let calendar = NSCalendar.currentCalendar() diff --git a/RileyLink/SettingsTableViewController.swift b/RileyLink/SettingsTableViewController.swift index 9b86a20d0..55b2e4de0 100644 --- a/RileyLink/SettingsTableViewController.swift +++ b/RileyLink/SettingsTableViewController.swift @@ -72,13 +72,13 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont 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 = Config.sharedInstance().pumpID ?? TapToSetString + configCell.detailTextLabel?.text = DeviceDataManager.sharedManager.pumpID ?? TapToSetString case .NightscoutURL: configCell.textLabel?.text = NSLocalizedString("Nightscout URL", comment: "The title text for the Nightscout URL config value") - configCell.detailTextLabel?.text = Config.sharedInstance().nightscoutURL ?? TapToSetString + configCell.detailTextLabel?.text = DeviceDataManager.sharedManager.nightscoutURL ?? TapToSetString case .NightscoutAPISecret: configCell.textLabel?.text = NSLocalizedString("Nightscout API Secret", comment: "The title text for the Nightscout API Secret config value") - configCell.detailTextLabel?.text = Config.sharedInstance().nightscoutAPISecret ?? TapToSetString + configCell.detailTextLabel?.text = DeviceDataManager.sharedManager.nightscoutAPISecret ?? TapToSetString } cell = configCell } @@ -129,14 +129,14 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont switch ConfigurationRow(rawValue: indexPath.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 = Config.sharedInstance().pumpID + vc.value = DeviceDataManager.sharedManager.pumpID case .NightscoutURL: vc.placeholder = NSLocalizedString("Enter the URL of your Nightscout site", comment: "The placeholder text instructing users how to enter the Nightscout URL") - vc.value = Config.sharedInstance().nightscoutURL + vc.value = DeviceDataManager.sharedManager.nightscoutURL vc.keyboardType = .URL case .NightscoutAPISecret: vc.placeholder = NSLocalizedString("Enter your Nightscout API Secret", comment: "The placeholder text instructing users how to enter their Nightscout API Secret") - vc.value = Config.sharedInstance().nightscoutAPISecret + vc.value = DeviceDataManager.sharedManager.nightscoutAPISecret } vc.title = cell.textLabel?.text @@ -160,11 +160,11 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont if let indexPath = controller.indexPath { switch ConfigurationRow(rawValue: indexPath.row)! { case .PumpID: - Config.sharedInstance().pumpID = controller.value + DeviceDataManager.sharedManager.pumpID = controller.value case .NightscoutURL: - Config.sharedInstance().nightscoutURL = controller.value + DeviceDataManager.sharedManager.nightscoutURL = controller.value case .NightscoutAPISecret: - Config.sharedInstance().nightscoutAPISecret = controller.value + DeviceDataManager.sharedManager.nightscoutAPISecret = controller.value } } From 6622bfa8e50dcd37a9289904f99c531230d0ad4d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 21 May 2016 20:37:37 -0500 Subject: [PATCH 26/40] Bump version number --- RileyLink/RileyLink-Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RileyLink/RileyLink-Info.plist b/RileyLink/RileyLink-Info.plist index 0fcec1bd9..f42191a06 100644 --- a/RileyLink/RileyLink-Info.plist +++ b/RileyLink/RileyLink-Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion From a41a4bf7137ec4d96997fcb654e0a0d8952ba9ea Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 21 May 2016 20:54:46 -0500 Subject: [PATCH 27/40] Adding about box --- RileyLink/SettingsTableViewController.swift | 33 +++++++++++++++++---- RileyLink/Storyboard.storyboard | 21 ++++++------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/RileyLink/SettingsTableViewController.swift b/RileyLink/SettingsTableViewController.swift index 55b2e4de0..d4fb5c28b 100644 --- a/RileyLink/SettingsTableViewController.swift +++ b/RileyLink/SettingsTableViewController.swift @@ -16,10 +16,17 @@ private let TapToSetString = NSLocalizedString("Tap to set", comment: "The empty class SettingsTableViewController: UITableViewController, TextFieldTableViewControllerDelegate { private enum Section: Int { - case Upload = 0 + case About = 0 + case Upload case Configuration - static let count = 2 + static let count = 3 + } + + private enum AboutRow: Int { + case Version = 0 + + static let count = 1 } private enum UploadRow: Int { @@ -44,6 +51,8 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont 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: @@ -55,8 +64,18 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont 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 = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")! + versionCell.textLabel?.text = "RileyLink iOS v\(version)" + + return versionCell + } case .Upload: - switch UploadRow(rawValue: indexPath.section)! { + switch UploadRow(rawValue: indexPath.row)! { case .Upload: let switchCell = tableView.dequeueReusableCellWithIdentifier(SwitchTableViewCell.className, forIndexPath: indexPath) as! SwitchTableViewCell @@ -87,6 +106,8 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { switch Section(rawValue: section)! { + case .About: + return NSLocalizedString("About", comment: "The title of the about section") case .Upload: return nil case .Configuration: @@ -105,14 +126,14 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont case .PumpID, .NightscoutAPISecret, .NightscoutURL: performSegueWithIdentifier(TextFieldTableViewController.className, sender: sender) } - case .Upload: + case .Upload, .About: break } } override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { switch Section(rawValue: section)! { - case .Upload, .Configuration: + case .Upload, .Configuration, .About: return nil } } @@ -148,7 +169,7 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont } } - // MARK: - Device mangement + // MARK: - Uploader mangement func uploadEnabledChanged(sender: UISwitch) { Config.sharedInstance().uploadEnabled = sender.on diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 7e5a81b43..0abdf6781 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -408,23 +408,24 @@ - + + + + + + - - - - From 909f8e5edd6dc8b0c5b68b70de286933e1607e07 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 21 May 2016 20:28:07 -0700 Subject: [PATCH 28/40] Updating Crypto branch to reduce flakiness --- Cartfile | 2 +- Cartfile.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile b/Cartfile index 60e2dcc01..77b4b3a30 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "loudnate/Crypto" +github "loudnate/Crypto" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index 31788b5b5..c2e3f6211 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "loudnate/Crypto" "v0.3.0" +github "loudnate/Crypto" "e0ef5b498f2c373d676135dabf5d1803b8558509" From 02269c7308bf2ba72f3dcaaf71d1008eb3f21f31 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 09:58:43 -0700 Subject: [PATCH 29/40] Minor directory organization --- RileyLink.xcodeproj/project.pbxproj | 16 ++++++++++++---- .../Views}/RileyLinkDeviceTableViewCell.swift | 0 2 files changed, 12 insertions(+), 4 deletions(-) rename {RileyLink => RileyLinkKit/Views}/RileyLinkDeviceTableViewCell.swift (100%) diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index f01d2f777..4c78b3f33 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 43722FC41CB9F7640038B7F2 /* RileyLinkKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 43722FCB1CB9F7DB0038B7F2 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; 43722FCC1CB9F7DB0038B7F2 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 430D64CB1CB855AB00FCA750 /* RileyLinkBLEKit.framework */; }; + 439731271CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */; }; 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 */; }; @@ -176,7 +177,6 @@ C1842C251C8FA45100DB42AC /* AlarmSensorPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1842BFB1C8FA45100DB42AC /* AlarmSensorPumpEvent.swift */; }; C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = C1AA39931AB6804000BC9E33 /* UIAlertView+Blocks.m */; }; C1AACC6B1CECD5F500C07049 /* RileyLinkListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1AACC6A1CECD5F500C07049 /* RileyLinkListTableViewController.swift */; }; - C1AACC6C1CECD63500C07049 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */; }; C1B3830E1CD0665D00CE7782 /* NightscoutUploadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C1B3830D1CD0665D00CE7782 /* NightscoutUploadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; C1B383151CD0665D00CE7782 /* NightscoutUploadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1B3830B1CD0665D00CE7782 /* NightscoutUploadKit.framework */; }; C1B3831C1CD0665D00CE7782 /* NightscoutUploadKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */; }; @@ -358,6 +358,7 @@ 43722FB71CB9F7640038B7F2 /* RileyLinkKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RileyLinkKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 43722FBE1CB9F7640038B7F2 /* RileyLinkKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkKitTests.swift; sourceTree = ""; }; 43722FC01CB9F7640038B7F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; 43CA93241CB8BB33000026B5 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; }; 43CA93281CB8CF22000026B5 /* ChangeTempBasalCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeTempBasalCarelinkMessageBody.swift; sourceTree = ""; }; 43CA932A1CB8CF76000026B5 /* ChangeTimeCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeTimeCarelinkMessageBody.swift; sourceTree = ""; }; @@ -514,7 +515,6 @@ C1B3831B1CD0665D00CE7782 /* NightscoutUploadKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadKitTests.swift; sourceTree = ""; }; 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 = ""; }; - C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RileyLinkDeviceTableViewCell.swift; path = ../RileyLink/RileyLinkDeviceTableViewCell.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 = ""; }; @@ -687,6 +687,7 @@ 43722FAF1CB9F7630038B7F2 /* RileyLinkKit */ = { isa = PBXGroup; children = ( + 439731251CF21BB800F474E5 /* Views */, C170C9951CECD76500F3D8E5 /* ViewControllers */, C170C98C1CECD6CE00F3D8E5 /* Extensions */, 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */, @@ -698,7 +699,6 @@ 434AB0941CBA0DF600422F4A /* PumpState.swift */, 434AB0C51CBCB41500422F4A /* RileyLinkDevice.swift */, 434AB0BD1CBB4E3200422F4A /* RileyLinkDeviceManager.swift */, - C1C2EB551CE583FF0070E259 /* RileyLinkDeviceTableViewCell.swift */, ); path = RileyLinkKit; sourceTree = ""; @@ -712,6 +712,14 @@ path = RileyLinkKitTests; sourceTree = ""; }; + 439731251CF21BB800F474E5 /* Views */ = { + isa = PBXGroup; + children = ( + 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */, + ); + path = Views; + sourceTree = ""; + }; C10D9BC21C8269D500378342 /* MinimedKit */ = { isa = PBXGroup; children = ( @@ -1512,9 +1520,9 @@ C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */, 434AB0C61CBCB41500422F4A /* RileyLinkDevice.swift in Sources */, 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */, + 439731271CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift in Sources */, 434AB0981CBA0DF600422F4A /* PumpState.swift in Sources */, C170C9991CECD80000F3D8E5 /* CommandResponseViewController.swift in Sources */, - C1AACC6C1CECD63500C07049 /* RileyLinkDeviceTableViewCell.swift in Sources */, C170C99A1CECD80000F3D8E5 /* MySentryPairViewController.swift in Sources */, 434AB0971CBA0DF600422F4A /* PumpOpsSynchronous.swift in Sources */, C170C98E1CECD6F300F3D8E5 /* CBPeripheralState.swift in Sources */, diff --git a/RileyLink/RileyLinkDeviceTableViewCell.swift b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift similarity index 100% rename from RileyLink/RileyLinkDeviceTableViewCell.swift rename to RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift From 43ca3ba4632bf380e2b2fd8049a6c48fb10f2442 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 10:18:24 -0700 Subject: [PATCH 30/40] Cleaning up redundant conformance conflicts --- RileyLink.xcodeproj/project.pbxproj | 12 ++++++----- RileyLink/IdentifiableClass.swift | 4 ++-- RileyLink/RileyLinkDeviceTableViewCell.swift | 13 ++++++++++++ .../Extensions/CBPeripheralState.swift | 9 +++++--- .../Extensions/IdentifiableClass.swift | 21 ------------------- RileyLinkKit/Extensions/NSDate.swift | 8 +++---- .../RileyLinkDeviceTableViewController.swift | 16 +++++++------- .../Views/RileyLinkDeviceTableViewCell.swift | 2 +- 8 files changed, 41 insertions(+), 44 deletions(-) create mode 100644 RileyLink/RileyLinkDeviceTableViewCell.swift delete mode 100644 RileyLinkKit/Extensions/IdentifiableClass.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 4c78b3f33..c0c41c856 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -32,6 +32,8 @@ 430D650D1CB89FC000FCA750 /* SendPacketCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = 430D64FD1CB89FC000FCA750 /* SendPacketCmd.m */; }; 430D650E1CB89FC000FCA750 /* UpdateRegisterCmd.h in Headers */ = {isa = PBXBuildFile; fileRef = 430D64FE1CB89FC000FCA750 /* UpdateRegisterCmd.h */; settings = {ATTRIBUTES = (Public, ); }; }; 430D650F1CB89FC000FCA750 /* UpdateRegisterCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = 430D64FF1CB89FC000FCA750 /* UpdateRegisterCmd.m */; }; + 431185A61CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185A51CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift */; }; + 431185A81CF21FC50059ED98 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843781CF0108B00D53CCD /* IdentifiableClass.swift */; }; 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */; }; 434AB0951CBA0DF600422F4A /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0911CBA0DF600422F4A /* Either.swift */; }; 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0921CBA0DF600422F4A /* PumpOps.swift */; }; @@ -111,7 +113,6 @@ C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */; }; C16843791CF0108B00D53CCD /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843781CF0108B00D53CCD /* IdentifiableClass.swift */; }; C170C98E1CECD6F300F3D8E5 /* CBPeripheralState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */; }; - C170C9911CECD72800F3D8E5 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C98F1CECD72800F3D8E5 /* IdentifiableClass.swift */; }; C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9901CECD72800F3D8E5 /* NSDate.swift */; }; C170C9991CECD80000F3D8E5 /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */; }; C170C99A1CECD80000F3D8E5 /* MySentryPairViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9971CECD80000F3D8E5 /* MySentryPairViewController.swift */; }; @@ -344,6 +345,7 @@ 430D64FD1CB89FC000FCA750 /* SendPacketCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SendPacketCmd.m; sourceTree = ""; }; 430D64FE1CB89FC000FCA750 /* UpdateRegisterCmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateRegisterCmd.h; sourceTree = ""; }; 430D64FF1CB89FC000FCA750 /* UpdateRegisterCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateRegisterCmd.m; sourceTree = ""; }; + 431185A51CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 434AB0911CBA0DF600422F4A /* Either.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Either.swift; sourceTree = ""; }; 434AB0921CBA0DF600422F4A /* PumpOps.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpOps.swift; sourceTree = ""; }; @@ -434,7 +436,6 @@ C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchTableViewCell.swift; sourceTree = ""; }; C16843781CF0108B00D53CCD /* IdentifiableClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifiableClass.swift; sourceTree = ""; }; C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBPeripheralState.swift; sourceTree = ""; }; - C170C98F1CECD72800F3D8E5 /* IdentifiableClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifiableClass.swift; sourceTree = ""; }; C170C9901CECD72800F3D8E5 /* NSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDate.swift; sourceTree = ""; }; C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandResponseViewController.swift; sourceTree = ""; }; C170C9971CECD80000F3D8E5 /* MySentryPairViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryPairViewController.swift; sourceTree = ""; }; @@ -784,9 +785,10 @@ C12616391B67CB9C001FAD87 /* TableViewCells */ = { isa = PBXGroup; children = ( - C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */, C12616581B6B2D20001FAD87 /* PacketTableViewCell.h */, C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */, + 431185A51CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift */, + C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */, ); name = TableViewCells; sourceTree = ""; @@ -922,7 +924,6 @@ C170C98C1CECD6CE00F3D8E5 /* Extensions */ = { isa = PBXGroup; children = ( - C170C98F1CECD72800F3D8E5 /* IdentifiableClass.swift */, C170C9901CECD72800F3D8E5 /* NSDate.swift */, C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */, ); @@ -1515,9 +1516,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C170C9911CECD72800F3D8E5 /* IdentifiableClass.swift in Sources */, 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */, C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */, + 431185A81CF21FC50059ED98 /* IdentifiableClass.swift in Sources */, 434AB0C61CBCB41500422F4A /* RileyLinkDevice.swift in Sources */, 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */, 439731271CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift in Sources */, @@ -1683,6 +1684,7 @@ 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */, C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, + 431185A61CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift in Sources */, C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, diff --git a/RileyLink/IdentifiableClass.swift b/RileyLink/IdentifiableClass.swift index c5e48080b..2f1cc4758 100644 --- a/RileyLink/IdentifiableClass.swift +++ b/RileyLink/IdentifiableClass.swift @@ -9,13 +9,13 @@ import Foundation -public protocol IdentifiableClass: class { +protocol IdentifiableClass: class { static var className: String { get } } extension IdentifiableClass { - public static var className: String { + static var className: String { return NSStringFromClass(self).componentsSeparatedByString(".").last! } } \ No newline at end of file diff --git a/RileyLink/RileyLinkDeviceTableViewCell.swift b/RileyLink/RileyLinkDeviceTableViewCell.swift new file mode 100644 index 000000000..1fc0e0fae --- /dev/null +++ b/RileyLink/RileyLinkDeviceTableViewCell.swift @@ -0,0 +1,13 @@ +// +// RileyLinkDeviceTableViewCell.swift +// RileyLink +// +// Created by Nathan Racklyeft on 5/22/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import Foundation +import RileyLinkKit + + +extension RileyLinkDeviceTableViewCell: IdentifiableClass { } \ No newline at end of file diff --git a/RileyLinkKit/Extensions/CBPeripheralState.swift b/RileyLinkKit/Extensions/CBPeripheralState.swift index 29c23856d..5debb21f6 100644 --- a/RileyLinkKit/Extensions/CBPeripheralState.swift +++ b/RileyLinkKit/Extensions/CBPeripheralState.swift @@ -9,8 +9,11 @@ import CoreBluetooth -extension CBPeripheralState: CustomStringConvertible { - public var description: String { +extension CBPeripheralState { + + // MARK: - CustomStringConvertible + + var description: String { switch self { case .Connected: return NSLocalizedString("Connected", comment: "The connected state") @@ -22,4 +25,4 @@ extension CBPeripheralState: CustomStringConvertible { return NSLocalizedString("Disconnecting", comment: "The in-progress disconnecting state") } } -} \ No newline at end of file +} diff --git a/RileyLinkKit/Extensions/IdentifiableClass.swift b/RileyLinkKit/Extensions/IdentifiableClass.swift deleted file mode 100644 index c5e48080b..000000000 --- a/RileyLinkKit/Extensions/IdentifiableClass.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// IdentifiableClass.swift -// Naterade -// -// Created by Nathan Racklyeft on 2/9/16. -// Copyright © 2016 Nathan Racklyeft. All rights reserved. -// - -import Foundation - - -public protocol IdentifiableClass: class { - static var className: String { get } -} - - -extension IdentifiableClass { - public static var className: String { - return NSStringFromClass(self).componentsSeparatedByString(".").last! - } -} \ No newline at end of file diff --git a/RileyLinkKit/Extensions/NSDate.swift b/RileyLinkKit/Extensions/NSDate.swift index 6f8fec0f8..b19efb77a 100644 --- a/RileyLinkKit/Extensions/NSDate.swift +++ b/RileyLinkKit/Extensions/NSDate.swift @@ -8,12 +8,12 @@ import Foundation -internal func ==(lhs: NSDate, rhs: NSDate) -> Bool { +func ==(lhs: NSDate, rhs: NSDate) -> Bool { return lhs === rhs || lhs.compare(rhs) == .OrderedSame } -public func <(lhs: NSDate, rhs: NSDate) -> Bool { +// MARK: - Comparable + +func <(lhs: NSDate, rhs: NSDate) -> Bool { return lhs.compare(rhs) == .OrderedAscending } - -extension NSDate: Comparable { } \ No newline at end of file diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift index ca61a381c..b58116c52 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -145,7 +145,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } case .Awake: switch device.pumpState?.awakeUntil { - case let until? where until < NSDate(): + case let until? where until.timeIntervalSinceNow < 0: cell.textLabel?.text = NSLocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") cell.detailTextLabel?.text = dateFormatter.stringFromDate(until) case let until?: @@ -286,13 +286,13 @@ public class RileyLinkDeviceTableViewController: UITableViewController { self.showViewController(vc, sender: indexPath) case .MySentryPair: - let vc = self.storyboard!.instantiateViewControllerWithIdentifier(MySentryPairViewController.className) as! MySentryPairViewController - - vc.device = device - - vc.title = NSLocalizedString("MySentry Pair", comment: "Title of screen for pairing with MySentry.") - - self.showViewController(vc, sender: indexPath) + if let vc = self.storyboard?.instantiateViewControllerWithIdentifier(MySentryPairViewController.className) as? MySentryPairViewController { + vc.device = device + + vc.title = NSLocalizedString("MySentry Pair", comment: "Title of screen for pairing with MySentry.") + + self.showViewController(vc, sender: indexPath) + } case .DumpHistory: let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)! diff --git a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift index 8dbc14060..37a1169b6 100644 --- a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift +++ b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift @@ -9,7 +9,7 @@ import CoreBluetooth import UIKit -public class RileyLinkDeviceTableViewCell: UITableViewCell, IdentifiableClass { +public class RileyLinkDeviceTableViewCell: UITableViewCell { @IBOutlet public weak var connectSwitch: UISwitch! From 67dc890e82760e8462d1b8ea6a4059fd587446c3 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 10:49:31 -0700 Subject: [PATCH 31/40] Removing the cell dependency from the device table view controller --- RileyLink/Storyboard.storyboard | 26 ------------------- .../RileyLinkDeviceTableViewController.swift | 22 +++++++++++----- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 0abdf6781..cc064201a 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -355,32 +355,6 @@ - - - - - - - - - - - - - - diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift index b58116c52..a6320613d 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -9,6 +9,8 @@ import UIKit import MinimedKit +let CellIdentifier = "Cell" + public class RileyLinkDeviceTableViewController: UITableViewController { public var device: RileyLinkDevice! @@ -108,7 +110,13 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } public override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) + let cell: UITableViewCell + + if let reusableCell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) { + cell = reusableCell + } else { + cell = UITableViewCell(style: .Value1, reuseIdentifier: CellIdentifier) + } cell.accessoryType = .None @@ -261,10 +269,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } }) - return NSLocalizedString("Tuning radio...", comment: "Progress message for tuning radio") + return NSLocalizedString("Tuning radio…", comment: "Progress message for tuning radio") }) - vc.title = "Tune device radio" + vc.title = NSLocalizedString("Tune device radio", comment: "Title of screen for tuning radio") self.showViewController(vc, sender: indexPath) case .ChangeTime: @@ -279,7 +287,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { } } - return NSLocalizedString("Changing time...", comment: "Progress message for changing pump time.") + return NSLocalizedString("Changing time…", comment: "Progress message for changing pump time.") } vc.title = NSLocalizedString("Change Time", comment: "Title of screen for changing pump time.") @@ -309,7 +317,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { completionHandler(responseText: String(error)) } } - return NSLocalizedString("Fetching history...", comment: "Progress message for fetching pump history.") + return NSLocalizedString("Fetching history…", comment: "Progress message for fetching pump history.") } vc.title = NSLocalizedString("Fetch History", comment: "Title of screen for fetching history.") @@ -325,7 +333,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { completionHandler(responseText: String(error)) } }) - return NSLocalizedString("Fetching pump model...", comment: "Progress message for fetching pump model.") + return NSLocalizedString("Fetching pump model…", comment: "Progress message for fetching pump model.") } vc.title = NSLocalizedString("Fetch Pump Model", comment: "Title of screen for fetching pump model.") @@ -340,7 +348,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { completionHandler(responseText: String(error)) } }) - return NSLocalizedString("Sending button press...", comment: "Progress message for sending button press to pump.") + return NSLocalizedString("Sending button press…", comment: "Progress message for sending button press to pump.") } vc.title = NSLocalizedString("Button Press", comment: "Title of screen for sending button press to pump.") From 03697f654977ec642a2b9481d0e0605ed838de89 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 10:58:54 -0700 Subject: [PATCH 32/40] Removing RileyLinkDeviceTableViewController from the storyboard Also, running `xcrun agvtool new-marketing-version 0.3.0` and `xcrun agvtool new-version 2` --- MinimedKit/Info.plist | 2 +- MinimedKitTests/Info.plist | 2 +- NightscoutUploadKit/Info.plist | 2 +- NightscoutUploadKitTests/Info.plist | 2 +- RileyLink.xcodeproj/project.pbxproj | 8 +++--- .../RileyLinkListTableViewController.swift | 27 +++++++------------ RileyLink/Storyboard.storyboard | 20 -------------- RileyLinkBLEKit/Info.plist | 2 +- RileyLinkBLEKitTests/Info.plist | 2 +- RileyLinkKit/Info.plist | 2 +- .../RileyLinkDeviceTableViewController.swift | 4 +++ RileyLinkKitTests/Info.plist | 2 +- RileyLinkTests/RileyLinkTests-Info.plist | 2 +- 13 files changed, 26 insertions(+), 51 deletions(-) diff --git a/MinimedKit/Info.plist b/MinimedKit/Info.plist index 6019f05bf..f42ccf54e 100644 --- a/MinimedKit/Info.plist +++ b/MinimedKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/MinimedKitTests/Info.plist b/MinimedKitTests/Info.plist index 9c88642be..33f323949 100644 --- a/MinimedKitTests/Info.plist +++ b/MinimedKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/NightscoutUploadKit/Info.plist b/NightscoutUploadKit/Info.plist index d3de8eefb..f42ccf54e 100644 --- a/NightscoutUploadKit/Info.plist +++ b/NightscoutUploadKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/NightscoutUploadKitTests/Info.plist b/NightscoutUploadKitTests/Info.plist index ba72822e8..37696856d 100644 --- a/NightscoutUploadKitTests/Info.plist +++ b/NightscoutUploadKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index c0c41c856..9bb10b1f4 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -2259,11 +2259,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; + DYLIB_CURRENT_VERSION = 2; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -2293,11 +2293,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; + DYLIB_CURRENT_VERSION = 2; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( diff --git a/RileyLink/RileyLinkListTableViewController.swift b/RileyLink/RileyLinkListTableViewController.swift index dd3f9fd7b..36502e715 100644 --- a/RileyLink/RileyLinkListTableViewController.swift +++ b/RileyLink/RileyLinkListTableViewController.swift @@ -108,7 +108,15 @@ class RileyLinkListTableViewController: UITableViewController { } } - + // MARK: - UITableViewDelegate + + override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + let vc = RileyLinkDeviceTableViewController() + + vc.device = dataManager.rileyLinkManager.devices[indexPath.row] + + showViewController(vc, sender: indexPath) + } /* // Override to support conditional editing of the table view. @@ -143,22 +151,5 @@ class RileyLinkListTableViewController: UITableViewController { return YES; } */ - - // MARK: Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { - if let - cell = sender as? UITableViewCell, - indexPath = tableView.indexPathForCell(cell) - { - switch segue.destinationViewController { - case let vc as RileyLinkDeviceTableViewController: - vc.device = dataManager.rileyLinkManager.devices[indexPath.row] - default: - break - } - } - } } \ No newline at end of file diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index cc064201a..be6091644 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -69,7 +69,6 @@ - @@ -347,25 +346,6 @@ - - - - - - - - - - - - - - - - - - - diff --git a/RileyLinkBLEKit/Info.plist b/RileyLinkBLEKit/Info.plist index 6019f05bf..f42ccf54e 100644 --- a/RileyLinkBLEKit/Info.plist +++ b/RileyLinkBLEKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkBLEKitTests/Info.plist b/RileyLinkBLEKitTests/Info.plist index 9c88642be..33f323949 100644 --- a/RileyLinkBLEKitTests/Info.plist +++ b/RileyLinkBLEKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKit/Info.plist b/RileyLinkKit/Info.plist index 6019f05bf..f42ccf54e 100644 --- a/RileyLinkKit/Info.plist +++ b/RileyLinkKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift index a6320613d..e45efc944 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -17,6 +17,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { private var appeared = false + convenience init() { + self.init(style: .Grouped) + } + public override func viewDidLoad() { super.viewDidLoad() diff --git a/RileyLinkKitTests/Info.plist b/RileyLinkKitTests/Info.plist index 9c88642be..33f323949 100644 --- a/RileyLinkKitTests/Info.plist +++ b/RileyLinkKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkTests/RileyLinkTests-Info.plist b/RileyLinkTests/RileyLinkTests-Info.plist index 62565e967..ca8898e2a 100644 --- a/RileyLinkTests/RileyLinkTests-Info.plist +++ b/RileyLinkTests/RileyLinkTests-Info.plist @@ -13,7 +13,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.2.0 + 0.3.0 CFBundleSignature ???? CFBundleVersion From 31959e039d3729e9eefb9af9b42b388002ba13c4 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 22 May 2016 15:16:30 -0500 Subject: [PATCH 33/40] Allow scan frequencies to be configured --- RileyLinkKit/PumpOps.swift | 3 ++- RileyLinkKit/PumpOpsSynchronous.swift | 13 ++++--------- RileyLinkKit/PumpState.swift | 8 ++++++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index 8903f7e9e..a1e242be6 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -168,7 +168,8 @@ public class PumpOps { device.runSession { (session) -> Void in let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) do { - let response = try ops.scanForPump() + let response = try ops.scanForPump(self.pumpState.scanFrequencies) + self.pumpState.lastTune = NSDate() dispatch_async(dispatch_get_main_queue(), { () -> Void in completion(.Success(response)) }) diff --git a/RileyLinkKit/PumpOpsSynchronous.swift b/RileyLinkKit/PumpOpsSynchronous.swift index fb0452f41..0d5ccf624 100644 --- a/RileyLinkKit/PumpOpsSynchronous.swift +++ b/RileyLinkKit/PumpOpsSynchronous.swift @@ -202,16 +202,15 @@ class PumpOpsSynchronous { NSLog("Set frequency to %f", freqMHz) } - internal func scanForPump() throws -> FrequencyScanResults { + internal func scanForPump(frequencies: [Double]) throws -> FrequencyScanResults { - let frequencies = [916.50, 916.55, 916.60, 916.65, 916.70, 916.75, 916.80] - //let frequencies = [868.0] var results = FrequencyScanResults() do { + // Needed to put the pump in listen mode try wakeup() } catch { - // Continue anyway + // Continue anyway; the pump likely heard us, even if we didn't hear it. } for freq in frequencies { @@ -256,11 +255,7 @@ class PumpOpsSynchronous { internal func getHistoryEventsSinceDate(startDate: NSDate) throws -> ([PumpEvent], PumpModel) { - do { - try wakeup() - } catch _ as PumpCommsError { - try scanForPump() - } + try wakeup() let pumpModel = try getPumpModel() diff --git a/RileyLinkKit/PumpState.swift b/RileyLinkKit/PumpState.swift index 599e39706..ae89f769c 100644 --- a/RileyLinkKit/PumpState.swift +++ b/RileyLinkKit/PumpState.swift @@ -23,8 +23,16 @@ public class PumpState { /// If the value type does not conform to AnyObject, a raw representation will be provided instead. public static let ValueChangeOldKey = "com.rileylink.RileyLinkKit.PumpState.ValueChangeOldKey" + public var scanFrequencies = [916.45, 916.50, 916.55, 916.60, 916.65, 916.70, 916.75, 916.80] + public let pumpID: String + public var lastTune: NSDate? { + didSet { + postChangeNotificationForKey("lastTune", oldValue: oldValue) + } + } + public var timeZone: NSTimeZone = NSTimeZone.defaultTimeZone() { didSet { postChangeNotificationForKey("timeZone", oldValue: oldValue) From d0c44e0957e628ae599505b9a59416deca7f8c64 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 14:05:49 -0700 Subject: [PATCH 34/40] Use CommandResponseViewController for MySentry pairing --- .../Messages/MySentryAckMessageBody.swift | 21 +++++---- .../MySentryPumpStatusMessageBody.swift | 10 +++-- .../RileyLinkListTableViewController.swift | 2 +- RileyLinkKit/PumpOps.swift | 44 +++++++++++++++--- RileyLinkKit/PumpOpsSynchronous.swift | 45 ++++++++++++++++++- .../RileyLinkDeviceTableViewController.swift | 37 +++++++++++++-- 6 files changed, 134 insertions(+), 25 deletions(-) diff --git a/MinimedKit/Messages/MySentryAckMessageBody.swift b/MinimedKit/Messages/MySentryAckMessageBody.swift index dae6bf37d..ee99875f3 100644 --- a/MinimedKit/Messages/MySentryAckMessageBody.swift +++ b/MinimedKit/Messages/MySentryAckMessageBody.swift @@ -10,19 +10,21 @@ import Foundation /// Describes an ACK message sent by a MySentry device in response to pump status messages. -/// a2 350535 06 59 000695 00 04000000 e2 +/// a2 350535 06 59 000695 00 04 00 00 00 e2 public struct MySentryAckMessageBody: MessageBody { public static let length = 9 - static var MessageCounter: UInt8 = 0 - let mySentryID: [UInt8] + let sequence: UInt8 + let mySentryID: NSData let responseMessageTypes: [MessageType] - public init(mySentryID: [UInt8], responseMessageTypes: [MessageType]) { - assert(mySentryID.count == 3) - assert(responseMessageTypes.count <= 4) + public init?(sequence: UInt8, watchdogID: NSData, responseMessageTypes: [MessageType]) { + guard responseMessageTypes.count <= 4 && watchdogID.length == 3 else { + return nil + } - self.mySentryID = mySentryID + self.sequence = sequence + self.mySentryID = watchdogID self.responseMessageTypes = responseMessageTypes } @@ -31,6 +33,7 @@ public struct MySentryAckMessageBody: MessageBody { return nil } + sequence = rxData[0] mySentryID = rxData[1...3] responseMessageTypes = rxData[5...8].flatMap({ MessageType(rawValue: $0) }) } @@ -38,8 +41,8 @@ public struct MySentryAckMessageBody: MessageBody { public var txData: NSData { var buffer = self.dynamicType.emptyBuffer - buffer[0] = UInt8(self.dynamicType.MessageCounter += 1) - buffer.replaceRange(1...3, with: mySentryID) + buffer[0] = sequence + buffer.replaceRange(1...3, with: mySentryID[0...2]) buffer.replaceRange(5..<5 + responseMessageTypes.count, with: responseMessageTypes.map({ $0.rawValue })) diff --git a/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift b/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift index 90fae4427..eab8be077 100644 --- a/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift +++ b/MinimedKit/Messages/MySentryPumpStatusMessageBody.swift @@ -83,7 +83,7 @@ public enum SensorReading { See: [MinimedRF Class](https://github.com/ps2/minimed_rf/blob/master/lib/minimed_rf/messages/pump_status.rb) ``` -- ------ -- 00 01 020304050607 08 09 10 11 1213 14 15 16 17 18 19 20 21 2223 24 25 26 27 282930313233 3435 -- - se tr pump date 01 bh ph resv bt st sr nxcal iob bl sens date 0000 + se tr pump date 01 bh ph resv bt st sr nxcal iob bl sens date 0000 a2 594040 04 c9 51 092c1e0f0904 01 32 33 00 037a 02 02 05 b0 18 30 13 2b 00d1 00 00 00 70 092b000f0904 0000 33 a2 594040 04 fb 51 1205000f0906 01 05 05 02 0000 04 00 00 00 ff 00 ff ff 0040 00 00 00 71 1205000f0906 0000 2b a2 594040 04 ff 50 1219000f0906 01 00 00 00 0000 04 00 00 00 00 00 00 00 005e 00 00 00 72 000000000000 0000 8b @@ -97,7 +97,9 @@ public struct MySentryPumpStatusMessageBody: MessageBody, DictionaryRepresentabl private static let reservoirSignificantDigit = 0.1 private static let iobSigificantDigit = 0.025 public static let length = 36 - + + public let sequence: UInt8 + public let pumpDateComponents: NSDateComponents public let batteryRemainingPercent: Int public let iob: Double @@ -122,7 +124,9 @@ public struct MySentryPumpStatusMessageBody: MessageBody, DictionaryRepresentabl } self.rxData = rxData - + + sequence = rxData[0] + let pumpDateComponents = NSDateComponents(mySentryBytes: rxData[2...7]) guard let calendar = pumpDateComponents.calendar where pumpDateComponents.isValidDateInCalendar(calendar) else { diff --git a/RileyLink/RileyLinkListTableViewController.swift b/RileyLink/RileyLinkListTableViewController.swift index 36502e715..c4acd187b 100644 --- a/RileyLink/RileyLinkListTableViewController.swift +++ b/RileyLink/RileyLinkListTableViewController.swift @@ -16,7 +16,7 @@ class RileyLinkListTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() - + dataManagerObserver = NSNotificationCenter.defaultCenter().addObserverForName(nil, object: dataManager, queue: nil) { [weak self = self] (note) -> Void in if let deviceManager = self?.dataManager.rileyLinkManager { switch note.name { diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index 8903f7e9e..275756565 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -94,7 +94,7 @@ public class PumpOps { - parameter units: The number of units to deliver - parameter completion: A closure called after the command is complete. This closure takes a single argument: - - error: An error describing why the command failed + - error: An error describing why the command failed */ public func setNormalBolus(units: Double, completion: (error: ErrorType?) -> Void) { device.runSession { (session) in @@ -123,8 +123,8 @@ public class PumpOps { - parameter unitsPerHour: The new basal rate, in Units per hour - parameter duration: The duration of the rate - parameter completion: A closure called after the command is complete. This closure takes a single Result argument: - - Success(messageBody): The pump message body describing the new basal rate - - Failure(error): An error describing why the command failed + - Success(messageBody): The pump message body describing the new basal rate + - Failure(error): An error describing why the command failed */ public func setTempBasal(unitsPerHour: Double, duration: NSTimeInterval, completion: (Either) -> Void) { device.runSession { (session) in @@ -146,7 +146,7 @@ public class PumpOps { - parameter generator: A closure which returns the desired date components. An exeception is raised if the date components are not valid. - parameter completion: A closure called after the command is complete. This closure takes a single argument: - - error: An error describing why the command failed + - error: An error describing why the command failed */ public func setTime(generator: () -> NSDateComponents, completion: (error: ErrorType?) -> Void) { device.runSession { (session) in @@ -162,9 +162,39 @@ public class PumpOps { } } } - - // TODO: Internal scope - public func tunePump(completion: (Either) -> Void) { + + /** + Pairs the pump with a virtual "watchdog" device to enable it to broadcast periodic status packets. Only pump models x23 and up are supported. + + This operation is performed asynchronously and the completion will be executed on an arbitrary background queue. + + - parameter watchdogID: A 3-byte address for the watchdog device. + - parameter completion: A closure called after the command is complete. This closure takes a single argument: + - error: An error describing why the command failed. + */ + public func changeWatchdogMarriageProfile(watchdogID: NSData, completion: (error: ErrorType?) -> Void) { + device.runSession { (session) in + let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) + + var lastError: ErrorType? + + for _ in 0..<3 { + do { + try ops.changeWatchdogMarriageProfile(watchdogID) + + lastError = nil + break + } catch let error { + print(error) + lastError = error + } + } + + completion(error: lastError) + } + } + + func tunePump(completion: (Either) -> Void) { device.runSession { (session) -> Void in let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) do { diff --git a/RileyLinkKit/PumpOpsSynchronous.swift b/RileyLinkKit/PumpOpsSynchronous.swift index fb0452f41..f106dabe7 100644 --- a/RileyLinkKit/PumpOpsSynchronous.swift +++ b/RileyLinkKit/PumpOpsSynchronous.swift @@ -177,7 +177,50 @@ class PumpOpsSynchronous { throw PumpCommsError.UnknownResponse("changeTime response: \(response.txData)") } } - + + internal func changeWatchdogMarriageProfile(watchdogID: NSData) throws { + let commandTimeoutMS: UInt16 = 30_000 + + print("\n\nPairing with \(watchdogID)\n\n") + + // Wait for the pump to start polling + print("Wait for the pump to start polling") + let listenForFindMessageCmd = GetPacketCmd() + listenForFindMessageCmd.listenChannel = 0 + listenForFindMessageCmd.timeoutMS = commandTimeoutMS + + guard session.doCmd(listenForFindMessageCmd, withTimeoutMs: Int(commandTimeoutMS) + expectedMaxBLELatencyMS) else { + throw PumpCommsError.RileyLinkTimeout + } + + guard let data = listenForFindMessageCmd.receivedPacket.data, findMessage = PumpMessage(rxData: data) where findMessage.address.hexadecimalString == pump.pumpID && findMessage.packetType == .MySentry, + let findMessageBody = findMessage.messageBody as? FindDeviceMessageBody, findMessageResponseBody = MySentryAckMessageBody(sequence: findMessageBody.sequence, watchdogID: watchdogID, responseMessageTypes: [findMessage.messageType]) + else { + throw PumpCommsError.UnknownResponse("Received \(listenForFindMessageCmd.receivedPacket.data ?? NSData())") + } + + // Identify as a MySentry device + print("Identify as a MySentry device") + let findMessageResponse = PumpMessage(packetType: .MySentry, address: pump.pumpID, messageType: .PumpAck, messageBody: findMessageResponseBody) + + let linkMessage = try sendAndListen(findMessageResponse, timeoutMS: commandTimeoutMS) + + guard let + linkMessageBody = linkMessage.messageBody as? DeviceLinkMessageBody, + linkMessageResponseBody = MySentryAckMessageBody(sequence: linkMessageBody.sequence, watchdogID: watchdogID, responseMessageTypes: [linkMessage.messageType]) + else { + throw PumpCommsError.UnknownResponse("Received \(linkMessage.messageBody.txData)") + } + + // Acknowledge the pump linked with us + print("Acknowledge the pump linked with us") + let linkMessageResponse = PumpMessage(packetType: .MySentry, address: pump.pumpID, messageType: .PumpAck, messageBody: linkMessageResponseBody) + + let cmd = SendPacketCmd() + cmd.packet = RFPacket(data: linkMessageResponse.txData) + session.doCmd(cmd, withTimeoutMs: expectedMaxBLELatencyMS) + } + internal func setRXFilterMode(mode: RXFilterMode) throws { let drate_e = UInt8(0x9) // exponent of symbol rate (16kbps) let chanbw = mode.rawValue diff --git a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift index e45efc944..ad4200019 100644 --- a/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKit/ViewControllers/RileyLinkDeviceTableViewController.swift @@ -298,13 +298,42 @@ public class RileyLinkDeviceTableViewController: UITableViewController { self.showViewController(vc, sender: indexPath) case .MySentryPair: - if let vc = self.storyboard?.instantiateViewControllerWithIdentifier(MySentryPairViewController.className) as? MySentryPairViewController { - vc.device = device + let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in - vc.title = NSLocalizedString("MySentry Pair", comment: "Title of screen for pairing with MySentry.") + self.device.ops?.setRXFilterMode(.Wide) { (error) in + if let error = error { + completionHandler(responseText: String(format: NSLocalizedString("Error setting filter bandwidth: %@", comment: "The error displayed during MySentry pairing when the RX filter could not be set"), String(error))) + } else { + var byteArray = [UInt8](count: 16, repeatedValue: 0) + self.device.peripheral.identifier.getUUIDBytes(&byteArray) + let watchdogID = NSData(bytes: &byteArray, length: 3) + + self.device.ops?.changeWatchdogMarriageProfile(watchdogID, completion: { (error) in + dispatch_async(dispatch_get_main_queue()) { + if let error = error { + completionHandler(responseText: String(format: NSLocalizedString("Failed: %@", comment: "A message indicating a command failed, with a substitution parameter for the error message"), String(error))) + } else { + completionHandler(responseText: NSLocalizedString("Succeeded", comment: "A message indicating a command succeeded")) + } + } + }) + } + } - self.showViewController(vc, sender: indexPath) + return NSLocalizedString( + "On your pump, go to the Find Device screen and select \"Find Device\"." + + "\n" + + "\nMain Menu >" + + "\nUtilities >" + + "\nConnect Devices >" + + "\nOther Devices >" + + "\nOn >" + + "\nFind Device", + comment: "Pump find device instruction" + ) } + + showViewController(vc, sender: indexPath) case .DumpHistory: let vc = CommandResponseViewController { [unowned self] (completionHandler) -> String in let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)! From e7c158f1947356d1f700140a4158bab53854fbc7 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 14:07:45 -0700 Subject: [PATCH 35/40] Removing MySentryPairViewController --- RileyLink.xcodeproj/project.pbxproj | 4 - RileyLink/Storyboard.storyboard | 83 ------ .../MySentryPairViewController.swift | 275 ------------------ 3 files changed, 362 deletions(-) delete mode 100644 RileyLinkKit/ViewControllers/MySentryPairViewController.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 9bb10b1f4..d83648e08 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -115,7 +115,6 @@ C170C98E1CECD6F300F3D8E5 /* CBPeripheralState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */; }; C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9901CECD72800F3D8E5 /* NSDate.swift */; }; C170C9991CECD80000F3D8E5 /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */; }; - C170C99A1CECD80000F3D8E5 /* MySentryPairViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9971CECD80000F3D8E5 /* MySentryPairViewController.swift */; }; C170C99B1CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */; }; C1711A561C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A551C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift */; }; C1711A5A1C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1711A591C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift */; }; @@ -438,7 +437,6 @@ C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBPeripheralState.swift; sourceTree = ""; }; C170C9901CECD72800F3D8E5 /* NSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDate.swift; sourceTree = ""; }; C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandResponseViewController.swift; sourceTree = ""; }; - C170C9971CECD80000F3D8E5 /* MySentryPairViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryPairViewController.swift; sourceTree = ""; }; C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewController.swift; sourceTree = ""; }; C1711A551C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonPressCarelinkMessageBody.swift; sourceTree = ""; }; C1711A591C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetPumpModelCarelinkMessageBody.swift; sourceTree = ""; }; @@ -934,7 +932,6 @@ isa = PBXGroup; children = ( C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */, - C170C9971CECD80000F3D8E5 /* MySentryPairViewController.swift */, C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */, ); path = ViewControllers; @@ -1524,7 +1521,6 @@ 439731271CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift in Sources */, 434AB0981CBA0DF600422F4A /* PumpState.swift in Sources */, C170C9991CECD80000F3D8E5 /* CommandResponseViewController.swift in Sources */, - C170C99A1CECD80000F3D8E5 /* MySentryPairViewController.swift in Sources */, 434AB0971CBA0DF600422F4A /* PumpOpsSynchronous.swift in Sources */, C170C98E1CECD6F300F3D8E5 /* CBPeripheralState.swift in Sources */, C170C99B1CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift in Sources */, diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index be6091644..47fd450cd 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -263,89 +263,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/RileyLinkKit/ViewControllers/MySentryPairViewController.swift b/RileyLinkKit/ViewControllers/MySentryPairViewController.swift deleted file mode 100644 index 6285d78d1..000000000 --- a/RileyLinkKit/ViewControllers/MySentryPairViewController.swift +++ /dev/null @@ -1,275 +0,0 @@ -// -// MySentryPairViewController.swift -// RileyLink -// -// Created by Pete Schwamb on 2/29/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -import UIKit -import MinimedKit -import RileyLinkBLEKit - -class MySentryPairViewController: UIViewController, UITextFieldDelegate, IdentifiableClass { - - enum PairingState { - case Complete - case NeedsConfig - case Ready - case Started - case ReceivedFindPacket - case ReceivedLinkPacket - } - - var device: RileyLinkDevice! - var wasDismissed = false - - @IBOutlet var instructionLabel: UILabel! - @IBOutlet var deviceIDTextField: UITextField! - @IBOutlet var startButton: UIButton! - @IBOutlet var progressView: UIProgressView! - - lazy var flailGestureRecognizer: UITapGestureRecognizer = { - let r = UITapGestureRecognizer(target: self, action: #selector(MySentryPairViewController.closeKeyboard(_:))) - r.cancelsTouchesInView = false; - r.enabled = false; - return r - }() - - var sendCounter: UInt8 = 0 - - override func viewDidLoad() { - super.viewDidLoad() - - deviceIDTextField.text = (device.peripheral.identifier.UUIDString as NSString).substringToIndex(6); - deviceIDTextField.delegate = self - - view.addGestureRecognizer(flailGestureRecognizer) - - textFieldDidEndEditing(deviceIDTextField) - } - - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } - - override func viewDidDisappear(animated: Bool) { - wasDismissed = true - } - - - // MARK: - UITextFieldDelegate - - func textFieldDidBeginEditing(textField: UITextField) { - flailGestureRecognizer.enabled = true - } - - func textFieldDidEndEditing(textField: UITextField) { - flailGestureRecognizer.enabled = false - - if textField.text?.characters.count == 6 { - state = .Ready - } else if .Ready == self.state { - state = .NeedsConfig - } - } - - func textField(textField: UITextField, - shouldChangeCharactersInRange range: NSRange, - replacementString string: String) -> Bool { - let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString:string) - - if newString.characters.count > 6 { - return false - } else if newString.characters.count == 6 { - textField.text = newString - textField.resignFirstResponder() - return false - } else if .Ready == self.state { - state = .NeedsConfig - } - - return true - } - - func textFieldShouldReturn(textField: UITextField) -> Bool { - return true - } - - // MARK: - Other - - func listenForPairing() { - if wasDismissed { - return - } - - let cmd = GetPacketCmd() - cmd.listenChannel = 0; - cmd.timeoutMS = 30000; - runCommand(cmd) - } - - var state: PairingState = .NeedsConfig { - didSet { - if (oldValue == state) { - return - } - switch state { - case .NeedsConfig: - startButton.enabled = false - startButton.hidden = true - instructionLabel.text = NSLocalizedString( - "Enter a 6-digit numeric value to identify your MySentry.", - comment: "Device ID instruction") - instructionLabel.hidden = false - case .Ready: - startButton.enabled = true - startButton.hidden = false - progressView.progress = 0 - - instructionLabel.hidden = true - case .Started: - startButton.enabled = false - startButton.hidden = true - deviceIDTextField.enabled = false - progressView.setProgress(1.0 / 4.0, animated:true) - - instructionLabel.text = NSLocalizedString( - "On your pump, go to the Find Device screen and select \"Find Device\"." + - "\n" + - "\nMain Menu >" + - "\nUtilities >" + - "\nConnect Devices >" + - "\nOther Devices >" + - "\nOn >" + - "\nFind Device", - comment: "Pump find device instruction") - instructionLabel.hidden = false - case .ReceivedFindPacket: - progressView.setProgress(2.0 / 4.0, animated:true) - - instructionLabel.text = NSLocalizedString( - "Pairing in process, please wait.", - comment: "Pairing waiting instruction") - case .ReceivedLinkPacket: - progressView.setProgress(3.0 / 4.0, animated:true) - instructionLabel.text = NSLocalizedString( - "Pump accepted pairing. " + - "Waiting for MySentry update from pump. " + - "This could take up to five minutes...", - comment: "Pairing waiting instruction") - case .Complete: - progressView.setProgress(4.0 / 4.0, animated:true) - - instructionLabel.text = NSLocalizedString( - "Congratulations! Pairing is complete.", - comment: "Pairing waiting instruction") - } - } - } - - // MARK: - Actions - - func packetReceived(packet: RFPacket) { - - var handled = false - - if let data = packet.data, msg = PumpMessage(rxData: data) { - if msg.packetType == PacketType.MySentry && - msg.address.hexadecimalString == device.pumpState?.pumpID { - switch (msg.messageType) { - case MessageType.FindDevice: - handleFindDevice(msg.messageBody as! FindDeviceMessageBody) - handled = true - case MessageType.DeviceLink: - handleDeviceLink(msg.messageBody as! DeviceLinkMessageBody) - handled = true - case MessageType.PumpStatus: - handlePumpStatus(msg.messageBody as! MySentryPumpStatusMessageBody) - handled = true - default: - NSLog("Unexpected packet received: " + String(msg.messageType)) - } - } - } - if (!handled && .Complete != self.state) { - // Other random packet; ignore and start listening again. - performSelector(#selector(MySentryPairViewController.listenForPairing), withObject:nil, afterDelay:0) - } - } - - func makeCommandForAckAndListen(sequence: UInt8, messageType: MessageType) -> ReceivingPacketCmd { - let replyString = String(format: "%02x%@%02x%02x%@00%02x000000", - PacketType.MySentry.rawValue, - device.pumpState!.pumpID, - MessageType.PumpAck.rawValue, - sequence, - self.deviceIDTextField.text!, - messageType.rawValue) - let data = NSData(hexadecimalString: replyString) - let send = SendAndListenCmd() - send.sendChannel = 0 - send.timeoutMS = 180 - send.listenChannel = 0 - send.packet = RFPacket(data: data!) - return send; - } - - func runCommand(cmd: ReceivingPacketCmd) { - device.ops?.device.runSession { - (session: RileyLinkCmdSession) -> Void in - if (session.doCmd(cmd, withTimeoutMs: 31000)) { - dispatch_async(dispatch_get_main_queue(), { () -> Void in - let rxPacket = cmd.receivedPacket - self.packetReceived(rxPacket) - }) - } else { - // Timed out. Try again - self.performSelector(#selector(MySentryPairViewController.listenForPairing), withObject:nil, afterDelay:0) - } - } - } - - func handleFindDevice(msg: FindDeviceMessageBody) { - if .Started == self.state { - self.state = .ReceivedFindPacket - } - - let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.FindDevice) - runCommand(cmd) - } - - func handleDeviceLink(msg: DeviceLinkMessageBody) { - if .ReceivedFindPacket == self.state { - self.state = .ReceivedLinkPacket - } - - let cmd = makeCommandForAckAndListen(msg.sequence, messageType: MessageType.DeviceLink) - runCommand(cmd) - } - - func handlePumpStatus(msg: MySentryPumpStatusMessageBody) { - if .ReceivedLinkPacket == self.state { - self.state = .Complete; - } - let cmd = makeCommandForAckAndListen(0, messageType: MessageType.PumpStatus) - runCommand(cmd) - } - - func closeKeyboard(recognizer: UITapGestureRecognizer) { - self.view.endEditing(true) - } - - @IBAction func beginPairing(sender: UIButton) { - if (.Ready == self.state) { - self.state = .Started - device.ops?.setRXFilterMode(.Wide, completion: { (error) in - if let error = error { - NSLog("Error setting filter bandwidth: %s", String(error)) - } - self.listenForPairing() - }) - } - } -} From d73e116100b2427809e8d24aa9a33d04484273b8 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 14:09:59 -0700 Subject: [PATCH 36/40] Removing print statements --- RileyLinkKit/PumpOps.swift | 1 - RileyLinkKit/PumpOpsSynchronous.swift | 5 ----- 2 files changed, 6 deletions(-) diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index 275756565..ff2317dca 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -185,7 +185,6 @@ public class PumpOps { lastError = nil break } catch let error { - print(error) lastError = error } } diff --git a/RileyLinkKit/PumpOpsSynchronous.swift b/RileyLinkKit/PumpOpsSynchronous.swift index f106dabe7..2e72c8738 100644 --- a/RileyLinkKit/PumpOpsSynchronous.swift +++ b/RileyLinkKit/PumpOpsSynchronous.swift @@ -181,10 +181,7 @@ class PumpOpsSynchronous { internal func changeWatchdogMarriageProfile(watchdogID: NSData) throws { let commandTimeoutMS: UInt16 = 30_000 - print("\n\nPairing with \(watchdogID)\n\n") - // Wait for the pump to start polling - print("Wait for the pump to start polling") let listenForFindMessageCmd = GetPacketCmd() listenForFindMessageCmd.listenChannel = 0 listenForFindMessageCmd.timeoutMS = commandTimeoutMS @@ -200,7 +197,6 @@ class PumpOpsSynchronous { } // Identify as a MySentry device - print("Identify as a MySentry device") let findMessageResponse = PumpMessage(packetType: .MySentry, address: pump.pumpID, messageType: .PumpAck, messageBody: findMessageResponseBody) let linkMessage = try sendAndListen(findMessageResponse, timeoutMS: commandTimeoutMS) @@ -213,7 +209,6 @@ class PumpOpsSynchronous { } // Acknowledge the pump linked with us - print("Acknowledge the pump linked with us") let linkMessageResponse = PumpMessage(packetType: .MySentry, address: pump.pumpID, messageType: .PumpAck, messageBody: linkMessageResponseBody) let cmd = SendPacketCmd() From 8bfdf4ba544a1eee53dfbee58054ef47ab5cad12 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 14:29:33 -0700 Subject: [PATCH 37/40] Moving RileyLinkDeviceTableViewCell's nib into the framework --- RileyLink/RileyLinkDeviceTableViewCell.swift | 13 ----- .../RileyLinkListTableViewController.swift | 2 + RileyLink/Storyboard.storyboard | 40 --------------- RileyLink/SwitchTableViewCell.swift | 1 + RileyLink/TextFieldTableViewController.swift | 1 + .../Extensions}/IdentifiableClass.swift | 6 +-- .../Views/RileyLinkDeviceTableViewCell.swift | 8 ++- .../Views/RileyLinkDeviceTableViewCell.xib | 51 +++++++++++++++++++ 8 files changed, 64 insertions(+), 58 deletions(-) delete mode 100644 RileyLink/RileyLinkDeviceTableViewCell.swift rename {RileyLink => RileyLinkKit/Extensions}/IdentifiableClass.swift (79%) create mode 100644 RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib diff --git a/RileyLink/RileyLinkDeviceTableViewCell.swift b/RileyLink/RileyLinkDeviceTableViewCell.swift deleted file mode 100644 index 1fc0e0fae..000000000 --- a/RileyLink/RileyLinkDeviceTableViewCell.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// RileyLinkDeviceTableViewCell.swift -// RileyLink -// -// Created by Nathan Racklyeft on 5/22/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -import Foundation -import RileyLinkKit - - -extension RileyLinkDeviceTableViewCell: IdentifiableClass { } \ No newline at end of file diff --git a/RileyLink/RileyLinkListTableViewController.swift b/RileyLink/RileyLinkListTableViewController.swift index c4acd187b..fa56bdb23 100644 --- a/RileyLink/RileyLinkListTableViewController.swift +++ b/RileyLink/RileyLinkListTableViewController.swift @@ -17,6 +17,8 @@ class RileyLinkListTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() + tableView.registerNib(RileyLinkDeviceTableViewCell.nib(), forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className) + dataManagerObserver = NSNotificationCenter.defaultCenter().addObserverForName(nil, object: dataManager, queue: nil) { [weak self = self] (note) -> Void in if let deviceManager = self?.dataManager.rileyLinkManager { switch note.name { diff --git a/RileyLink/Storyboard.storyboard b/RileyLink/Storyboard.storyboard index 47fd450cd..126767f5f 100644 --- a/RileyLink/Storyboard.storyboard +++ b/RileyLink/Storyboard.storyboard @@ -32,46 +32,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/RileyLink/SwitchTableViewCell.swift b/RileyLink/SwitchTableViewCell.swift index 9dafc2308..8dcc04030 100644 --- a/RileyLink/SwitchTableViewCell.swift +++ b/RileyLink/SwitchTableViewCell.swift @@ -7,6 +7,7 @@ // import UIKit +import RileyLinkKit class SwitchTableViewCell: UITableViewCell, IdentifiableClass { diff --git a/RileyLink/TextFieldTableViewController.swift b/RileyLink/TextFieldTableViewController.swift index 4f129d221..c97144ae3 100644 --- a/RileyLink/TextFieldTableViewController.swift +++ b/RileyLink/TextFieldTableViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import RileyLinkKit protocol TextFieldTableViewControllerDelegate: class { func textFieldTableViewControllerDidEndEditing(controller: TextFieldTableViewController) diff --git a/RileyLink/IdentifiableClass.swift b/RileyLinkKit/Extensions/IdentifiableClass.swift similarity index 79% rename from RileyLink/IdentifiableClass.swift rename to RileyLinkKit/Extensions/IdentifiableClass.swift index 2f1cc4758..d12a7fe60 100644 --- a/RileyLink/IdentifiableClass.swift +++ b/RileyLinkKit/Extensions/IdentifiableClass.swift @@ -9,13 +9,13 @@ import Foundation -protocol IdentifiableClass: class { +public protocol IdentifiableClass: class { static var className: String { get } } extension IdentifiableClass { - static var className: String { + public static var className: String { return NSStringFromClass(self).componentsSeparatedByString(".").last! } -} \ No newline at end of file +} diff --git a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift index 37a1169b6..063721c7a 100644 --- a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift +++ b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift @@ -9,14 +9,18 @@ import CoreBluetooth import UIKit -public class RileyLinkDeviceTableViewCell: UITableViewCell { +public class RileyLinkDeviceTableViewCell: UITableViewCell, IdentifiableClass { @IBOutlet public weak var connectSwitch: UISwitch! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var signalLabel: UILabel! - + + public static func nib() -> UINib { + return UINib(nibName: className, bundle: NSBundle(forClass: self)) + } + public func configureCellWithName(name: String?, signal: Int?, peripheralState: CBPeripheralState?) { nameLabel.text = name signalLabel.text = signal != nil ? "\(signal!) dB" : nil diff --git a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib new file mode 100644 index 000000000..284ad6573 --- /dev/null +++ b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.xib @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 13448bbc217a6ef33041ed1b3c6f0e67d92cadbf Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 14:30:39 -0700 Subject: [PATCH 38/40] Removing NibLoadableView --- RileyLink.xcodeproj/project.pbxproj | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index d83648e08..7b20a2f40 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -32,8 +32,8 @@ 430D650D1CB89FC000FCA750 /* SendPacketCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = 430D64FD1CB89FC000FCA750 /* SendPacketCmd.m */; }; 430D650E1CB89FC000FCA750 /* UpdateRegisterCmd.h in Headers */ = {isa = PBXBuildFile; fileRef = 430D64FE1CB89FC000FCA750 /* UpdateRegisterCmd.h */; settings = {ATTRIBUTES = (Public, ); }; }; 430D650F1CB89FC000FCA750 /* UpdateRegisterCmd.m in Sources */ = {isa = PBXBuildFile; fileRef = 430D64FF1CB89FC000FCA750 /* UpdateRegisterCmd.m */; }; - 431185A61CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185A51CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift */; }; - 431185A81CF21FC50059ED98 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843781CF0108B00D53CCD /* IdentifiableClass.swift */; }; + 431185AA1CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 431185A91CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib */; }; + 431185AF1CF25A590059ED98 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; }; 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */; }; 434AB0951CBA0DF600422F4A /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0911CBA0DF600422F4A /* Either.swift */; }; 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0921CBA0DF600422F4A /* PumpOps.swift */; }; @@ -111,7 +111,6 @@ C16843741CF009E600D53CCD /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843721CF009E600D53CCD /* SettingsTableViewController.swift */; }; C16843751CF009E600D53CCD /* TextFieldTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843731CF009E600D53CCD /* TextFieldTableViewController.swift */; }; C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */; }; - C16843791CF0108B00D53CCD /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16843781CF0108B00D53CCD /* IdentifiableClass.swift */; }; C170C98E1CECD6F300F3D8E5 /* CBPeripheralState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */; }; C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9901CECD72800F3D8E5 /* NSDate.swift */; }; C170C9991CECD80000F3D8E5 /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */; }; @@ -344,7 +343,8 @@ 430D64FD1CB89FC000FCA750 /* SendPacketCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SendPacketCmd.m; sourceTree = ""; }; 430D64FE1CB89FC000FCA750 /* UpdateRegisterCmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateRegisterCmd.h; sourceTree = ""; }; 430D64FF1CB89FC000FCA750 /* UpdateRegisterCmd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateRegisterCmd.m; sourceTree = ""; }; - 431185A51CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; + 431185A91CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RileyLinkDeviceTableViewCell.xib; sourceTree = ""; }; + 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifiableClass.swift; sourceTree = ""; }; 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 434AB0911CBA0DF600422F4A /* Either.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Either.swift; sourceTree = ""; }; 434AB0921CBA0DF600422F4A /* PumpOps.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpOps.swift; sourceTree = ""; }; @@ -433,7 +433,6 @@ C16843721CF009E600D53CCD /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = ""; }; C16843731CF009E600D53CCD /* TextFieldTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewController.swift; sourceTree = ""; }; C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchTableViewCell.swift; sourceTree = ""; }; - C16843781CF0108B00D53CCD /* IdentifiableClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifiableClass.swift; sourceTree = ""; }; C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBPeripheralState.swift; sourceTree = ""; }; C170C9901CECD72800F3D8E5 /* NSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDate.swift; sourceTree = ""; }; C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandResponseViewController.swift; sourceTree = ""; }; @@ -715,6 +714,7 @@ isa = PBXGroup; children = ( 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */, + 431185A91CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib */, ); path = Views; sourceTree = ""; @@ -785,7 +785,6 @@ children = ( C12616581B6B2D20001FAD87 /* PacketTableViewCell.h */, C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */, - 431185A51CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift */, C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */, ); name = TableViewCells; @@ -922,8 +921,9 @@ C170C98C1CECD6CE00F3D8E5 /* Extensions */ = { isa = PBXGroup; children = ( - C170C9901CECD72800F3D8E5 /* NSDate.swift */, C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */, + 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */, + C170C9901CECD72800F3D8E5 /* NSDate.swift */, ); path = Extensions; sourceTree = ""; @@ -1004,7 +1004,6 @@ C1AA398B1AB67F6A00BC9E33 /* Extensions */ = { isa = PBXGroup; children = ( - C16843781CF0108B00D53CCD /* IdentifiableClass.swift */, C1E535E81991E36700C2AC49 /* NSData+Conversion.h */, C1E535E91991E36700C2AC49 /* NSData+Conversion.m */, C1AA39921AB6804000BC9E33 /* UIAlertView+Blocks.h */, @@ -1423,6 +1422,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 431185AA1CF257D10059ED98 /* RileyLinkDeviceTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1515,7 +1515,7 @@ files = ( 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */, C170C9921CECD72800F3D8E5 /* NSDate.swift in Sources */, - 431185A81CF21FC50059ED98 /* IdentifiableClass.swift in Sources */, + 431185AF1CF25A590059ED98 /* IdentifiableClass.swift in Sources */, 434AB0C61CBCB41500422F4A /* RileyLinkDevice.swift in Sources */, 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */, 439731271CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift in Sources */, @@ -1675,12 +1675,10 @@ C139AC241BFD84B500B0518F /* RuntimeUtils.m in Sources */, C12616541B6892DB001FAD87 /* RileyLinkRecord.m in Sources */, C12616671B76E8DC001FAD87 /* TPKeyboardAvoidingCollectionView.m in Sources */, - C16843791CF0108B00D53CCD /* IdentifiableClass.swift in Sources */, C126165A1B6B2D20001FAD87 /* PacketTableViewCell.m in Sources */, 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */, C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, - 431185A61CF21F6E0059ED98 /* RileyLinkDeviceTableViewCell.swift in Sources */, C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, From daeba6e53f6a91567ecdd382a6854395da61bd38 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 22 May 2016 16:43:38 -0500 Subject: [PATCH 39/40] Remove lastTune; it's already in RileyLinkDevice --- RileyLinkKit/PumpOps.swift | 1 - RileyLinkKit/PumpState.swift | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/RileyLinkKit/PumpOps.swift b/RileyLinkKit/PumpOps.swift index a1e242be6..9f8e3e9fa 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/RileyLinkKit/PumpOps.swift @@ -169,7 +169,6 @@ public class PumpOps { let ops = PumpOpsSynchronous(pumpState: self.pumpState, session: session) do { let response = try ops.scanForPump(self.pumpState.scanFrequencies) - self.pumpState.lastTune = NSDate() dispatch_async(dispatch_get_main_queue(), { () -> Void in completion(.Success(response)) }) diff --git a/RileyLinkKit/PumpState.swift b/RileyLinkKit/PumpState.swift index ae89f769c..612d41245 100644 --- a/RileyLinkKit/PumpState.swift +++ b/RileyLinkKit/PumpState.swift @@ -26,13 +26,7 @@ public class PumpState { public var scanFrequencies = [916.45, 916.50, 916.55, 916.60, 916.65, 916.70, 916.75, 916.80] public let pumpID: String - - public var lastTune: NSDate? { - didSet { - postChangeNotificationForKey("lastTune", oldValue: oldValue) - } - } - + public var timeZone: NSTimeZone = NSTimeZone.defaultTimeZone() { didSet { postChangeNotificationForKey("timeZone", oldValue: oldValue) From 1d495a9c95c0aa40bfc5f59bb6fe6b1efe185081 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sun, 22 May 2016 15:25:19 -0700 Subject: [PATCH 40/40] Don't let IdentifiableClass be public... again --- RileyLink.xcodeproj/project.pbxproj | 6 ++++++ RileyLink/RileyLinkDeviceTableViewCell.swift | 12 ++++++++++++ RileyLinkKit/Extensions/IdentifiableClass.swift | 4 ++-- .../Views/RileyLinkDeviceTableViewCell.swift | 5 ++++- 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 RileyLink/RileyLinkDeviceTableViewCell.swift diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 7b20a2f40..8a6901bb9 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -43,6 +43,8 @@ 434AB0BE1CBB4E3200422F4A /* RileyLinkDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0BD1CBB4E3200422F4A /* RileyLinkDeviceManager.swift */; }; 434AB0C61CBCB41500422F4A /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0C51CBCB41500422F4A /* RileyLinkDevice.swift */; }; 434AB0C71CBCB76400422F4A /* NSData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* NSData.swift */; }; + 434FF1DC1CF268BD000DB779 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; }; + 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */; }; 43523ED71CC2C558001850F1 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = C1E535E91991E36700C2AC49 /* NSData+Conversion.m */; }; 43722FB11CB9F7640038B7F2 /* RileyLinkKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43722FB81CB9F7640038B7F2 /* RileyLinkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; }; @@ -353,6 +355,7 @@ 434AB09D1CBA28F100422F4A /* NSTimeInterval.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSTimeInterval.swift; sourceTree = ""; }; 434AB0BD1CBB4E3200422F4A /* RileyLinkDeviceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceManager.swift; sourceTree = ""; }; 434AB0C51CBCB41500422F4A /* RileyLinkDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDevice.swift; sourceTree = ""; }; + 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RileyLinkKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RileyLinkKit.h; sourceTree = ""; }; 43722FB21CB9F7640038B7F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -785,6 +788,7 @@ children = ( C12616581B6B2D20001FAD87 /* PacketTableViewCell.h */, C12616591B6B2D20001FAD87 /* PacketTableViewCell.m */, + 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */, C16843761CF00C0100D53CCD /* SwitchTableViewCell.swift */, ); name = TableViewCells; @@ -1680,6 +1684,7 @@ C174F26B19EB824D00398C72 /* ISO8601DateFormatter.m in Sources */, C126166A1B76E8DC001FAD87 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */, + 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */, C1AA39941AB6804000BC9E33 /* UIAlertView+Blocks.m in Sources */, C1EF58881B3F93FE001C8C80 /* Config.m in Sources */, C126164B1B685F93001FAD87 /* RileyLink.xcdatamodeld in Sources */, @@ -1689,6 +1694,7 @@ C1B383361CD1BA8100CE7782 /* DeviceDataManager.swift in Sources */, C1271B071A9A34E900B7C949 /* Log.m in Sources */, C16843741CF009E600D53CCD /* SettingsTableViewController.swift in Sources */, + 434FF1DC1CF268BD000DB779 /* IdentifiableClass.swift in Sources */, C1E535EA1991E36700C2AC49 /* NSData+Conversion.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/RileyLink/RileyLinkDeviceTableViewCell.swift b/RileyLink/RileyLinkDeviceTableViewCell.swift new file mode 100644 index 000000000..61ba2dc13 --- /dev/null +++ b/RileyLink/RileyLinkDeviceTableViewCell.swift @@ -0,0 +1,12 @@ +// +// RileyLinkDeviceTableViewCell.swift +// RileyLink +// +// Created by Nathan Racklyeft on 5/22/16. +// Copyright © 2016 Pete Schwamb. All rights reserved. +// + +import UIKit +import RileyLinkKit + +extension RileyLinkDeviceTableViewCell: IdentifiableClass { } diff --git a/RileyLinkKit/Extensions/IdentifiableClass.swift b/RileyLinkKit/Extensions/IdentifiableClass.swift index d12a7fe60..ec5606829 100644 --- a/RileyLinkKit/Extensions/IdentifiableClass.swift +++ b/RileyLinkKit/Extensions/IdentifiableClass.swift @@ -9,13 +9,13 @@ import Foundation -public protocol IdentifiableClass: class { +protocol IdentifiableClass: class { static var className: String { get } } extension IdentifiableClass { - public static var className: String { + static var className: String { return NSStringFromClass(self).componentsSeparatedByString(".").last! } } diff --git a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift index 063721c7a..5f0a96fd1 100644 --- a/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift +++ b/RileyLinkKit/Views/RileyLinkDeviceTableViewCell.swift @@ -9,7 +9,7 @@ import CoreBluetooth import UIKit -public class RileyLinkDeviceTableViewCell: UITableViewCell, IdentifiableClass { +public class RileyLinkDeviceTableViewCell: UITableViewCell { @IBOutlet public weak var connectSwitch: UISwitch! @@ -53,3 +53,6 @@ public class RileyLinkDeviceTableViewCell: UITableViewCell, IdentifiableClass { } } + +extension RileyLinkDeviceTableViewCell: IdentifiableClass { } +