Jon Fawcett пре 6 година
родитељ
комит
6b693d3857

+ 4 - 0
LoopFollow.xcodeproj/project.pbxproj

@@ -151,6 +151,7 @@
 		FCC6886B24898FD800A0279D /* ObservationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6886A24898FD800A0279D /* ObservationToken.swift */; };
 		FCC6886D2489909D00A0279D /* AnyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6886C2489909D00A0279D /* AnyConvertible.swift */; };
 		FCC6886F2489A53800A0279D /* AppConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCC6886E2489A53800A0279D /* AppConstants.swift */; };
+		FCD49B6C24AA536E007879DC /* DebugViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCD49B6B24AA536E007879DC /* DebugViewController.swift */; };
 		FCE537BC249A4D7D00F80BF8 /* carbBolusArrays.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE537BB249A4D7D00F80BF8 /* carbBolusArrays.swift */; };
 		FCEF87AC24A141A700AE6FA0 /* bgUnits.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEF87AA24A1417900AE6FA0 /* bgUnits.swift */; };
 		FCFEEC9E2486E68E00402A7F /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCFEEC9D2486E68E00402A7F /* WebKit.framework */; };
@@ -308,6 +309,7 @@
 		FCC6886C2489909D00A0279D /* AnyConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyConvertible.swift; sourceTree = "<group>"; };
 		FCC6886E2489A53800A0279D /* AppConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppConstants.swift; sourceTree = "<group>"; };
 		FCC688702489A57C00A0279D /* Loop Follow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Loop Follow.entitlements"; sourceTree = "<group>"; };
+		FCD49B6B24AA536E007879DC /* DebugViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugViewController.swift; sourceTree = "<group>"; };
 		FCE537BB249A4D7D00F80BF8 /* carbBolusArrays.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = carbBolusArrays.swift; sourceTree = "<group>"; };
 		FCE537C2249AAB2600F80BF8 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; };
 		FCEF87AA24A1417900AE6FA0 /* bgUnits.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = bgUnits.swift; sourceTree = "<group>"; };
@@ -572,6 +574,7 @@
 			children = (
 				FC97881B2485969B00A7906C /* MainViewController.swift */,
 				FC97881D2485969B00A7906C /* NightScoutViewController.swift */,
+				FCD49B6B24AA536E007879DC /* DebugViewController.swift */,
 				FCFEECA1248857A600402A7F /* SettingsViewController.swift */,
 				FCC6884F248935D800A0279D /* AlarmViewController.swift */,
 				FC7CE59E248D8D23001F83B8 /* SnoozeViewController.swift */,
@@ -840,6 +843,7 @@
 				FCC6886B24898FD800A0279D /* ObservationToken.swift in Sources */,
 				FCC6886D2489909D00A0279D /* AnyConvertible.swift in Sources */,
 				FC97881A2485969B00A7906C /* SceneDelegate.swift in Sources */,
+				FCD49B6C24AA536E007879DC /* DebugViewController.swift in Sources */,
 				FC1BDD2B24A22650001B652C /* Stats.swift in Sources */,
 				FC1BDD2D24A23204001B652C /* StatsView.swift in Sources */,
 				FCE537BC249A4D7D00F80BF8 /* carbBolusArrays.swift in Sources */,

+ 46 - 0
LoopFollow/Application/Base.lproj/Main.storyboard

@@ -431,6 +431,50 @@
             </objects>
             <point key="canvasLocation" x="130" y="700"/>
         </scene>
