Преглед изворни кода

rewrite unlockmanager by @andreas, refactor to use async syntax

polscm32 пре 2 година
родитељ
комит
e218317d45

+ 11 - 7
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -233,7 +233,7 @@ extension Bolus {
                 .roundBolus(amount: max(insulinCalculated, 0))
         }
 
-        func add() {
+        func add() async {
             guard amount > 0 else {
                 showModal(for: nil)
                 return
@@ -241,13 +241,17 @@ extension Bolus {
 
             let maxAmount = Double(min(amount, provider.pumpSettings().maxBolus))
 
-            unlockmanager.unlock()
-                .sink { _ in } receiveValue: { [weak self] _ in
-                    guard let self = self else { return }
-                    self.apsManager.enactBolus(amount: maxAmount, isSMB: false)
-                    self.showModal(for: nil)
+            do {
+                let authenticated = try await unlockmanager.unlock()
+                if authenticated {
+                    apsManager.enactBolus(amount: maxAmount, isSMB: false)
+                    showModal(for: nil)
+                } else {
+                    print("authentication failed")
                 }
-                .store(in: &lifetime)
+            } catch {
+                print("authentication error: \(error.localizedDescription)")
+            }
         }
 
         func setupInsulinRequired() {

+ 6 - 3
FreeAPS/Sources/Modules/Bolus/View/AlternativeBolusCalcRootView.swift

@@ -434,10 +434,13 @@ extension Bolus {
                 if state.amount > 0 {
                     Section {
                         Button {
-                            state.add()
-                            state.hideModal()
-                            state.addCarbs()
+                            Task {
+                                await state.add()
+                                state.hideModal()
+                                state.addCarbs()
+                            }
                         }
+
                         label: { Text(exceededMaxBolus ? "Max Bolus exceeded!" : "Enact bolus") }
                             .frame(maxWidth: .infinity, alignment: .center)
                             .disabled(disabled)

+ 5 - 3
FreeAPS/Sources/Modules/Bolus/View/DefaultBolusCalcRootView.swift

@@ -117,9 +117,11 @@ extension Bolus {
                 if state.amount > 0 {
                     Section {
                         Button {
-                            keepForNextWiew = true
-                            state.add()
-                            state.hideModal()
+                            Task {
+                                await state.add()
+                                state.hideModal()
+                                keepForNextWiew = true
+                            }
                         }
                         label: { Text(!(state.amount > state.maxBolus) ? "Enact bolus" : "Max Bolus exceeded!") }
                             .frame(maxWidth: .infinity, alignment: .center)

+ 44 - 31
FreeAPS/Sources/Modules/DataTable/DataTableStateModel.swift

@@ -160,13 +160,17 @@ extension DataTable {
             provider.deleteCarbs(treatment)
         }
 
-        func deleteInsulin(_ treatment: Treatment) {
-            unlockmanager.unlock()
-                .sink { _ in } receiveValue: { [weak self] _ in
-                    guard let self = self else { return }
-                    self.provider.deleteInsulin(treatment)
+        func deleteInsulin(_ treatment: Treatment) async {
+            do {
+                let authenticated = try await unlockmanager.unlock()
+                if authenticated {
+                    provider.deleteInsulin(treatment)
+                } else {
+                    print("authentication failed")
                 }
-                .store(in: &lifetime)
+            } catch {
+                print("authentication error: \(error.localizedDescription)")
+            }
         }
 
         func deleteGlucose(_ glucose: Glucose) {
@@ -219,38 +223,47 @@ extension DataTable {
             saveToHealth.append(saveToJSON)
         }
 
-        func addExternalInsulin() {
+        func addExternalInsulin() async {
             guard externalInsulinAmount > 0 else {
                 showModal(for: nil)
                 return
             }
 
-            externalInsulinAmount = min(externalInsulinAmount, maxBolus * 3) // Allow for 3 * Max Bolus for external insulin
-            unlockmanager.unlock()
-                .sink { _ in } receiveValue: { [weak self] _ in
-                    guard let self = self else { return }
-                    pumpHistoryStorage.storeEvents(
-                        [
-                            PumpHistoryEvent(
-                                id: UUID().uuidString,
-                                type: .bolus,
-                                timestamp: externalInsulinDate,
-                                amount: externalInsulinAmount,
-                                duration: nil,
-                                durationMin: nil,
-                                rate: nil,
-                                temp: nil,
-                                carbInput: nil,
-                                isExternal: true
-                            )
-                        ]
-                    )
-                    debug(.default, "External insulin saved to pumphistory.json")
+            externalInsulinAmount = min(externalInsulinAmount, maxBolus * 3)
 
-                    // Reset amount to 0 for next entry.
-                    externalInsulinAmount = 0
+            do {
+                let authenticated = try await unlockmanager.unlock()
+                if authenticated {
+                    storeExternalInsulinEvent()
+                } else {
+                    print("authentication failed")
                 }
-                .store(in: &lifetime)
+            } catch {
+                print("authentication error: \(error.localizedDescription)")
+            }
+        }
+
+        private func storeExternalInsulinEvent() {
+            pumpHistoryStorage.storeEvents(
+                [
+                    PumpHistoryEvent(
+                        id: UUID().uuidString,
+                        type: .bolus,
+                        timestamp: externalInsulinDate,
+                        amount: externalInsulinAmount,
+                        duration: nil,
+                        durationMin: nil,
+                        rate: nil,
+                        temp: nil,
+                        carbInput: nil,
+                        isExternal: true
+                    )
+                ]
+            )
+            debug(.default, "External insulin saved to pumphistory.json")
+
+            // Reset amount to 0 for next entry.
+            externalInsulinAmount = 0
         }
     }
 }

+ 13 - 6
FreeAPS/Sources/Modules/DataTable/View/DataTableRootView.swift

@@ -322,7 +322,11 @@ extension DataTable {
                     if state.historyLayout == .twoTabs, treatmentToDelete.type == .carbs || treatmentToDelete.type == .fpus {
                         state.deleteCarbs(treatmentToDelete)
                     } else {
-                        state.deleteInsulin(treatmentToDelete)
+                        Task {
+                            do {
+                                await state.deleteInsulin(treatmentToDelete)
+                            }
+                        }
                     }
                 }
             } message: {
@@ -434,11 +438,14 @@ extension DataTable {
                         Section {
                             HStack {
                                 Button {
-                                    state.addExternalInsulin()
-                                    isAmountUnconfirmed = false
-                                    showExternalInsulin = false
-                                }
-                                label: {
+                                    Task {
+                                        do {
+                                            await state.addExternalInsulin()
+                                            isAmountUnconfirmed = false
+                                            showExternalInsulin = false
+                                        }
+                                    }
+                                } label: {
                                     Text("Log external insulin")
                                 }
                                 .foregroundStyle(foregroundColor)

+ 9 - 25
FreeAPS/Sources/Services/UnlockManager/UnlockManager.swift

@@ -2,7 +2,7 @@ import Combine
 import LocalAuthentication
 
 protocol UnlockManager {
-    func unlock() -> AnyPublisher<Void, Error>
+    func unlock() async throws -> Bool
 }
 
 struct UnlockError: Error {
@@ -10,31 +10,15 @@ struct UnlockError: Error {
 }
 
 final class BaseUnlockManager: UnlockManager {
-    func unlock() -> AnyPublisher<Void, Error> {
-        Future { promise in
-            let context = LAContext()
-            var error: NSError?
+    func unlock() async throws -> Bool {
+        let context = LAContext()
+        let reason = "We need to make sure you are the owner of the device."
 
-            let handler: (Bool, Error?) -> Void = { success, error in
-                if success {
-                    promise(.success(()))
-                } else {
-                    promise(.failure(UnlockError(error: error)))
-                }
-            }
-
-            let reason = "We need to make sure you are the owner of the device."
-
-            if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) {
-                context.evaluatePolicy(
-                    .deviceOwnerAuthentication,
-                    localizedReason: reason,
-                    reply: handler
-                )
-            } else {
-                handler(true, nil)
-            }
+        do {
+            _ = try await context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason)
+            return true
+        } catch {
+            throw UnlockError(error: error)
         }
-        .eraseToAnyPublisher()
     }
 }