123 lines
3.5 KiB
Swift
123 lines
3.5 KiB
Swift
//
|
|
// SettingsService.swift
|
|
// AutoCatCore
|
|
//
|
|
// Created by Selim Mustafaev on 17.08.2024.
|
|
// Copyright © 2024 Selim Mustafaev. All rights reserved.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
@Observable
|
|
public final class SettingsService: SettingsServiceProtocol {
|
|
|
|
public static let shared = SettingsService(defaults: .standard)
|
|
|
|
let defaults: UserDefaults
|
|
var observations: [NSKeyValueObservation] = []
|
|
|
|
let jsonEncoder = JSONEncoder()
|
|
let jsonDecoder = JSONDecoder()
|
|
|
|
public var user: User {
|
|
get {
|
|
if let data = userData {
|
|
let result = try? jsonDecoder.decode(User.self, from: data)
|
|
return result ?? User()
|
|
} else {
|
|
return User()
|
|
}
|
|
}
|
|
|
|
set {
|
|
if let json = try? jsonEncoder.encode(newValue) {
|
|
userData = json
|
|
}
|
|
}
|
|
}
|
|
|
|
public var userData: Data? = nil {
|
|
didSet {
|
|
defaults.user = userData
|
|
}
|
|
}
|
|
|
|
public var recognizeAlternativeOrder: Bool = false {
|
|
didSet {
|
|
defaults.recognizeAlternativeOrder = recognizeAlternativeOrder
|
|
}
|
|
}
|
|
|
|
public var recognizeShortenedNumbers: Bool = false {
|
|
didSet {
|
|
defaults.recognizeShortenedNumbers = recognizeShortenedNumbers
|
|
}
|
|
}
|
|
|
|
public var defaultRegion: String = "161" {
|
|
didSet {
|
|
defaults.defaultRegion = defaultRegion
|
|
}
|
|
}
|
|
|
|
public var recordBeep: Bool = false {
|
|
didSet {
|
|
defaults.recordBeep = recordBeep
|
|
}
|
|
}
|
|
|
|
public var showDebugInfo: Bool = false {
|
|
didSet {
|
|
defaults.showDebugInfo = showDebugInfo
|
|
}
|
|
}
|
|
|
|
public var useTestBackend: Bool = false {
|
|
didSet {
|
|
defaults.useTestBackend = useTestBackend
|
|
}
|
|
}
|
|
|
|
public init(defaults: UserDefaults) {
|
|
self.defaults = defaults
|
|
|
|
observe(key: \.recognizeAlternativeOrder, for: \.recognizeAlternativeOrder)
|
|
observe(key: \.recognizeShortenedNumbers, for: \.recognizeShortenedNumbers)
|
|
observe(key: \.defaultRegion, for: \.defaultRegion)
|
|
observe(key: \.recordBeep, for: \.recordBeep)
|
|
observe(key: \.showDebugInfo, for: \.showDebugInfo)
|
|
observe(key: \.useTestBackend, for: \.useTestBackend)
|
|
observe(key: \.user, for: \.userData)
|
|
|
|
register(defaultValues: [
|
|
.recognizeAlternativeOrder: false,
|
|
.recognizeShortenedNumbers: false,
|
|
.defaultRegion: "761",
|
|
.recordBeep: false,
|
|
.showDebugInfo: false,
|
|
.useTestBackend: false
|
|
])
|
|
}
|
|
|
|
deinit {
|
|
observations.forEach { $0.invalidate() }
|
|
}
|
|
|
|
func observe<T>(key userDefaultsKey: KeyPath<UserDefaults,T>, for settingsKey: ReferenceWritableKeyPath<SettingsService,T>) where T: Equatable {
|
|
let observation = defaults.observe(userDefaultsKey, options: [.initial, .new]) { [weak self] _, change in
|
|
guard let self else { return }
|
|
|
|
if let new = change.newValue, self[keyPath: settingsKey] != new {
|
|
self[keyPath: settingsKey] = new
|
|
}
|
|
}
|
|
observations.append(observation)
|
|
}
|
|
|
|
func register(defaultValues: [SettingsKey: Any]) {
|
|
defaults.register(defaults: defaultValues.reduce(into: [:], { (partialResult: inout [String: Any], tuple) in
|
|
partialResult[tuple.key.rawValue] = tuple.value
|
|
}))
|
|
}
|
|
}
|