+        <!--Debug-->
+        <scene sceneID="cZ6-3g-mng">
+            <objects>
+                <viewController id="9r8-3s-tWh" customClass="debugViewController" customModule="Loop_Follow" customModuleProvider="target" sceneMemberID="viewController">
+                    <view key="view" contentMode="scaleToFill" id="7hU-AX-9jB">
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="onDrag" translatesAutoresizingMaskIntoConstraints="NO" id="Ieq-pV-T9Q">
+                                <rect key="frame" x="8" y="52" width="398" height="703"/>
+                                <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                                <color key="textColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" smartDashesType="no" smartInsertDeleteType="no" smartQuotesType="no"/>
+                            </textView>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6PS-rq-xdP">
+                                <rect key="frame" x="147" y="763" width="120" height="30"/>
+                                <state key="normal" title="Clear Log Display"/>
+                                <connections>
+                                    <action selector="clearButton:" destination="9r8-3s-tWh" eventType="touchUpInside" id="Owz-mE-5pP"/>
+                                </connections>
+                            </button>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                        <constraints>
+                            <constraint firstItem="6PS-rq-xdP" firstAttribute="top" secondItem="Ieq-pV-T9Q" secondAttribute="bottom" constant="8" id="BWN-dg-cZc"/>
+                            <constraint firstItem="Ieq-pV-T9Q" firstAttribute="leading" secondItem="aMT-dx-6x9" secondAttribute="leading" constant="8" id="Osu-OU-EnY"/>
+                            <constraint firstItem="aMT-dx-6x9" firstAttribute="bottom" secondItem="6PS-rq-xdP" secondAttribute="bottom" constant="20" id="djl-I0-32Y"/>
+                            <constraint firstItem="aMT-dx-6x9" firstAttribute="trailing" secondItem="Ieq-pV-T9Q" secondAttribute="trailing" constant="8" id="fTv-Gn-qks"/>
+                            <constraint firstItem="Ieq-pV-T9Q" firstAttribute="top" secondItem="aMT-dx-6x9" secondAttribute="top" constant="8" id="ieU-fq-W8U"/>
+                            <constraint firstItem="6PS-rq-xdP" firstAttribute="centerX" secondItem="aMT-dx-6x9" secondAttribute="centerX" id="tMD-fi-wJu"/>
+                        </constraints>
+                        <viewLayoutGuide key="safeArea" id="aMT-dx-6x9"/>
+                    </view>
+                    <tabBarItem key="tabBarItem" title="Debug" image="keyboard" catalog="system" id="wbk-Vr-CKq"/>
+                    <connections>
+                        <outlet property="clearButton" destination="6PS-rq-xdP" id="IFy-5R-qT5"/>
+                        <outlet property="debugLogTextView" destination="Ieq-pV-T9Q" id="HvY-Z3-T2E"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="ccN-WA-Klh" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="973.91304347826099" y="-13.392857142857142"/>
+        </scene>
         <!--Settings-->
         <scene sceneID="ORV-wr-Fd3">
             <objects>
@@ -470,6 +514,7 @@
                         <segue destination="e0E-cx-0Wr" kind="relationship" relationship="viewControllers" id="NKn-DR-nLR"/>
                         <segue destination="8rJ-Kc-sve" kind="relationship" relationship="viewControllers" id="lzU-1b-eKA"/>
                         <segue destination="hDv-qK-Udb" kind="relationship" relationship="viewControllers" id="maf-Gu-a58"/>
+                        <segue destination="9r8-3s-tWh" kind="relationship" relationship="viewControllers" id="Sjn-Lm-tBH"/>
                     </connections>
                 </tabBarController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="HuB-VB-40B" sceneMemberID="firstResponder"/>
@@ -481,6 +526,7 @@
         <image name="alarm" catalog="system" width="124" height="128"/>
         <image name="gear" catalog="system" width="128" height="119"/>
         <image name="house" catalog="system" width="128" height="110"/>
+        <image name="keyboard" catalog="system" width="128" height="70"/>
         <image name="safari" catalog="system" width="128" height="121"/>
         <image name="zzz" catalog="system" width="121" height="128"/>
     </resources>

+ 1 - 1
LoopFollow/Controllers/Alarms.swift

