NightscoutConfigStateModel.swift 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import Combine
  2. import SwiftDate
  3. import SwiftUI
  4. extension NightscoutConfig {
  5. final class StateModel: BaseStateModel<Provider> {
  6. @Injected() private var keychain: Keychain!
  7. @Injected() private var nightscoutManager: NightscoutManager!
  8. @Injected() private var glucoseStorage: GlucoseStorage!
  9. @Published var url = ""
  10. @Published var secret = ""
  11. @Published var message = ""
  12. @Published var connecting = false
  13. @Published var backfilling = false
  14. @Published var isUploadEnabled = false
  15. @Published var useLocalSource = false
  16. @Published var localPort: Decimal = 0
  17. override func subscribe() {
  18. url = keychain.getValue(String.self, forKey: Config.urlKey) ?? ""
  19. secret = keychain.getValue(String.self, forKey: Config.secretKey) ?? ""
  20. subscribeSetting(\.isUploadEnabled, on: $isUploadEnabled) { isUploadEnabled = $0 }
  21. subscribeSetting(\.useLocalGlucoseSource, on: $useLocalSource) { useLocalSource = $0 }
  22. subscribeSetting(\.localGlucosePort, on: $localPort.map(Int.init)) { localPort = Decimal($0) }
  23. }
  24. func connect() {
  25. guard let url = URL(string: url) else {
  26. message = "Invalid URL"
  27. return
  28. }
  29. connecting = true
  30. message = ""
  31. provider.checkConnection(url: url, secret: secret.isEmpty ? nil : secret)
  32. .receive(on: DispatchQueue.main)
  33. .sink { completion in
  34. switch completion {
  35. case .finished: break
  36. case let .failure(error):
  37. self.message = "Error: \(error.localizedDescription)"
  38. }
  39. self.connecting = false
  40. } receiveValue: {
  41. self.message = "Connected!"
  42. self.keychain.setValue(self.url, forKey: Config.urlKey)
  43. self.keychain.setValue(self.secret, forKey: Config.secretKey)
  44. }
  45. .store(in: &lifetime)
  46. }
  47. func backfillGlucose() {
  48. backfilling = true
  49. nightscoutManager.fetchGlucose(since: Date().addingTimeInterval(-1.days.timeInterval))
  50. .sink { [weak self] glucose in
  51. guard let self = self, glucose.isNotEmpty else { return }
  52. self.glucoseStorage.storeGlucose(glucose)
  53. DispatchQueue.main.async {
  54. self.backfilling = false
  55. }
  56. }
  57. .store(in: &lifetime)
  58. }
  59. func delete() {
  60. keychain.removeObject(forKey: Config.urlKey)
  61. keychain.removeObject(forKey: Config.secretKey)
  62. url = ""
  63. secret = ""
  64. }
  65. }
  66. }