import Foundation struct ServerConfig: Codable, Sendable { var host: String var port: Int? var path: String var token: String var useHttps: Bool var baseUrl: String { var url = useHttps ? "https://" : "http://" url += host if let port { url += ":\(port)" } if !path.isEmpty { url += path } return url } } extension ServerConfig { private static let key = "serverConfig" private static let appGroupId = "group.com.magicive.marks" static func load() -> ServerConfig? { guard let data = UserDefaults.standard.data(forKey: key) else { return nil } return try? JSONDecoder().decode(ServerConfig.self, from: data) } /// Loads config from the shared app group — used by extensions, which have no /// access to the main app's `UserDefaults.standard`. static func loadShared() -> ServerConfig? { guard let data = UserDefaults(suiteName: appGroupId)?.data(forKey: key) else { return nil } return try? JSONDecoder().decode(ServerConfig.self, from: data) } func save() { guard let data = try? JSONEncoder().encode(self) else { return } UserDefaults.standard.set(data, forKey: ServerConfig.key) UserDefaults(suiteName: ServerConfig.appGroupId)?.set(data, forKey: ServerConfig.key) } func delete() { UserDefaults.standard.removeObject(forKey: ServerConfig.key) UserDefaults(suiteName: ServerConfig.appGroupId)?.removeObject(forKey: ServerConfig.key) } }