-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUserDefaultsManager_soft_dynamic.swift
More file actions
128 lines (104 loc) · 3.74 KB
/
UserDefaultsManager_soft_dynamic.swift
File metadata and controls
128 lines (104 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// UserDefaultsManager.swift
// by Daniel Illescas Romero
// Github: @illescasDaniel
// License: MIT
import class Foundation.UserDefaults
import protocol Foundation.LocalizedError
import class Foundation.NSData
import class Foundation.NSString
import class Foundation.NSNumber
import class Foundation.NSDate
import class Foundation.NSArray
import class Foundation.NSDictionary
import struct Foundation.Date
import struct Foundation.Data
public protocol UserDefaultsKeyProtocol {
// var string: String? { get }
// ...
}
extension NSData: UserDefaultsKeyProtocol {}
extension NSString: UserDefaultsKeyProtocol {}
extension NSNumber: UserDefaultsKeyProtocol {}
extension NSDate: UserDefaultsKeyProtocol {}
extension NSArray: UserDefaultsKeyProtocol {}
extension NSDictionary: UserDefaultsKeyProtocol {}
extension Bool: UserDefaultsKeyProtocol {}
extension Int: UserDefaultsKeyProtocol {}
extension Double: UserDefaultsKeyProtocol {}
extension Float: UserDefaultsKeyProtocol {}
extension String: UserDefaultsKeyProtocol {}
extension Array: UserDefaultsKeyProtocol where Element: UserDefaultsKeyProtocol {}
extension Dictionary: UserDefaultsKeyProtocol where Key: UserDefaultsKeyProtocol, Value: UserDefaultsKeyProtocol {}
extension Data: UserDefaultsKeyProtocol {}
extension Date: UserDefaultsKeyProtocol {}
public protocol RawEnumProtocol: RawRepresentable {}
public protocol RawStringEnumProtocol: RawEnumProtocol where Self.RawValue == String {}
public protocol UserDefaultsEnumProtocol: RawStringEnumProtocol, CaseIterable {
var `default`: UserDefaultsKeyProtocol { get }
}
public final class UserDefaultsManager<Key: UserDefaultsEnumProtocol> {
private let defaults: UserDefaults
/// Should NOT be used directly, since everytime is called, it will register all default keys (again) in the standard UserDefaults
/// It should be used when creating an extension, for example
public static var standardDefaults: UserDefaultsManager<Key> {
return UserDefaultsManager<Key>(defaults: .standard)
}
/// If the UserDefaults created from `suiteName` is nil, the class will use `UserDefaults.standard`
public convenience init(suiteName: String) {
self.init(defaults: UserDefaults(suiteName: suiteName))
}
fileprivate init(defaults: UserDefaults? = .standard) {
self.defaults = defaults ?? .standard
self.registerKeyDefaults()
}
//
public subscript(key: Key) -> Any {
get {
return self.defaults.object(forKey: key.rawValue) ?? key.default
} set {
self.set(newValue, forKey: key)
}
}
public subscript<T>(key: Key) -> T? {
get {
return (self[key] as Any) as? T
} set {
self.set(newValue, forKey: key)
}
}
// Convenience
private func registerKeyDefaults() {
let mappedDefaults = Dictionary(uniqueKeysWithValues: Key.allCases.map { ($0.rawValue, $0.default) })
self.defaults.register(defaults: mappedDefaults)
}
private func set(_ value: Any?, forKey key: Key) {
self.defaults.set(value, forKey: key.rawValue)
}
}
//
public enum UserDefaultsKey: String, UserDefaultsEnumProtocol {
case isDarkTheme
case isBlack
case score
case today
public var `default`: UserDefaultsKeyProtocol {
switch self {
case .isDarkTheme: return false
case .isBlack: return true
case .score: return 20.1
case .today: return Date()
}
}
}
// in app-delegate:
public extension UserDefaultsManager where Key == UserDefaultsKey {
//public static let standard = UserDefaultsManager<Key>.standardDefaults
public static let custom = UserDefaultsManager<Key>(suiteName: "_swift-app-test__5")
}
print(UserDefaultsManager.custom[.score])
UserDefaultsManager.custom[.score] = 99
let score: Int? = UserDefaultsManager.custom[.score]
print(score ?? 10)
print(UserDefaultsManager.custom[.today])
let today: Date? = UserDefaultsManager.custom[.today]
print(today)