From 215ad947048940f1cf87518e6a8e72441e8e554b Mon Sep 17 00:00:00 2001 From: ensan Date: Sun, 23 Jul 2023 15:58:55 +0900 Subject: [PATCH] Add UserDefaultsManager.swift --- Sources/SwiftUtils/UserDefaultsManager.swift | 64 ++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 Sources/SwiftUtils/UserDefaultsManager.swift diff --git a/Sources/SwiftUtils/UserDefaultsManager.swift b/Sources/SwiftUtils/UserDefaultsManager.swift new file mode 100644 index 0000000..c63efc3 --- /dev/null +++ b/Sources/SwiftUtils/UserDefaultsManager.swift @@ -0,0 +1,64 @@ +// +// UserDefaultsManager.swift +// +// +// Created by ensan on 2023/07/21. +// + +import Foundation + +public protocol UserDefaultsKeys: RawRepresentable where RawValue == String { + associatedtype Manager: UserDefaultsManager + init(keyPath: PartialKeyPath) +} + +public protocol UserDefaultsManager { + associatedtype Keys: UserDefaultsKeys where Keys.Manager == Self + var userDefaults: UserDefaults { get } + mutating func update(_ value: KeyPath, newValue: T) + mutating func update(_ value: KeyPath, process: (inout T) -> Void) +} + +public extension UserDefaultsManager { + mutating func update(_ value: KeyPath, newValue: T) { + if let value = value as? WritableKeyPath { + self[keyPath: value] = newValue + update(value: value) + } + } + + mutating func update(_ value: KeyPath, process: (inout T) -> Void) { + if let value = value as? WritableKeyPath { + process(&self[keyPath: value]) + update(value: value) + } + } +} + +public extension UserDefaultsManager { + mutating func update(value: WritableKeyPath) { + do { + let data = try JSONEncoder().encode(self[keyPath: value]) + let key = Keys(keyPath: value) + userDefaults.set(data, forKey: key.rawValue) + } catch { + debug(error) + } + } + + static func load(key: Keys, userDefaults: UserDefaults) -> T { + if let value = userDefaults.data(forKey: key.rawValue) { + do { + let value = try JSONDecoder().decode(T.self, from: value) + return value + } catch { + debug(error) + } + } + return T.initialValue + } +} + +public protocol StaticInitialValueAvailable: Codable { + static var initialValue: Self {get} +}