@@ -13,7 +13,7 @@ extension MainViewController {
     
     
     func checkAlarms(bgs: [DataStructs.sgvData]) {
-           print("ALARMS --- Checking")
+           if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Checking Alarms") }
            // Don't check or fire alarms within 1 minute of prior alarm
            if checkAlarmTimer.isValid {  return }
            

+ 2 - 2
LoopFollow/Controllers/Graphs.swift

@@ -231,7 +231,7 @@ extension MainViewController {
         
         // Add Prediction Data
         if predictionData.count > 0 && bgData.count > 0 && UserDefaultsRepository.graphPrediction.value {
-            print("graph prediction")
+            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: print prediction") }
             var startingTime = entries[entries.count - 1].date + 300
             var i = 0
             // Add 1 hour of predictions
@@ -263,7 +263,7 @@ extension MainViewController {
         lineBGSmall.circleColors.removeAll()
 
         if colors.count > 0 {
-            print("graph colors")
+            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Graph: colors") }
             for i in 0..<colors.count{
                 mainChart.addColor(colors[i])
                 mainChart.circleColors.append(colors[i])

+ 30 - 31
LoopFollow/Controllers/NightScout.swift

@@ -97,7 +97,7 @@ extension MainViewController {
             
             
             // Give the alarms and calendar 15 seconds delay to allow time for data to compile
-            print("Start View Timer")
+//            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Start view timer") }
             self.startViewTimer(time: viewTimeInterval)
         } else {
             // Things to do if we already have data and don't need a network call
@@ -120,7 +120,7 @@ extension MainViewController {
     
     // NS BG Data Web call
     func webLoadNSBGData(onlyPullLastRecord: Bool = false) {
-        print("Enter BG Web Call")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: BG") }
         // Set the count= in the url either to pull 24 hours or only the last record
         var points = "1"
         if !onlyPullLastRecord {
@@ -144,7 +144,6 @@ extension MainViewController {
         
         // Downloader
         let getBGTask = URLSession.shared.dataTask(with: request) { data, response, error in
-            if self.consoleLogging == true {print("start bg url")}
             guard error == nil else {
                 return
                 
@@ -172,7 +171,7 @@ extension MainViewController {
     
     // NS BG Data Response processor
     func ProcessNSBGData(data: [DataStructs.sgvData], onlyPullLastRecord: Bool){
-        print("Enter BG Processor")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: BG") }
         
         var pullDate = data[data.count - 1].date / 1000
         pullDate.round(FloatingPointRoundingRule.toNearestOrEven)
@@ -207,7 +206,7 @@ extension MainViewController {
     
     // NS BG Data Front end updater
     func viewUpdateNSBG () {
-        print("Enter BG View Update")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Display: BG") }
         guard let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController else { return }
         let entries = bgData
         if entries.count > 0 {
@@ -264,7 +263,7 @@ extension MainViewController {
     
     // NS Device Status Web Call
     func webLoadNSDeviceStatus() {
-        print("Enter download device status")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: device status") }
         let urlUser = UserDefaultsRepository.url.value
         var urlStringDeviceStatus = urlUser + "/api/v1/devicestatus.json?count=1"
         if token != "" {
@@ -275,7 +274,6 @@ extension MainViewController {
             
             return
         }
-        if consoleLogging == true {print("entered device status task.")}
         
         
         var requestDeviceStatus = URLRequest(url: urlDeviceStatus)
@@ -283,7 +281,6 @@ extension MainViewController {
         
         
         let deviceStatusTask = URLSession.shared.dataTask(with: requestDeviceStatus) { data, response, error in
-            if self.consoleLogging == true {print("in device status loop.")}
             guard error == nil else {
                 return
             }
@@ -299,15 +296,13 @@ extension MainViewController {
                 }
             } else {
                 return
-            }
-            if self.consoleLogging == true {print("finish pump update")}}
+            } }
         deviceStatusTask.resume()
     }
     
     // NS Device Status Response Processor
     func updateDeviceStatusDisplay(jsonDeviceStatus: [[String:AnyObject]]) {
-        print("Enter process device status")
-        if consoleLogging == true {print("in updatePump")}
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: device status") }
         if jsonDeviceStatus.count == 0 {
             return
         }
@@ -343,9 +338,11 @@ extension MainViewController {
                 if let failure = lastLoopRecord["failureReason"] {
                     LoopStatusLabel.text = "X"
                     latestLoopStatusString = "X"
+                    if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Loop Failure: X") }
                 } else {
                     var wasEnacted = false
                     if let enacted = lastLoopRecord["enacted"] as? [String:AnyObject] {
+                        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Loop: Was Enacted") }
                         wasEnacted = true
                         if let lastTempBasal = enacted["rate"] as? Double {
                             // tableData[2].value = String(format:"%.1f", lastTempBasal)
@@ -378,17 +375,23 @@ extension MainViewController {
                             if bgData.count > 0 {
                                 lastBGTime = bgData[bgData.count - 1].date
                             }
+                            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "tempBasalTime: " + String(tempBasalTime)) }
+                            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "lastBGTime: " + String(lastBGTime)) }
+                            if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "wasEnacted: " + String(wasEnacted)) }
                             if tempBasalTime > lastBGTime && !wasEnacted {
                                 LoopStatusLabel.text = "⏀"
                                 latestLoopStatusString = "⏀"
+                                if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Open Loop: recommended temp. temp time > bg time, was not enacted") }
                             } else {
                                 LoopStatusLabel.text = "↻"
                                 latestLoopStatusString = "↻"
+                                if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Looping: recommended temp, but temp time is < bg time and/or was enacted") }
                             }
                         }
                     } else {
                         LoopStatusLabel.text = "↻"
                         latestLoopStatusString = "↻"
+                        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Looping: no recommended temp") }
                     }
                     
                 }
@@ -430,7 +433,7 @@ extension MainViewController {
     
     // NS Cage Web Call
     func webLoadNSCage() {
-        print("enter download cage")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: CAGE") }
         let urlUser = UserDefaultsRepository.url.value
         var urlString = urlUser + "/api/v1/treatments.json?find[eventType]=Site%20Change&count=1"
         if token != "" {
@@ -444,7 +447,6 @@ extension MainViewController {
         request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
         
         let task = URLSession.shared.dataTask(with: request) { data, response, error in
-            if self.consoleLogging == true {print("start cage url")}
             guard error == nil else {
                 return
             }
@@ -467,8 +469,7 @@ extension MainViewController {
     
     // NS Cage Response Processor
     func updateCage(data: [cageData]) {
-        print("enter process cage")
-        if consoleLogging == true {print("in updateCage")}
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: CAGE") }
         if data.count == 0 {
             return
         }
@@ -499,7 +500,7 @@ extension MainViewController {
     
     // NS Sage Web Call
     func webLoadNSSage() {
-        print("enter download sage")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: SAGE") }
         var dayComponent    = DateComponents()
         dayComponent.day    = -10 // For removing 10 days
         let theCalendar     = Calendar.current
@@ -522,7 +523,6 @@ extension MainViewController {
         request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData
         
         let task = URLSession.shared.dataTask(with: request) { data, response, error in
-            if self.consoleLogging == true {print("start cage url")}
             guard error == nil else {
                 return
             }
@@ -545,8 +545,7 @@ extension MainViewController {
     
     // NS Sage Response Processor
     func updateSage(data: [cageData]) {
-        print("enter update sage")
-        if consoleLogging == true {print("in updateSage")}
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process/Display: SAGE") }
         if data.count == 0 {
             return
         }
@@ -577,7 +576,7 @@ extension MainViewController {
     
     // NS Profile Web Call
     func webLoadNSProfile() {
-        print("enter download profile")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: profile") }
         let urlUser = UserDefaultsRepository.url.value
         var urlString = urlUser + "/api/v1/profile/current.json"
         if token != "" {
@@ -615,7 +614,7 @@ extension MainViewController {
     
     // NS Profile Response Processor
     func updateProfile(jsonDeviceStatus: Dictionary<String, Any>) {
-        print("enter process profile")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: profile") }
         if jsonDeviceStatus.count == 0 {
             return
         }
@@ -629,7 +628,7 @@ extension MainViewController {
                 let entry = basalProfileStruct(value: thisValue, time: thisTime, timeAsSeconds: thisTimeAsSeconds)
                 basalProfile.append(entry)
             } catch {
-                print("Error Catch: Profile wrapped in Quotes")
+               if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "ERROR: profile wrapped in quotes") }
             }
             
         }
@@ -637,7 +636,7 @@ extension MainViewController {
     
     // NS Temp Basal Web Call
     func WebLoadNSTempBasals() {
-        print("enter download basals")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: Basal") }
         if !UserDefaultsRepository.downloadBasal.value { return }
         
         let yesterdayString = dateTimeUtils.nowMinus24HoursTimeInterval()
@@ -677,7 +676,7 @@ extension MainViewController {
     
     // NS Temp Basal Response Processor
     func updateBasals(entries: [[String:AnyObject]]) {
-        print("enter process basal")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: Basal") }
         // due to temp basal durations, we're going to destroy the array and load everything each cycle for the time being.
         basalData.removeAll()
         
@@ -829,7 +828,7 @@ extension MainViewController {
     
     // NS Bolus Web Call
     func webLoadNSBoluses(){
-        print("enter download bolus")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: Bolus") }
         if !UserDefaultsRepository.downloadBolus.value { return }
         let yesterdayString = dateTimeUtils.nowMinus24HoursTimeInterval()
         let urlUser = UserDefaultsRepository.url.value
@@ -870,7 +869,7 @@ extension MainViewController {
     
     // NS Meal Bolus Response Processor
     func processNSBolus(entries: [[String:AnyObject]]) {
-        print("enter process bolus")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: Bolus") }
         // because it's a small array, we're going to destroy and reload every time.
         bolusData.removeAll()
         var lastFoundIndex = 0
@@ -903,7 +902,7 @@ extension MainViewController {
                     bolusData.append(dot)
                 }
             } catch {
-                print("Null Bolus Warning")
+                if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "ERROR: Null Bolus") }
             }
             
            
@@ -919,7 +918,7 @@ extension MainViewController {
     
     // NS Carb Web Call
     func webLoadNSCarbs(){
-        print("enter download carbs")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Download: Carbs") }
         if !UserDefaultsRepository.downloadCarbs.value { return }
         let yesterdayString = dateTimeUtils.nowMinus24HoursTimeInterval()
         let urlUser = UserDefaultsRepository.url.value
@@ -960,7 +959,7 @@ extension MainViewController {
     
     // NS Carb Bolus Response Processor
     func processNSCarbs(entries: [[String:AnyObject]]) {
-        print("enter process carbs")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Process: Carbs") }
         // because it's a small array, we're going to destroy and reload every time.
         carbData.removeAll()
         var lastFoundIndex = 0
@@ -993,7 +992,7 @@ extension MainViewController {
                     carbData.append(dot)
                 }
             } catch {
-                print("Null Carb Warning")
+                if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "ERROR: Null Carb entry") }
             }
             
             

+ 29 - 0
LoopFollow/ViewControllers/DebugViewController.swift

@@ -0,0 +1,29 @@
+//
+//  DebugViewController.swift
+//  LoopFollow
+//
+//  Created by Jon Fawcett on 6/29/20.
+//  Copyright © 2020 Jon Fawcett. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+class debugViewController: UIViewController {
+    
+    @IBOutlet weak var debugLogTextView: UITextView!
+    @IBOutlet weak var clearButton: UIButton!
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        debugLogTextView.isEditable = false
+
+    }
+    
+    @IBAction func clearButton(_ sender: Any) {
+        
+        self.debugLogTextView.text = ""
+    }
+    
+    
+}

+ 45 - 38
LoopFollow/ViewControllers/MainViewController.swift

@@ -32,7 +32,6 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     @IBOutlet weak var statsEstA1C: UILabel!
     
     
-    
     // Data Table Struct
     struct infoData {
         var name: String
@@ -112,6 +111,18 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     override func viewDidLoad() {
         super.viewDidLoad()
         
+        // Start Log Timer if needed
+        if UserDefaultsRepository.debugLog.value {
+            guard let debug = self.tabBarController!.viewControllers?[5] as? debugViewController else { return }
+            debug.loadViewIfNeeded()
+        } else {
+            do {
+                try self.tabBarController?.viewControllers?.remove(at: 5)
+            } catch {
+                
+            }
+        }
+        
         BGChart.delegate = self
         BGChartFull.delegate = self
         
@@ -213,27 +224,27 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     
     // Nothing should be done when this timer ends because it just blocks the alarms from firing when it's active
     @objc func calTimerDidEnd(_ timer:Timer) {
-        if UserDefaultsRepository.sendNotificationLog.value { self.sendNotification(self, text: "Calendar Timer Ended") }
-        print("cal timer ended")
+       // if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Calendar Timer Ended") }
     }
     
     // This delays a few things to hopefully all all data to arrive.
-       @objc func viewTimerDidEnd(_ timer:Timer) {
-        print(dateTimeUtils.printNow() + "view timer ended")
+    @objc func viewTimerDidEnd(_ timer:Timer) {
+//        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "View timer ended") }
         if bgData.count > 0 {
-                self.checkAlarms(bgs: bgData)
-                self.updateMinAgo()
-                // self.updateBadge(val: bgData[bgData.count - 1].sgv)
-               //self.viewUpdateNSBG()
-               if UserDefaultsRepository.writeCalendarEvent.value {
-                   self.writeCalendar()
-               }
-           }
-       }
+            self.checkAlarms(bgs: bgData)
+            self.updateMinAgo()
+            // self.updateBadge(val: bgData[bgData.count - 1].sgv)
+            //self.viewUpdateNSBG()
+            if UserDefaultsRepository.writeCalendarEvent.value {
+                self.writeCalendar()
+            }
+        }
+    }
+    
     
     // Nothing should be done when this timer ends because it just blocks the alarms from firing when it's active
     @objc func checkAlarmTimerDidEnd(_ timer:Timer) {
-        print("check alarm timer ended")
+//        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Check alarm timer ended") }
     }
     
     @objc func appMovedToBackground() {
@@ -270,13 +281,14 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     
     // Check for new data when timer ends
     @objc func timerDidEnd(_ timer:Timer) {
-        print(dateTimeUtils.printNow() + " " + "main timer ended " + "\(Thread.current)")
+//        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Main timer ended") }
         updateMinAgo()
         nightscoutLoader()
     }
 
     //update Min Ago Text. We need to call this separately because it updates between readings
     func updateMinAgo(){
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Update min ago text") }
         guard let snoozer = self.tabBarController!.viewControllers?[2] as? SnoozeViewController else { return }
         if bgData.count > 0 {
             let deltaTime = (TimeInterval(Date().timeIntervalSince1970)-bgData[bgData.count - 1].date) / 60
@@ -315,7 +327,7 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
         } else {
             UIApplication.shared.applicationIconBadgeNumber = 0
         }
-        print("updated badge")
+//        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "updated badge") }
     }
     
     
@@ -349,14 +361,14 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
     
     // Write calendar
     func writeCalendar() {
-        print(dateTimeUtils.printNow() + " " + "write calendar start " + "\(Thread.current)")
+        if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Write calendar start") }
         store.requestAccess(to: .event) {(granted, error) in
             if !granted { return }
             
             if UserDefaultsRepository.calendarIdentifier.value == "" { return }
                 
             if self.lastCalDate == self.bgData[self.bgData.count - 1].date && self.calTimer.isValid {
-                    if UserDefaultsRepository.sendNotificationLog.value { self.sendNotification(self, text: "Calendar - Not saving same entry") }
+//                    if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Calendar - Not saving same entry") }
                     return }
                 
                 // Create Event info
@@ -373,7 +385,7 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
                 let direction = self.bgDirectionGraphic(self.bgData[self.bgData.count - 1].direction ?? "")
                 
                 var eventStartDate = Date(timeIntervalSince1970: self.bgData[self.bgData.count - 1].date)
-                print(eventStartDate)
+//                if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Calendar start date") }
                 var eventEndDate = eventStartDate.addingTimeInterval(60 * 10)
                 var  eventTitle = UserDefaultsRepository.watchLine1.value + "\n" + UserDefaultsRepository.watchLine2.value
                 eventTitle = eventTitle.replacingOccurrences(of: "%BG%", with: bgUnits.toDisplayUnits(String(self.bgData[self.bgData.count - 1].sgv)))
@@ -423,10 +435,9 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
                     for i in eVDelete! {
                         do {
                             try self.store.remove(i, span: EKSpan.thisEvent, commit: true)
-                            if UserDefaultsRepository.sendNotificationLog.value { self.sendNotification(self, text: "Calendar Delete") }
+                            //if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Calendar Delete") }
                         } catch let error {
-                            print("ERROR -- Delete calendar entry")
-                            if UserDefaultsRepository.sendNotificationLog.value { self.sendNotification(self, text: "Error - Calendar Delete") }
+                            //if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Error - Calendar Delete") }
                             print(error)
                         }
                     }
@@ -443,13 +454,11 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
                     self.lastCalDate = self.bgData[self.bgData.count - 1].date
                     self.calTimer.invalidate()
                     self.startCalTimer(time: (60 * 5))
-                    if UserDefaultsRepository.sendNotificationLog.value { self.sendNotification(self, text: "Calendar Write: " + eventTitle) }
+                    //if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Calendar Write: " + eventTitle) }
                     //UserDefaultsRepository.savedEventID.value = event.eventIdentifier //save event id to access this particular event later
                 } catch {
                     // Display error to user
-                    if UserDefaultsRepository.sendNotificationLog.value { self.sendNotification(self, text: "Error - Calendar Write") }
-                    print("ERROR - add calendar entry")
-                    print(error)
+                    //if UserDefaultsRepository.debugLog.value { self.writeDebugLog(value: "Error: Calendar Write") }
                 }
             
         }
@@ -464,18 +473,16 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
         }
     }
     
-    func sendNotification(_ sender: Any, text: String) {
-        
-        UNUserNotificationCenter.current().delegate = self
-        
-        let content = UNMutableNotificationContent()
-        content.title = dateTimeUtils.printNow()
-        content.title += " - " + text
-        
-        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
-        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
-        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
+    func writeDebugLog(value: String) {
+        guard let debug = self.tabBarController!.viewControllers?[5] as? debugViewController else { return }
+        var logText = "\n" + dateTimeUtils.printNow() + " - " + value
+        print(logText)
+        if debug.debugLogTextView.text.lengthOfBytes(using: .utf8) > 1000 {
+            debug.debugLogTextView.text = ""
+        }
+        debug.debugLogTextView.text += logText
     }
     
+    
 }
 

+ 4 - 5
LoopFollow/ViewControllers/SettingsViewController.swift

@@ -412,14 +412,13 @@ class SettingsViewController: FormViewController {
                     guard let value = row.value else { return }
                     UserDefaultsRepository.graphPrediction.value = value
             }
-            <<< SwitchRow("sendNotificationLog"){ row in
-                row.title = "iPhone Notifications for Logs"
-                row.value = UserDefaultsRepository.sendNotificationLog.value
+            <<< SwitchRow("debugLog"){ row in
+                row.title = "Show Debug Log"
+                row.value = UserDefaultsRepository.debugLog.value
             }.onChange { [weak self] row in
                         guard let value = row.value else { return }
-                        UserDefaultsRepository.sendNotificationLog.value = value
+                        UserDefaultsRepository.debugLog.value = value
                 }
-        
         <<< StepperRow("viewRefreshDelay") { row in
             row.title = "View Refresh Delay"
             row.cell.stepper.stepValue = 1

+ 1 - 1
LoopFollow/repository/UserDefaults.swift

@@ -52,7 +52,7 @@ class UserDefaultsRepository {
         static let graphBolus = UserDefaultsValue<Bool>(key: "graphBolus", default: true)
         static let graphCarbs = UserDefaultsValue<Bool>(key: "graphCarbs", default: true)
         static let graphPrediction = UserDefaultsValue<Bool>(key: "graphPrediction", default: true)
-        static let sendNotificationLog = UserDefaultsValue<Bool>(key: "sendNotificationLog", default: false)
+        static let debugLog = UserDefaultsValue<Bool>(key: "debugLog", default: false)
         static let viewRefreshDelay = UserDefaultsValue<Double>(key: "viewRefreshDelay", default: 15.0)