Skip to content

Commit 0bbdf94

Browse files
committed
Improve toke-based API with observers
1 parent a05dfb7 commit 0bbdf94

File tree

4 files changed

+66
-28
lines changed

4 files changed

+66
-28
lines changed

Source/Shared/Storage/HybridStorage.swift

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ public final class HybridStorage<T> {
55
public let memoryStorage: MemoryStorage<T>
66
public let diskStorage: DiskStorage<T>
77

8-
private var observations = (
9-
storage: [UUID : (HybridStorage, StorageChange) -> Void](),
10-
key: [String : (HybridStorage, KeyChange<T>) -> Void]()
11-
)
8+
private var storageObservations = [UUID : (HybridStorage, StorageChange) -> Void]()
9+
private var keyObservations = [String : (HybridStorage, KeyChange<T>) -> Void]()
1210

1311
public init(memoryStorage: MemoryStorage<T>, diskStorage: DiskStorage<T>) {
1412
self.memoryStorage = memoryStorage
@@ -49,7 +47,7 @@ extension HybridStorage: StorageAware {
4947
public func setObject(_ object: T, forKey key: String, expiry: Expiry? = nil) throws {
5048
var keyChange: KeyChange<T>?
5149

52-
if observations.key[key] != nil {
50+
if keyObservations[key] != nil {
5351
keyChange = .edit(before: try? self.object(forKey: key), after: object)
5452
}
5553

@@ -93,55 +91,77 @@ public extension HybridStorage {
9391

9492
extension HybridStorage: StorageObservationRegistry {
9593
@discardableResult
96-
public func observeStorage(using closure: @escaping (HybridStorage, StorageChange) -> Void) -> ObservationToken {
94+
public func addStorageObserver<O: AnyObject>(
95+
_ observer: O,
96+
closure: @escaping (O, HybridStorage, StorageChange) -> Void
97+
) -> ObservationToken {
9798
let id = UUID()
98-
observations.storage[id] = closure
99+
100+
storageObservations[id] = { [weak self, weak observer] storage, change in
101+
guard let observer = observer else {
102+
self?.storageObservations.removeValue(forKey: id)
103+
return
104+
}
105+
106+
closure(observer, storage, change)
107+
}
99108

100109
return ObservationToken { [weak self] in
101-
self?.observations.storage.removeValue(forKey: id)
110+
self?.storageObservations.removeValue(forKey: id)
102111
}
103112
}
104113

105114
public func removeAllStorageObservations() {
106-
observations.storage.removeAll()
115+
storageObservations.removeAll()
107116
}
108117

109118
private func notifyStorageObservers(about change: StorageChange) {
110-
observations.storage.values.forEach { closure in
119+
storageObservations.values.forEach { closure in
111120
closure(self, change)
112121
}
113122
}
114123
}
115124

116125
extension HybridStorage: KeyObservationRegistry {
117126
@discardableResult
118-
public func observeKey(_ key: String, using closure: @escaping (HybridStorage, KeyChange<T>) -> Void) -> ObservationToken {
119-
observations.key[key] = closure
127+
public func addObserver<O: AnyObject>(
128+
_ observer: O,
129+
forKey key: String,
130+
closure: @escaping (O, HybridStorage, KeyChange<T>) -> Void
131+
) -> ObservationToken {
132+
keyObservations[key] = { [weak self, weak observer] storage, change in
133+
guard let observer = observer else {
134+
self?.removeObservation(forKey: key)
135+
return
136+
}
137+
138+
closure(observer, storage, change)
139+
}
120140

121141
return ObservationToken { [weak self] in
122-
self?.observations.key.removeValue(forKey: key)
142+
self?.keyObservations.removeValue(forKey: key)
123143
}
124144
}
125145

126146
public func removeObservation(forKey key: String) {
127-
observations.key.removeValue(forKey: key)
147+
keyObservations.removeValue(forKey: key)
128148
}
129149

130150
public func removeAllKeyObservations() {
131-
observations.key.removeAll()
151+
keyObservations.removeAll()
132152
}
133153

134154
private func notifyObserver(forKey key: String, about change: KeyChange<T>) {
135-
observations.key[key]?(self, change)
155+
keyObservations[key]?(self, change)
136156
}
137157

138158
private func notifyObserver(about change: KeyChange<T>, whereKey closure: ((String) -> Bool)) {
139-
let observation = observations.key.first { key, value in closure(key) }?.value
159+
let observation = keyObservations.first { key, value in closure(key) }?.value
140160
observation?(self, change)
141161
}
142162

143163
private func notifyKeyObservers(about change: KeyChange<T>) {
144-
observations.key.values.forEach { closure in
164+
keyObservations.values.forEach { closure in
145165
closure(self, change)
146166
}
147167
}

Source/Shared/Storage/KeyObservationRegistry.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ public protocol KeyObservationRegistry {
44
associatedtype S: StorageAware
55

66
@discardableResult
7-
func observeKey(_ key: String, using closure: @escaping (S, KeyChange<S.T>) -> Void) -> ObservationToken
7+
func addObserver<O: AnyObject>(
8+
_ observer: O,
9+
forKey key: String,
10+
closure: @escaping (O, S, KeyChange<S.T>) -> Void
11+
) -> ObservationToken
12+
813
func removeObservation(forKey key: String)
914
func removeAllKeyObservations()
1015
}

Source/Shared/Storage/Storage.swift

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,14 @@ public extension Storage {
8686

8787
extension Storage: StorageObservationRegistry {
8888
@discardableResult
89-
public func observeStorage(using closure: @escaping (Storage, StorageChange) -> Void) -> ObservationToken {
90-
return hybridStorage.observeStorage(using: { _, change in
91-
closure(self, change)
92-
})
89+
public func addStorageObserver<O: AnyObject>(
90+
_ observer: O,
91+
closure: @escaping (O, Storage, StorageChange) -> Void
92+
) -> ObservationToken {
93+
return hybridStorage.addStorageObserver(observer) { [weak self] observer, _, change in
94+
guard let strongSelf = self else { return }
95+
closure(observer, strongSelf, change)
96+
}
9397
}
9498

9599
public func removeAllStorageObservations() {
@@ -99,10 +103,15 @@ extension Storage: StorageObservationRegistry {
99103

100104
extension Storage: KeyObservationRegistry {
101105
@discardableResult
102-
public func observeKey(_ key: String, using closure: @escaping (Storage, KeyChange<T>) -> Void) -> ObservationToken {
103-
return hybridStorage.observeKey(key, using: { _, change in
104-
closure(self, change)
105-
})
106+
public func addObserver<O: AnyObject>(
107+
_ observer: O,
108+
forKey key: String,
109+
closure: @escaping (O, Storage, KeyChange<T>) -> Void
110+
) -> ObservationToken {
111+
return hybridStorage.addObserver(observer, forKey: key) { [weak self] observer, _ , change in
112+
guard let strongSelf = self else { return }
113+
closure(observer, strongSelf, change)
114+
}
106115
}
107116

108117
public func removeObservation(forKey key: String) {

Source/Shared/Storage/StorageObservationRegistry.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ public protocol StorageObservationRegistry {
44
associatedtype S: StorageAware
55

66
@discardableResult
7-
func observeStorage(using closure: @escaping (S, StorageChange) -> Void) -> ObservationToken
7+
func addStorageObserver<O: AnyObject>(
8+
_ observer: O,
9+
closure: @escaping (O, S, StorageChange) -> Void
10+
) -> ObservationToken
11+
812
func removeAllStorageObservations()
913
}
1014

0 commit comments

Comments
 (0)