فهرست منبع

Data migration

Jonas Björkert 1 سال پیش
والد
کامیت
0b118befd6

+ 1 - 1
LoopFollow/Controllers/Nightscout/DeviceStatusLoop.swift

@@ -9,7 +9,7 @@ import UIKit
 
 extension MainViewController {
     func DeviceStatusLoop(formatter: ISO8601DateFormatter, lastLoopRecord: [String: AnyObject]) {
-        ObservableUserDefaults.shared.device.value = "Loop"
+        Storage.shared.device.value = "Loop"
 
         if Storage.shared.remoteType.value == .trc {
             Storage.shared.remoteType.value = .none

+ 1 - 1
LoopFollow/Controllers/Nightscout/DeviceStatusOpenAPS.swift

@@ -8,7 +8,7 @@ import UIKit
 
 extension MainViewController {
     func DeviceStatusOpenAPS(formatter: ISO8601DateFormatter, lastDeviceStatus: [String: AnyObject]?, lastLoopRecord: [String: AnyObject]) {
-        ObservableUserDefaults.shared.device.value = lastDeviceStatus?["device"] as? String ?? ""
+        Storage.shared.device.value = lastDeviceStatus?["device"] as? String ?? ""
         if lastLoopRecord["failureReason"] != nil {
             LoopStatusLabel.text = "X"
             latestLoopStatusString = "X"

+ 1 - 1
LoopFollow/Controllers/Nightscout/Treatments/Overrides.swift

@@ -72,7 +72,7 @@ extension MainViewController {
         }
 
         Observable.shared.override.value = activeOverrideNote
-        if ObservableUserDefaults.shared.device.value == "Trio" {
+        if Storage.shared.device.value == "Trio" {
             if let note = activeOverrideNote {
                 infoManager.updateInfoData(type: .override, value: note)
             } else {

+ 6 - 6
LoopFollow/Helpers/NightscoutUtils.swift

@@ -63,7 +63,7 @@ class NightscoutUtils {
     }
 
     static func executeRequest<T: Decodable>(eventType: EventType, parameters: [String: String], completion: @escaping (Result<T, Error>) -> Void) {
-        let baseURL = ObservableUserDefaults.shared.url.value
+        let baseURL = Storage.shared.url.value
         let token = Storage.shared.token.value
 
         guard let url = NightscoutUtils.constructURL(baseURL: baseURL, token: token, endpoint: eventType.endpoint, parameters: parameters) else {
@@ -113,7 +113,7 @@ class NightscoutUtils {
     }
 
     static func executeDynamicRequest(eventType: EventType, parameters: [String: String], completion: @escaping (Result<Any, Error>) -> Void) {
-        let baseURL = ObservableUserDefaults.shared.url.value
+        let baseURL = Storage.shared.url.value
         let token = Storage.shared.token.value
 
         guard let url = NightscoutUtils.constructURL(baseURL: baseURL, token: token, endpoint: eventType.endpoint, parameters: parameters) else {
@@ -186,7 +186,7 @@ class NightscoutUtils {
     }
 
     static func verifyURLAndToken(completion: @escaping (NightscoutError?, String?, Bool, Bool) -> Void) {
-        let urlUser = ObservableUserDefaults.shared.url.value
+        let urlUser = Storage.shared.url.value
         let token = Storage.shared.token.value
 
         if urlUser.isEmpty {
@@ -284,7 +284,7 @@ class NightscoutUtils {
     }
 
     static func retrieveJWTToken() async throws -> String {
-        let urlUser = ObservableUserDefaults.shared.url.value
+        let urlUser = Storage.shared.url.value
         let token = Storage.shared.token.value
 
         if urlUser.isEmpty {
@@ -327,7 +327,7 @@ class NightscoutUtils {
 
     static func executePostRequest<T: Decodable>(eventType: EventType, body: [String: Any]) async throws -> T {
         let jwtToken = try await retrieveJWTToken()
-        let baseURL = ObservableUserDefaults.shared.url.value
+        let baseURL = Storage.shared.url.value
 
         guard let url = URL(string: "\(baseURL)\(eventType.endpoint)") else {
             throw NightscoutError.invalidURL
@@ -357,7 +357,7 @@ class NightscoutUtils {
 
     static func executePostRequest(eventType: EventType, body: [String: Any]) async throws -> String {
         let jwtToken = try await retrieveJWTToken()
-        let baseURL = ObservableUserDefaults.shared.url.value
+        let baseURL = Storage.shared.url.value
 
         guard let url = URL(string: "\(baseURL)\(eventType.endpoint)") else {
             throw NightscoutError.invalidURL

+ 7 - 7
LoopFollow/Nightscout/NightscoutSettingsViewModel.swift

@@ -15,10 +15,10 @@ class NightscoutSettingsViewModel: ObservableObject {
     private var initialURL: String
     private var initialToken: String
 
-    @Published var nightscoutURL: String = ObservableUserDefaults.shared.url.value {
+    @Published var nightscoutURL: String = Storage.shared.url.value {
         willSet {
             if newValue != nightscoutURL {
-                ObservableUserDefaults.shared.url.value = newValue
+                Storage.shared.url.value = newValue
                 triggerCheckStatus()
             }
         }
@@ -40,7 +40,7 @@ class NightscoutSettingsViewModel: ObservableObject {
     private var checkStatusWorkItem: DispatchWorkItem?
 
     init() {
-        initialURL = ObservableUserDefaults.shared.url.value
+        initialURL = Storage.shared.url.value
         initialToken = Storage.shared.token.value
 
         setupDebounce()
@@ -98,8 +98,8 @@ class NightscoutSettingsViewModel: ObservableObject {
     func checkNightscoutStatus() {
         NightscoutUtils.verifyURLAndToken { error, _, nsWriteAuth, nsAdminAuth in
             DispatchQueue.main.async {
-                ObservableUserDefaults.shared.nsWriteAuth.value = nsWriteAuth
-                ObservableUserDefaults.shared.nsAdminAuth.value = nsAdminAuth
+                Storage.shared.nsWriteAuth.value = nsWriteAuth
+                Storage.shared.nsAdminAuth.value = nsAdminAuth
 
                 self.updateStatusLabel(error: error)
             }
@@ -126,10 +126,10 @@ class NightscoutSettingsViewModel: ObservableObject {
             }
         } else {
             let authStatus: String
-            if ObservableUserDefaults.shared.nsAdminAuth.value {
+            if Storage.shared.nsAdminAuth.value {
                 authStatus = "Admin"
             } else {
-                authStatus = "Read" + (ObservableUserDefaults.shared.nsWriteAuth.value ? " & Write" : "")
+                authStatus = "Read" + (Storage.shared.nsWriteAuth.value ? " & Write" : "")
             }
 
             nightscoutStatus = "OK (\(authStatus))"

+ 1 - 1
LoopFollow/Remote/Loop/LoopNightscoutRemoteView.swift

@@ -6,7 +6,7 @@ import SwiftUI
 
 struct LoopNightscoutRemoteView: View {
     @Environment(\.presentationMode) var presentationMode
-    @ObservedObject var nsAdmin = ObservableUserDefaults.shared.nsWriteAuth
+    @ObservedObject var nsAdmin = Storage.shared.nsWriteAuth
 
     var body: some View {
         NavigationView {

+ 2 - 2
LoopFollow/Remote/Loop/LoopOverrideView.swift

@@ -8,9 +8,9 @@ import SwiftUI
 struct LoopOverrideView: View {
     @Environment(\.presentationMode) private var presentationMode
 
-    @ObservedObject var device = ObservableUserDefaults.shared.device
+    @ObservedObject var device = Storage.shared.device
     @ObservedObject var overrideNote = Observable.shared.override
-    @ObservedObject var nsAdmin = ObservableUserDefaults.shared.nsWriteAuth
+    @ObservedObject var nsAdmin = Storage.shared.nsWriteAuth
 
     @StateObject private var viewModel = LoopOverrideViewModel()
 

+ 3 - 3
LoopFollow/Remote/Nightscout/TrioNightscoutRemoteView.swift

@@ -8,9 +8,9 @@ import SwiftUI
 struct TrioNightscoutRemoteView: View {
     private let remoteController = TrioNightscoutRemoteController()
 
-    @ObservedObject var nightscoutURL = ObservableUserDefaults.shared.url
-    @ObservedObject var device = ObservableUserDefaults.shared.device
-    @ObservedObject var nsWriteAuth = ObservableUserDefaults.shared.nsWriteAuth
+    @ObservedObject var nightscoutURL = Storage.shared.url
+    @ObservedObject var device = Storage.shared.device
+    @ObservedObject var nsWriteAuth = Storage.shared.nsWriteAuth
     @ObservedObject var tempTarget = Observable.shared.tempTarget
 
     @State private var newHKTarget = HKQuantity(unit: .milligramsPerDeciliter, doubleValue: 0.0)

+ 6 - 6
LoopFollow/Remote/RemoteViewController.swift

@@ -17,7 +17,7 @@ class RemoteViewController: UIViewController {
 
         cancellable = Publishers.CombineLatest(
             Storage.shared.remoteType.$value,
-            ObservableUserDefaults.shared.device.$value
+            Storage.shared.device.$value
         )
         .sink { [weak self] _, _ in
             DispatchQueue.main.async {
@@ -40,7 +40,7 @@ class RemoteViewController: UIViewController {
         if remoteType == .nightscout {
             var remoteView: AnyView
 
-            switch ObservableUserDefaults.shared.device.value {
+            switch Storage.shared.device.value {
             case "Trio":
                 remoteView = AnyView(TrioNightscoutRemoteView())
             case "Loop":
@@ -51,7 +51,7 @@ class RemoteViewController: UIViewController {
 
             hostingController = UIHostingController(rootView: remoteView)
         } else if remoteType == .trc {
-            if ObservableUserDefaults.shared.device.value != "Trio" {
+            if Storage.shared.device.value != "Trio" {
                 hostingController = UIHostingController(
                     rootView: AnyView(
                         Text("Trio Remote Control is only supported for 'Trio'")
@@ -81,11 +81,11 @@ class RemoteViewController: UIViewController {
             hostingController.didMove(toParent: self)
         }
 
-        if remoteType == .nightscout, !ObservableUserDefaults.shared.nsWriteAuth.value {
+        if remoteType == .nightscout, !Storage.shared.nsWriteAuth.value {
             NightscoutUtils.verifyURLAndToken { _, _, nsWriteAuth, nsAdminAuth in
                 DispatchQueue.main.async {
-                    ObservableUserDefaults.shared.nsWriteAuth.value = nsWriteAuth
-                    ObservableUserDefaults.shared.nsAdminAuth.value = nsAdminAuth
+                    Storage.shared.nsWriteAuth.value = nsWriteAuth
+                    Storage.shared.nsAdminAuth.value = nsAdminAuth
                 }
             }
         }

+ 2 - 2
LoopFollow/Remote/Settings/RemoteSettingsViewModel.swift

@@ -19,7 +19,7 @@ class RemoteSettingsViewModel: ObservableObject {
     @Published var maxFat: HKQuantity
     @Published var mealWithBolus: Bool
     @Published var mealWithFatProtein: Bool
-    @Published var isTrioDevice: Bool = (ObservableUserDefaults.shared.device.value == "Trio")
+    @Published var isTrioDevice: Bool = (Storage.shared.device.value == "Trio")
 
     private var storage = Storage.shared
     private var cancellables = Set<AnyCancellable>()
@@ -85,7 +85,7 @@ class RemoteSettingsViewModel: ObservableObject {
             .sink { [weak self] in self?.storage.mealWithFatProtein.value = $0 }
             .store(in: &cancellables)
 
-        ObservableUserDefaults.shared.device.$value
+        Storage.shared.device.$value
             .receive(on: DispatchQueue.main)
             .sink { [weak self] newValue in
                 self?.isTrioDevice = (newValue == "Trio")

+ 1 - 1
LoopFollow/Remote/TRC/OverrideView.swift

@@ -9,7 +9,7 @@ struct OverrideView: View {
     @Environment(\.presentationMode) private var presentationMode
     private let pushNotificationManager = PushNotificationManager()
 
-    @ObservedObject var device = ObservableUserDefaults.shared.device
+    @ObservedObject var device = Storage.shared.device
     @ObservedObject var overrideNote = Observable.shared.override
 
     @State private var showAlert: Bool = false

+ 1 - 1
LoopFollow/Remote/TRC/TempTargetView.swift

@@ -9,7 +9,7 @@ struct TempTargetView: View {
     @Environment(\.presentationMode) private var presentationMode
     private let pushNotificationManager = PushNotificationManager()
 
-    @ObservedObject var device = ObservableUserDefaults.shared.device
+    @ObservedObject var device = Storage.shared.device
     @ObservedObject var tempTarget = Observable.shared.tempTarget
 
     @State private var newHKTarget = HKQuantity(unit: .milligramsPerDeciliter, doubleValue: 0.0)

+ 4 - 4
LoopFollow/Storage/ObservableUserDefaults.swift

@@ -12,10 +12,10 @@ import Foundation
 class ObservableUserDefaults {
     static let shared = ObservableUserDefaults()
 
-    var url = ObservableUserDefaultsValue<String>(key: "url", default: "")
-    var device = ObservableUserDefaultsValue<String>(key: "device", default: "")
-    var nsWriteAuth = ObservableUserDefaultsValue<Bool>(key: "nsWriteAuth", default: false)
-    var nsAdminAuth = ObservableUserDefaultsValue<Bool>(key: "nsAdminAuth", default: false)
+    var old_url = ObservableUserDefaultsValue<String>(key: "url", default: "")
+    var old_device = ObservableUserDefaultsValue<String>(key: "device", default: "")
+    var old_nsWriteAuth = ObservableUserDefaultsValue<Bool>(key: "nsWriteAuth", default: false)
+    var old_nsAdminAuth = ObservableUserDefaultsValue<Bool>(key: "nsAdminAuth", default: false)
 
     private init() {}
 }

+ 6 - 1
LoopFollow/Storage/Storage+Migrate.swift

@@ -5,7 +5,12 @@
 import Foundation
 
 extension Storage {
-    func migrate() {
+    func migrateStep1() {
+        Storage.shared.url.value = ObservableUserDefaults.shared.old_url.value
+        Storage.shared.device.value = ObservableUserDefaults.shared.old_device.value
+        Storage.shared.nsWriteAuth.value = ObservableUserDefaults.shared.old_nsWriteAuth.value
+        Storage.shared.nsAdminAuth.value = ObservableUserDefaults.shared.old_nsAdminAuth.value
+
         // Helper: 1-to-1 type -----------------------------------------------------------------
         func move<T: AnyConvertible & Equatable>(
             _ legacy: @autoclosure () -> UserDefaultsValue<T>,

+ 7 - 0
LoopFollow/Storage/Storage.swift

@@ -149,6 +149,13 @@ class Storage {
     var infoSort = StorageValue<[Int]>(key: "infoSort", defaultValue: InfoType.allCases.map { $0.sortOrder })
     var infoVisible = StorageValue<[Bool]>(key: "infoVisible", defaultValue: InfoType.allCases.map { $0.defaultVisible })
 
+    var url = StorageValue<String>(key: "url", defaultValue: "")
+    var device = StorageValue<String>(key: "device", defaultValue: "")
+    var nsWriteAuth = StorageValue<Bool>(key: "nsWriteAuth", defaultValue: false)
+    var nsAdminAuth = StorageValue<Bool>(key: "nsAdminAuth", defaultValue: false)
+
+    var migrationStep = StorageValue<Int>(key: "migrationStep", defaultValue: 0)
+
     static let shared = Storage()
     private init() {}
 }

+ 5 - 6
LoopFollow/ViewControllers/MainViewController.swift

@@ -13,7 +13,7 @@ import UIKit
 import UserNotifications
 
 func IsNightscoutEnabled() -> Bool {
-    return !ObservableUserDefaults.shared.url.value.isEmpty
+    return !Storage.shared.url.value.isEmpty
 }
 
 class MainViewController: UIViewController, UITableViewDataSource, ChartViewDelegate, UNUserNotificationCenterDelegate, UIScrollViewDelegate {
@@ -119,12 +119,11 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
 
         loadDebugData()
 
-        if ObservableUserDefaults.shared.device.value != "Trio" && Storage.shared.remoteType.value == .trc {
-            Storage.shared.remoteType.value = .none
+        if Storage.shared.migrationStep.value < 1 {
+            Storage.shared.migrateStep1()
+            Storage.shared.migrationStep.value = 1
         }
 
-        Storage.shared.migrate()
-
         // Synchronize info types to ensure arrays are the correct size
         synchronizeInfoTypes()
 
@@ -702,7 +701,7 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele
                 }
 
                 if let url = debugData.url {
-                    ObservableUserDefaults.shared.url.value = url
+                    Storage.shared.url.value = url
                 }
 
                 if let token = debugData.token {

+ 1 - 1
LoopFollow/ViewControllers/NightScoutViewController.swift

@@ -14,7 +14,7 @@ class NightscoutViewController: UIViewController {
             overrideUserInterfaceStyle = .dark
         }
 
-        var url = ObservableUserDefaults.shared.url.value
+        var url = Storage.shared.url.value
         let token = Storage.shared.token.value
 
         if token != "" {