Переглянути джерело

removed fade-in for test audio
removed underscores from audio file name display
finalized pulling basal profile from NS into array

Jon Fawcett 6 роки тому
батько
коміт
f74c5d785c

+ 4 - 0
LoopFollow.xcodeproj/project.pbxproj

@@ -134,6 +134,7 @@
 		FC9788242485969B00A7906C /* LoopFollow.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = FC9788222485969B00A7906C /* LoopFollow.xcdatamodeld */; };
 		FC9788262485969C00A7906C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FC9788252485969C00A7906C /* Assets.xcassets */; };
 		FC9788292485969C00A7906C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FC9788272485969C00A7906C /* LaunchScreen.storyboard */; };
+		FCC0FAC224922A22003E610E /* DictionaryKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC0FAC124922A22003E610E /* DictionaryKeyPath.swift */; };
 		FCC68850248935D800A0279D /* AlarmViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6884F248935D800A0279D /* AlarmViewController.swift */; };
 		FCC6885A2489554800A0279D /* BackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC688592489554800A0279D /* BackgroundTask.swift */; };
 		FCC6885C2489559400A0279D /* blank.wav in Resources */ = {isa = PBXBuildFile; fileRef = FCC6885B2489559400A0279D /* blank.wav */; };
@@ -282,6 +283,7 @@
 		FC9788232485969B00A7906C /* LoopFollow.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LoopFollow.xcdatamodel; sourceTree = "<group>"; };
 		FC9788252485969C00A7906C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		FC9788282485969C00A7906C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+		FCC0FAC124922A22003E610E /* DictionaryKeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryKeyPath.swift; sourceTree = "<group>"; };
 		FCC6884F248935D800A0279D /* AlarmViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlarmViewController.swift; sourceTree = "<group>"; };
 		FCC688592489554800A0279D /* BackgroundTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundTask.swift; sourceTree = "<group>"; };
 		FCC6885B2489559400A0279D /* blank.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = blank.wav; sourceTree = "<group>"; };
@@ -517,6 +519,7 @@
 				FCC6885B2489559400A0279D /* blank.wav */,
 				FCC688592489554800A0279D /* BackgroundTask.swift */,
 				FCFEEC9F2488157B00402A7F /* Chart.swift */,
+				FCC0FAC124922A22003E610E /* DictionaryKeyPath.swift */,
 			);
 			path = helpers;
 			sourceTree = "<group>";
@@ -790,6 +793,7 @@
 				FC7CE598248B0AF2001F83B8 /* AlarmEditing.swift in Sources */,
 				FCC6886524898EEE00A0279D /* UserDefaults.swift in Sources */,
 				FC97881C2485969B00A7906C /* MainViewController.swift in Sources */,
+				FCC0FAC224922A22003E610E /* DictionaryKeyPath.swift in Sources */,
 				FC9788182485969B00A7906C /* AppDelegate.swift in Sources */,
 				FCC6886B24898FD800A0279D /* ObservationToken.swift in Sources */,
 				FCC6886D2489909D00A0279D /* AnyConvertible.swift in Sources */,

+ 18 - 0
LoopFollow.xcworkspace/xcuserdata/jon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -3,4 +3,22 @@
    uuid = "35B1BDC7-1374-42B0-9D79-1E7D694F0434"
    type = "0"
    version = "2.0">
+   <Breakpoints>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "E5424127-C4FD-420C-9081-6A647D9F4465"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "LoopFollow/Controllers/MainViewController.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "665"
+            endingLineNumber = "665"
+            landmarkName = "updateProfile(jsonDeviceStatus:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+   </Breakpoints>
 </Bucket>

+ 4 - 0
LoopFollow/Controllers/AlarmViewController.swift

@@ -258,6 +258,10 @@ class AlarmViewController: FormViewController {
                         row.options = soundFiles
                         row.hidden = "$alertTemporaryActive == false"
                         row.value = UserDefaultsRepository.alertTemporarySound.value
+                        row.displayValueFor = { value in
+                        guard let value = value else { return nil }
+                            return "\(String(value.replacingOccurrences(of: "_", with: " ")))"
+                        }
                     }.onChange { [weak self] row in
                             guard let value = row.value else { return }
                             UserDefaultsRepository.alertTemporarySound.value = value

+ 79 - 1
LoopFollow/Controllers/MainViewController.swift

@@ -36,6 +36,19 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
         var created_at: String
     }
     
+    //NS Basal Profile Struct
+    struct basalProfileStruct: Codable {
+        var value: Double
+        var time: String
+        var timeAsSeconds: Double
+    }
+    
+    //NS Basal Data  Struct
+    struct basalDataStruct: Codable {
+        var value: Double
+        var date: TimeInterval
+    }
+    
     // Data Table Struct
     struct infoData {
         var name: String
@@ -82,6 +95,8 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     ]
     
     var bgData: [sgvData] = []
+    var basalProfile: [basalProfileStruct] = []
+    var basalData: [basalDataStruct] = []
     var predictionData: [Double] = []
     
     var snoozeTabItem: UITabBarItem = UITabBarItem()
@@ -212,13 +227,15 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
             clearLastInfoData()
             loadCage(urlUser: urlUser)
             loadSage(urlUser: urlUser)
