// // DataStore.swift // USB Meter // // Created by Bogdan Timofte on 03/03/2020. // Copyright © 2020 Bogdan Timofte. All rights reserved. // import SwiftUI import Combine import CoreBluetooth final class AppData : ObservableObject { private var bluetoothManagerNotification: AnyCancellable? private var meterStoreObserver: AnyCancellable? private var meterStoreCloudObserver: AnyCancellable? private let meterStore = MeterNameStore.shared init() { bluetoothManagerNotification = bluetoothManager.objectWillChange.sink { [weak self] _ in self?.scheduleObjectWillChange() } meterStoreObserver = NotificationCenter.default.publisher(for: .meterNameStoreDidChange) .receive(on: DispatchQueue.main) .sink { [weak self] _ in self?.refreshMeterMetadata() } meterStoreCloudObserver = NotificationCenter.default.publisher(for: .meterNameStoreCloudStatusDidChange) .receive(on: DispatchQueue.main) .sink { [weak self] _ in self?.scheduleObjectWillChange() } } let bluetoothManager = BluetoothManager() @Published var enableRecordFeature: Bool = true @Published var meters: [UUID:Meter] = [UUID:Meter]() var cloudAvailability: MeterNameStore.CloudAvailability { meterStore.currentCloudAvailability } func meterName(for macAddress: String) -> String? { meterStore.name(for: macAddress) } func setMeterName(_ name: String, for macAddress: String) { meterStore.upsert(macAddress: macAddress, name: name, temperatureUnitRawValue: nil) } func temperatureUnitPreference(for macAddress: String) -> TemperatureUnitPreference { let rawValue = meterStore.temperatureUnitRawValue(for: macAddress) ?? TemperatureUnitPreference.celsius.rawValue return TemperatureUnitPreference(rawValue: rawValue) ?? .celsius } func setTemperatureUnitPreference(_ preference: TemperatureUnitPreference, for macAddress: String) { meterStore.upsert(macAddress: macAddress, name: nil, temperatureUnitRawValue: preference.rawValue) } private func scheduleObjectWillChange() { DispatchQueue.main.async { [weak self] in self?.objectWillChange.send() } } private func refreshMeterMetadata() { DispatchQueue.main.async { [weak self] in guard let self else { return } var didUpdateAnyMeter = false for meter in self.meters.values { let mac = meter.btSerial.macAddress.description let displayName = self.meterName(for: mac) ?? mac if meter.name != displayName { meter.updateNameFromStore(displayName) didUpdateAnyMeter = true } let previousTemperaturePreference = meter.tc66TemperatureUnitPreference meter.reloadTemperatureUnitPreference() if meter.tc66TemperatureUnitPreference != previousTemperaturePreference { didUpdateAnyMeter = true } } if didUpdateAnyMeter { self.scheduleObjectWillChange() } } } }