AutoCat/AutoCatCore/Services/SettingsService/SettingsService.swift

155 lines
4.1 KiB
Swift

//
// SettingsService.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 17.08.2024.
// Copyright © 2024 Selim Mustafaev. All rights reserved.
//
import Foundation
enum SettingsKey: String {
case user
case recognizeAlternativeOrder
case recognizeShortenedNumbers
case defaultRegion
case recordBeep
case showDebugInfo
case backendString
}
@MainActor
@Observable
public final class SettingsService: SettingsServiceProtocol {
let jsonEncoder = JSONEncoder()
let jsonDecoder = JSONDecoder()
let suiteName: String?
var defaults: UserDefaults {
if let suiteName {
return UserDefaults(suiteName: suiteName) ?? .standard
} else {
return .standard
}
}
public var user: User {
get {
if let userData, userData.count > 0 {
let result = try? jsonDecoder.decode(User.self, from: userData)
return result ?? User()
} else {
return User()
}
}
set {
if let json = try? jsonEncoder.encode(newValue) {
userData = json
}
}
}
public var userData: Data? {
didSet {
set(value: userData, for: .user)
}
}
public var recognizeAlternativeOrder: Bool = false {
didSet {
set(value: recognizeAlternativeOrder, for: .recognizeAlternativeOrder)
}
}
public var recognizeShortenedNumbers: Bool = false {
didSet {
set(value: recognizeShortenedNumbers, for: .recognizeShortenedNumbers)
}
}
public var defaultRegion: String = "161" {
didSet {
set(value: defaultRegion, for: .defaultRegion)
}
}
public var recordBeep: Bool = false {
didSet {
set(value: recordBeep, for: .recordBeep)
}
}
public var showDebugInfo: Bool = false {
didSet {
set(value: showDebugInfo, for: .showDebugInfo)
}
}
public var backend: Constants.Backend {
get { Constants.Backend(rawValue: backendString) ?? .de }
set { backendString = newValue.rawValue }
}
public var backendString: String = Constants.Backend.de.rawValue {
didSet {
set(value: backendString, for: .backendString)
}
}
public init(suiteName: String? = nil) async {
self.suiteName = suiteName
register(defaultValues: [
.recognizeAlternativeOrder: false,
.recognizeShortenedNumbers: false,
.defaultRegion: "761",
.recordBeep: false,
.showDebugInfo: false,
.backendString: Constants.Backend.de.rawValue
])
userData = data(for: .user)
recognizeAlternativeOrder = bool(for: .recognizeAlternativeOrder)
recognizeShortenedNumbers = bool(for: .recognizeShortenedNumbers)
defaultRegion = string(for: .defaultRegion)
recordBeep = bool(for: .recordBeep)
showDebugInfo = bool(for: .showDebugInfo)
backendString = string(for: .backendString)
}
func register(defaultValues: [SettingsKey: Any]) {
defaults.register(defaults: defaultValues.reduce(into: [:], { (partialResult: inout [String: Any], tuple) in
partialResult[tuple.key.rawValue] = tuple.value
}))
}
func set<T>(value: T, for key: SettingsKey) {
defaults.setValue(value, forKey: key.rawValue)
}
func bool(for key: SettingsKey) -> Bool {
defaults.bool(forKey: key.rawValue)
}
func string(for key: SettingsKey, defaultValue: String = "") -> String {
defaults.string(forKey: key.rawValue) ?? defaultValue
}
func data(for key: SettingsKey) -> Data? {
defaults.data(forKey: key.rawValue)
}
public func setFirebaseIdToken(_ idToken: String?) {
user.firebaseIdToken = idToken
}
public func setFirebaseRefreshToken(_ refreshToken: String?) {
user.firebaseRefreshToken = refreshToken
}
}