+            loadProfile(urlUser: urlUser)
            // loadBoluses(urlUser: urlUser)
            // loadTempBasals(urlUser: urlUser)
         } else {
-            // We're still going to process the Min Ago display and alarm sections without a network call. A snoozer could have expired during since the last call
+            loadDeviceStatus(urlUser: urlUser)
             updateMinAgo()
             clearOldSnoozes()
             checkAlarms(bgs: bgData)
+            loadProfile(urlUser: urlUser)
         }
         
     }
@@ -598,6 +615,67 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
         infoTable.reloadData()
     }
      
+    // Load Current Profile
+    func loadProfile(urlUser: String) {
+        let urlString = urlUser + "/api/v1/profile/current.json"
+        let escapedAddress = urlString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
+        guard let url = URL(string: escapedAddress!) else {
+            return
+        }
+        
+        var request = URLRequest(url: url)
+        request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
+        let task = URLSession.shared.dataTask(with: request) { data, response, error in
+            guard error == nil else {
+                return
+            }
+            guard let data = data else {
+                return
+            }
+            
+            
+            let json = try? JSONSerialization.jsonObject(with: data) as! Dictionary<String, Any>
+            
+            if let json = json {
+                DispatchQueue.main.async {
+                    self.updateProfile(jsonDeviceStatus: json)
+                }
+            } else {
+                return
+            }
+        }
+        task.resume()
+    }
+    
+    // Parse Basal schedule from the profile
+    func updateProfile(jsonDeviceStatus: Dictionary<String, Any>) {
+   
+        if jsonDeviceStatus.count == 0 {
+            return
+        }
+        let basal = jsonDeviceStatus[keyPath: "store.Default.basal"] as! NSArray
+        for i in 0..<basal.count {
+            let dict = basal[i] as! Dictionary<String, Any>
+            let thisValue = dict[keyPath: "value"] as! Double
+            let thisTime = dict[keyPath: "time"] as! String
+            let thisTimeAsSeconds = dict[keyPath: "timeAsSeconds"] as! Double
+            let entry = basalProfileStruct(value: thisValue, time: thisTime, timeAsSeconds: thisTimeAsSeconds)
+            basalProfile.append(entry)
+        }
+        
+    }
+    
+    func createBasalIncrements()
+    {
+        // remove old entries
+        
+        // Get the starting time for first BG entry
+        
+        // cycle through temp basals
+        
+        // if a temp basal doesn't exist, check for the scheduled basal based on time
+    }
+    
     // Need to figure out the date to pull only last 24 hours
     // NOT IMPLEMENTED YET
     func loadTempBasals(urlUser: String) {

+ 1 - 1
LoopFollow/Models/AlarmSound.swift

@@ -98,7 +98,7 @@ class AlarmSound {
             
             // init volume before start playing (mute if fade-in)
             
-            self.audioPlayer!.volume = (self.muted || (self.fadeInTimeInterval.value > 0)) ? 0.0 : 1.0
+            //self.audioPlayer!.volume = (self.muted || (self.fadeInTimeInterval.value > 0)) ? 0.0 : 1.0
             
             if !self.audioPlayer!.prepareToPlay() {
                 NSLog("AlarmSound - audio player failed preparing to play")

+ 45 - 0
LoopFollow/helpers/DictionaryKeyPath.swift

@@ -0,0 +1,45 @@
+// For details, see
+// http://stackoverflow.com/questions/40261857/remove-nested-key-from-dictionary
+import Foundation
+
+extension Dictionary {
+    subscript(keyPath keyPath: String) -> Any? {
+        get {
+            guard let keyPath = Dictionary.keyPathKeys(forKeyPath: keyPath)
+                else { return nil }
+            return getValue(forKeyPath: keyPath)
+        }
+        set {
+            guard let keyPath = Dictionary.keyPathKeys(forKeyPath: keyPath),
+                let newValue = newValue else { return }
+            self.setValue(newValue, forKeyPath: keyPath)
+        }
+    }
+
+    static private func keyPathKeys(forKeyPath: String) -> [Key]? {
+        let keys = forKeyPath.components(separatedBy: ".")
+            .reversed().flatMap({ $0 as? Key })
+        return keys.isEmpty ? nil : keys
+    }
+
+    // recursively (attempt to) access queried subdictionaries
+    // (keyPath will never be empty here; the explicit unwrapping is safe)
+    private func getValue(forKeyPath keyPath: [Key]) -> Any? {
+        guard let value = self[keyPath.last!] else { return nil }
+        return keyPath.count == 1 ? value : (value as? [Key: Any])
+                .flatMap { $0.getValue(forKeyPath: Array(keyPath.dropLast())) }
+    }
+
+    // recursively (attempt to) access the queried subdictionaries to
+    // finally replace the "inner value", given that the key path is valid
+    private mutating func setValue(_ value: Any, forKeyPath keyPath: [Key]) {
+        guard self[keyPath.last!] != nil else { return }
+        if keyPath.count == 1 {
+            (value as? Value).map { self[keyPath.last!] = $0 }
+        }
+        else if var subDict = self[keyPath.last!] as? [Key: Value] {
+            subDict.setValue(value, forKeyPath: Array(keyPath.dropLast()))
+            (subDict as? Value).map { self[keyPath.last!] = $0 }
+        }
+    }
+}