-
Notifications
You must be signed in to change notification settings - Fork 44
/
Contents.swift
181 lines (131 loc) · 4.22 KB
/
Contents.swift
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import Foundation
protocol Memento {
// MARK: - Properties
var data: [String : Any] { get }
// MARK: - Initializers
init?(data: [String : Any])
}
protocol Caretaker {
// MARK: - Properties
var states: [String : String] { get }
// MARK: - Methods
mutating func save<T: Memento>(memento: T, for stateName: String)
func restore<T: Memento>(state: String) -> T?
mutating func delete(state: String)
}
@dynamicMemberLookup
struct PropertyListCaretaker: Caretaker {
// MARK: - Private properties
private let standardDefaults = UserDefaults.standard
private static let STATES_KEY = "KEYS FOR STATES"
// MARK: - Initializers
init() {
if let states = standardDefaults.object(forKey: PropertyListCaretaker.STATES_KEY) as? [String : String] {
print("restored state keys: ", states)
self.states = states
}
}
// MARK: - Conformance to Caretaker protocol
var states: [String : String] = [:] {
didSet {
standardDefaults.set(states, forKey: PropertyListCaretaker.STATES_KEY)
}
}
mutating func save<T: Memento>(memento: T, for stateName: String) {
states.updateValue(stateName, forKey: stateName)
standardDefaults.set(memento.data, forKey: stateName)
}
func restore<T: Memento>(state: String) -> T? {
guard let data = standardDefaults.object(forKey: state) as? [String : Any] else {
return nil
}
let memento = T(data: data)
return memento
}
mutating func delete(state: String) {
states.removeValue(forKey: state)
standardDefaults.removeObject(forKey: state)
}
// MARK: - Dynamic Member Lookup Subscripts
subscript<T: Memento>(dynamicMember input: String) -> T? {
return restore(state: input)
}
}
class User: Memento {
var name: String
var age: Int
var address: String
var data: [String : Any] {
return ["name" : name, "age" : age, "address" : address]
}
init(name: String, age: Int, address: String) {
self.name = name
self.age = age
self.address = address
}
required init?(data: [String : Any]) {
guard let mName = data["name"] as? String, let mAge = data["age"] as? Int, let mAddress = data["address"] as? String else {
return nil
}
name = mName
age = mAge
address = mAddress
}
}
extension User: CustomStringConvertible {
var description: String {
return "name: \(name), age: \(age), address: \(address)"
}
}
class Animal: Memento {
var name: String
var age: Int
var data: [String : Any] {
return ["name" : name, "age" : age]
}
init(name: String, age: Int) {
self.name = name
self.age = age
}
required init?(data: [String : Any]) {
guard let mName = data["name"] as? String, let mAge = data["age"] as? Int else {
return nil
}
name = mName
age = mAge
}
}
extension Animal: CustomStringConvertible {
var description: String {
return "name: \(name), age: \(age)"
}
}
var user = User(name: "John", age: 26, address: "New Ave, 456")
var animal = Animal(name: "Monkey", age: 8)
var caretaker = PropertyListCaretaker()
caretaker.states
if let user = caretaker.restore(state: "defaultUser02") as User? {
print("user that was restored from the persistent state key: ", user)
}
caretaker.save(memento: user, for: "defaultUser")
caretaker.save(memento: animal, for: "defaultAnimal")
user.age = 32
animal.age = 10
caretaker.save(memento: user, for: "defaultUser01")
caretaker.save(memento: animal, for: "defaultAnimal01")
user.name = "Alex"
animal.name = "Cat"
print(user)
print(animal)
if let restoredUser = caretaker.defaultUser as User? {
print("restored: ", restoredUser)
}
if let restoredUser = caretaker.defaultUser01 as User? {
print("restored: ", restoredUser)
}
if let restoredAnimal = caretaker.defaultAnimal as Animal? {
print("restored: ", restoredAnimal)
}
if let restoredAnimal = caretaker.defaultAnimal02 as Animal? {
print("restored: ", restoredAnimal)
}