Files
hope-voice-api/ios/Sources/App/SettingsStore.swift
T
2026-10-04 07:23:49 -04:00

70 lines
2.5 KiB
Swift

import Foundation
import Combine
final class SettingsStore: ObservableObject {
@Published var serverURL: String {
didSet { AppPreferences.store.set(serverURL, forKey: Keys.serverURL) }
}
@Published var voiceID: String {
didSet { AppPreferences.store.set(voiceID, forKey: Keys.voiceID) }
}
@Published var textMode: Bool {
didSet { AppPreferences.store.set(textMode, forKey: Keys.textMode) }
}
private enum Keys {
static let serverURL = "serverURL"
static let voiceID = "voiceID"
static let textMode = "textMode"
}
static let defaultServerURL = "https://192.168.86.2:9178"
init() {
let d = AppPreferences.store
// Sanitize legacy values: earlier versions wrote the field to storage on
// every keystroke, so an invalid half-typed URL could be persisted and
// shipped to the network layer. Fall back to the documented default and
// repair the stored value once.
let storedURL = d.string(forKey: Keys.serverURL) ?? Self.defaultServerURL
switch ServerConfig.parse(storedURL) {
case .success:
serverURL = storedURL
case .failure:
// Legacy invalid value: repair to the documented default.
serverURL = Self.defaultServerURL
d.set(Self.defaultServerURL, forKey: Keys.serverURL)
}
let storedVoice = d.string(forKey: Keys.voiceID)
voiceID = Voices.restoredID(storedVoice)
textMode = d.bool(forKey: Keys.textMode)
d.set(voiceID, forKey: Keys.voiceID)
}
var trimmedServerURL: String {
serverURL.trimmingCharacters(in: .whitespacesAndNewlines)
}
}
enum AppPreferences {
static let store: UserDefaults = {
#if DEBUG
if ProcessInfo.processInfo.arguments.contains("--ui-testing") {
let suite = "dev.shane.voice.ui-testing"
let defaults = UserDefaults(suiteName: suite)!
if ProcessInfo.processInfo.arguments.contains("--reset-ui-testing") {
defaults.removePersistentDomain(forName: suite)
// Deterministic offline errors; UI tests must not contact the NAS.
defaults.set("https://127.0.0.1:1", forKey: "serverURL")
}
if ProcessInfo.processInfo.arguments.contains("--live-testing") {
defaults.set(SettingsStore.defaultServerURL, forKey: "serverURL")
defaults.set(true, forKey: "textMode")
}
return defaults
}
#endif
return .standard
}()
}