1 contributor
//
// 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()
}
}
}
}