Przeglądaj źródła

async fetching functions in NS manager

polscm32 aka Marvout 1 rok temu
rodzic
commit
18ac6023cd

+ 8 - 10
FreeAPS/Sources/APS/FetchTreatmentsManager.swift

@@ -22,23 +22,21 @@ final class BaseFetchTreatmentsManager: FetchTreatmentsManager, Injectable {
     private func subscribe() {
         timer.publisher
             .receive(on: processQueue)
-            .flatMap { _ -> AnyPublisher<([CarbsEntry], [TempTarget]), Never> in
+            .sink { [weak self] _ in
+                guard let self = self else { return }
                 debug(.nightscout, "FetchTreatmentsManager heartbeat")
                 debug(.nightscout, "Start fetching carbs and temptargets")
-                return Publishers.CombineLatest(
-                    self.nightscoutManager.fetchCarbs(),
-                    self.nightscoutManager.fetchTempTargets()
-                ).eraseToAnyPublisher()
-            }
-            .sink { [weak self] carbs, targets in
-                guard let self = self else { return }
 
                 Task {
-                    let filteredCarbs = carbs.filter { !($0.enteredBy?.contains(CarbsEntry.manual) ?? false) }
+                    async let carbs = self.nightscoutManager.fetchCarbs()
+                    async let tempTargets = self.nightscoutManager.fetchTempTargets()
+
+                    let filteredCarbs = await carbs.filter { !($0.enteredBy?.contains(CarbsEntry.manual) ?? false) }
                     if filteredCarbs.isNotEmpty {
                         await self.carbsStorage.storeCarbs(filteredCarbs)
                     }
-                    let filteredTargets = targets.filter { !($0.enteredBy?.contains(TempTarget.manual) ?? false) }
+
+                    let filteredTargets = await tempTargets.filter { !($0.enteredBy?.contains(TempTarget.manual) ?? false) }
                     if filteredTargets.isNotEmpty {
                         self.tempTargetsStorage.storeTempTargets(filteredTargets)
                     }

+ 26 - 69
FreeAPS/Sources/Services/Network/NightscoutAPI.swift

@@ -98,7 +98,7 @@ extension NightscoutAPI {
         }
     }
 
-    func fetchCarbs(sinceDate: Date? = nil) -> AnyPublisher<[CarbsEntry], Swift.Error> {
+    func fetchCarbs(sinceDate: Date? = nil) async throws -> [CarbsEntry] {
         var components = URLComponents()
         components.scheme = url.scheme
         components.host = url.host
@@ -131,14 +131,19 @@ extension NightscoutAPI {
             request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret")
         }
 
-        return service.run(request)
-            .retry(Config.retryCount)
-            .decode(type: [CarbsEntry].self, decoder: JSONCoding.decoder)
-            .catch { error -> AnyPublisher<[CarbsEntry], Swift.Error> in
-                warning(.nightscout, "Carbs fetching error: \(error.localizedDescription)")
-                return Just([]).setFailureType(to: Swift.Error.self).eraseToAnyPublisher()
+        do {
+            let (data, response) = try await URLSession.shared.data(for: request)
+
+            guard let httpResponse = response as? HTTPURLResponse, (200 ... 299).contains(httpResponse.statusCode) else {
+                throw URLError(.badServerResponse)
             }
-            .eraseToAnyPublisher()
+
+            let carbs = try JSONCoding.decoder.decode([CarbsEntry].self, from: data)
+            return carbs
+        } catch {
+            warning(.nightscout, "Carbs fetching error: \(error.localizedDescription)")
+            throw error
+        }
     }
 
     func deleteCarbs(withId id: String) async throws {
@@ -232,36 +237,7 @@ extension NightscoutAPI {
         }
     }
 
-//    func deleteInsulin(at date: Date) -> AnyPublisher<Void, Swift.Error> {
-//        var components = URLComponents()
-//        components.scheme = url.scheme
-//        components.host = url.host
-//        components.port = url.port
-//        components.path = Config.treatmentsPath
-//        components.queryItems = [
-//            URLQueryItem(name: "find[bolus][$exists]", value: "true"),
-//            URLQueryItem(
-//                name: "find[created_at][$eq]",
-//                value: Formatter.iso8601withFractionalSeconds.string(from: date)
-//            )
-//        ]
-//
-//        var request = URLRequest(url: components.url!)
-//        request.allowsConstrainedNetworkAccess = false
-//        request.timeoutInterval = Config.timeout
-//        request.httpMethod = "DELETE"
-//
-//        if let secret = secret {
-//            request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret")
-//        }
-//
-//        return service.run(request)
-//            .retry(Config.retryCount)
-//            .map { _ in () }
-//            .eraseToAnyPublisher()
-//    }
-
-    func fetchTempTargets(sinceDate: Date? = nil) -> AnyPublisher<[TempTarget], Swift.Error> {
+    func fetchTempTargets(sinceDate: Date? = nil) async throws -> [TempTarget] {
         var components = URLComponents()
         components.scheme = url.scheme
         components.host = url.host
@@ -295,14 +271,19 @@ extension NightscoutAPI {
             request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret")
         }
 
-        return service.run(request)
-            .retry(Config.retryCount)
-            .decode(type: [TempTarget].self, decoder: JSONCoding.decoder)
-            .catch { error -> AnyPublisher<[TempTarget], Swift.Error> in
-                warning(.nightscout, "TempTarget fetching error: \(error.localizedDescription)")
-                return Just([]).setFailureType(to: Swift.Error.self).eraseToAnyPublisher()
+        do {
+            let (data, response) = try await URLSession.shared.data(for: request)
+
+            guard let httpResponse = response as? HTTPURLResponse, (200 ... 299).contains(httpResponse.statusCode) else {
+                throw URLError(.badServerResponse)
             }
-            .eraseToAnyPublisher()
+
+            let tempTargets = try JSONCoding.decoder.decode([TempTarget].self, from: data)
+            return tempTargets
+        } catch {
+            warning(.nightscout, "TempTarget fetching error: \(error.localizedDescription)")
+            throw error
+        }
     }
 
     func fetchAnnouncement(sinceDate: Date? = nil) -> AnyPublisher<[Announcement], Swift.Error> {
@@ -442,30 +423,6 @@ extension NightscoutAPI {
         }
     }
 
-//    func uploadStats(_ stats: NightscoutStatistics) -> AnyPublisher<Void, Swift.Error> {
-//        var components = URLComponents()
-//        components.scheme = url.scheme
-//        components.host = url.host
-//        components.port = url.port
-//        components.path = Config.statusPath
-//
-//        var request = URLRequest(url: components.url!)
-//        request.allowsConstrainedNetworkAccess = false
-//        request.timeoutInterval = Config.timeout
-//        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
-//
-//        if let secret = secret {
-//            request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret")
-//        }
-//        request.httpBody = try! JSONCoding.encoder.encode(stats)
-//        request.httpMethod = "POST"
-//
-//        return service.run(request)
-//            .retry(Config.retryCount)
-//            .map { _ in () }
-//            .eraseToAnyPublisher()
-//    }
-
     func uploadStatus(_ status: NightscoutStatus) -> AnyPublisher<Void, Swift.Error> {
         var components = URLComponents()
         components.scheme = url.scheme

+ 20 - 12
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -7,8 +7,8 @@ import UIKit
 
 protocol NightscoutManager: GlucoseSource {
     func fetchGlucose(since date: Date) async -> [BloodGlucose]
-    func fetchCarbs() -> AnyPublisher<[CarbsEntry], Never>
-    func fetchTempTargets() -> AnyPublisher<[TempTarget], Never>
+    func fetchCarbs() async -> [CarbsEntry]
+    func fetchTempTargets() async -> [TempTarget]
     func fetchAnnouncements() -> AnyPublisher<[Announcement], Never>
     func deleteCarbs(withID id: String) async
     func deleteInsulin(withID id: String) async
@@ -153,26 +153,34 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         fetch(nil)
     }
 
-    func fetchCarbs() -> AnyPublisher<[CarbsEntry], Never> {
+    func fetchCarbs() async -> [CarbsEntry] {
         guard let nightscout = nightscoutAPI, isNetworkReachable else {
-            return Just([]).eraseToAnyPublisher()
+            return []
         }
 
         let since = carbsStorage.syncDate()
-        return nightscout.fetchCarbs(sinceDate: since)
-            .replaceError(with: [])
-            .eraseToAnyPublisher()
+        do {
+            let carbs = try await nightscout.fetchCarbs(sinceDate: since)
+            return carbs
+        } catch {
+            debug(.nightscout, "Error fetching carbs: \(error.localizedDescription)")
+            return []
+        }
     }
 
-    func fetchTempTargets() -> AnyPublisher<[TempTarget], Never> {
+    func fetchTempTargets() async -> [TempTarget] {
         guard let nightscout = nightscoutAPI, isNetworkReachable else {
-            return Just([]).eraseToAnyPublisher()
+            return []
         }
 
         let since = tempTargetsStorage.syncDate()
-        return nightscout.fetchTempTargets(sinceDate: since)
-            .replaceError(with: [])
-            .eraseToAnyPublisher()
+        do {
+            let tempTargets = try await nightscout.fetchTempTargets(sinceDate: since)
+            return tempTargets
+        } catch {
+            debug(.nightscout, "Error fetching temp targets: \(error.localizedDescription)")
+            return []
+        }
     }
 
     func fetchAnnouncements() -> AnyPublisher<[Announcement], Never> {