Selected server and better settings
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct Server: Identifiable, Codable
|
struct Server: Identifiable, Codable, Equatable
|
||||||
{
|
{
|
||||||
let serviceName: String?
|
let serviceName: String?
|
||||||
let baseURL: URL
|
let baseURL: URL
|
||||||
|
|||||||
@@ -9,44 +9,106 @@ import Foundation
|
|||||||
|
|
||||||
struct Settings
|
struct Settings
|
||||||
{
|
{
|
||||||
var configuredServers: [Server]
|
var selectedServer: Server?
|
||||||
|
|
||||||
|
var configuredServers: [Server] {
|
||||||
|
willSet {
|
||||||
|
// Set selected server to whatever the first server is, if we're adding the first one.
|
||||||
|
if configuredServers.isEmpty && !newValue.isEmpty && selectedServer == nil {
|
||||||
|
selectedServer = newValue.first
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the selected server is being removed, set it to something else
|
||||||
|
if !newValue.contains(where: { $0 == selectedServer }) {
|
||||||
|
selectedServer = newValue.first // nil if empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isConfigured: Bool { !configuredServers.isEmpty }
|
||||||
|
|
||||||
|
static func fromDefaults() -> Settings {
|
||||||
|
let defaults = UserDefaults.standard
|
||||||
|
return Settings(
|
||||||
|
selectedServer: defaults[SelectedServerKey.self],
|
||||||
|
configuredServers: defaults[ConfiguredServersKey.self]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func save() {
|
||||||
|
let defaults = UserDefaults.standard
|
||||||
|
defaults[ConfiguredServersKey.self] = configuredServers
|
||||||
|
defaults[SelectedServerKey.self] = selectedServer
|
||||||
|
|
||||||
|
postSettingsChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
func postSettingsChanged() {
|
||||||
|
NotificationCenter.default.post(name: .settingsChanged, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Modifiers
|
||||||
|
|
||||||
|
func selectedServer(_ server: Server?) -> Self {
|
||||||
|
var copy = self
|
||||||
|
copy.selectedServer = server
|
||||||
|
return copy
|
||||||
|
}
|
||||||
|
|
||||||
func configuredServers(_ servers: [Server]) -> Self {
|
func configuredServers(_ servers: [Server]) -> Self {
|
||||||
var copy = self
|
var copy = self
|
||||||
copy.configuredServers = servers
|
copy.configuredServers = servers
|
||||||
return copy
|
return copy
|
||||||
}
|
|
||||||
|
|
||||||
var isConfigured: Bool {
|
|
||||||
!configuredServers.isEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
static func fromDefaults() -> Settings {
|
|
||||||
let configuredServers: [Server] = {
|
|
||||||
guard let configuredServersData = UserDefaults.standard.data(forKey: Keys.configuredServers.rawValue)
|
|
||||||
else { return [] }
|
|
||||||
|
|
||||||
guard let configuredServers = try? PropertyListDecoder().decode([Server].self, from: configuredServersData)
|
|
||||||
else { return [] }
|
|
||||||
|
|
||||||
return configuredServers
|
|
||||||
}()
|
|
||||||
|
|
||||||
return Settings(configuredServers: configuredServers)
|
|
||||||
}
|
|
||||||
|
|
||||||
func save() {
|
|
||||||
let configuredServersData = try! PropertyListEncoder().encode(configuredServers)
|
|
||||||
UserDefaults.standard.set(configuredServersData, forKey: Keys.configuredServers.rawValue)
|
|
||||||
NotificationCenter.default.post(name: .settingsChanged, object: nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Types
|
// MARK: - Types
|
||||||
|
|
||||||
enum Keys: String
|
enum Keys: String
|
||||||
{
|
{
|
||||||
|
case selectedServer
|
||||||
case configuredServers
|
case configuredServers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate protocol Key
|
||||||
|
{
|
||||||
|
associatedtype Value: Codable
|
||||||
|
|
||||||
|
static var defaultValue: Value { get }
|
||||||
|
static var key: String { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct ConfiguredServersKey: Key {
|
||||||
|
static var defaultValue: [Server] { [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct SelectedServerKey: Key {
|
||||||
|
static var defaultValue: Server? { nil }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UserDefaults
|
||||||
|
{
|
||||||
|
fileprivate subscript<T: Settings.Key>(_ type: T.Type) -> T.Value {
|
||||||
|
get {
|
||||||
|
guard let data = data(forKey: type.key)
|
||||||
|
else { return type.defaultValue }
|
||||||
|
|
||||||
|
guard let value = try? PropertyListDecoder().decode(type.Value, from: data)
|
||||||
|
else { return type.defaultValue }
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
let data = try? PropertyListEncoder().encode(newValue)
|
||||||
|
set(data, forKey: type.key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Settings.Key
|
||||||
|
{
|
||||||
|
static var key: String { Mirror(reflecting: Self.self).description }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Notification.Name
|
extension Notification.Name
|
||||||
|
|||||||
Reference in New Issue
Block a user