Skip to content

Commit d510e71

Browse files
committed
Version 2.0.0
- Version 2.0.0 Release Commit - Removed the `<TKey: Hashable>` Generics from all implementations of `KeyedObservable` - `KeyedObservable` now has `<TKey: Hashable>` applied to applicable respective `func`s - `KeyedObservable` Implementations now use `AnyHashable` for internal members related to Keys. - `for:` Parameter of `KeyedObservable` `func`s has become `key:` for individual Keys, and `keys: ` for `Array`s of Keys. This is because an `Array` is itself a `Hashable` type, and causes ambiguity with `func` overloading. - Keyed Unit Tests updated accordingly - README.MD updated to reflect all of the above
1 parent 9e64095 commit d510e71

File tree

6 files changed

+106
-112
lines changed

6 files changed

+106
-112
lines changed

README.md

+12-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</p>
1818

1919
Collection of carefully-prepared Classes and Protocols designed to imbue your inheriting Object Types with efficient, protocol-driven Observer Pattern Behaviour.
20-
As of version 1.1.0, this includes support for *Keyed Observers* (see usage examples below for details)
20+
As of version 2.0.0, this includes support for *Keyed Observers* (see usage examples below for details)
2121

2222
## Installation
2323
### Xcode Projects
@@ -31,7 +31,7 @@ let package = Package(
3131
dependencies: [
3232
.package(
3333
url: "https://github.com/Flowduino/Observable.git",
34-
.upToNextMajor(from: "1.1.0")
34+
.upToNextMajor(from: "2.0.0")
3535
),
3636
],
3737
//...
@@ -196,11 +196,12 @@ You can adopt this approach for any Observation-Based Thread Behaviour you requi
196196

197197
### Keyed Observation Pattern
198198
As of version 1.1.0, you can now register and notify *Keyed Observers*.
199+
**Note**: Version 2.0.0 modified the Interface significantly to eliminate the need for Generic Typing of the Key. Key Types are now inferred for you.
199200

200201
This functionality is an extension of the standard Observer Pattern, and is implemented in the following classes from which you can extend:
201-
- `KeyedObservableClass<TKey: Hashable>` instead of `ObservableClass`
202-
- `KeyedObservableThread<TKey: Hashable>` instead of `ObservableThread`
203-
- `KeyedObservableThreadSafeClass<TKey: Hashable>` instead of `ObservableThreadSafeClass`
202+
- `KeyedObservableClass` instead of `ObservableClass`
203+
- `KeyedObservableThread` instead of `ObservableThread`
204+
- `KeyedObservableThreadSafeClass` instead of `ObservableThreadSafeClass`
204205

205206
*Remember, Keyed Observation is an **extension** of the basic Observation Pattern, so any Keyed Observable is also inherently able to register and notify non-Keyed Observers*
206207

@@ -227,7 +228,7 @@ class TestKeyedObservableClass: KeyedObservableClass<String> {
227228
private var keyValues: [String:String] = ["A":"Hello", "B":"Foo", "C":"Ping"]
228229

229230
func setValue(key: String, value: String) {
230-
withKeyedObservers(for: key) { (key, observer: TestKeyedObservable) in
231+
withKeyedObservers(key: key) { (key, observer: TestKeyedObservable) in
231232
observer.onValueChanged(key: key, oldValue: self.keyValues[key]!, newValue: value)
232233
}
233234
self.keyValues[key] = value
@@ -265,29 +266,29 @@ At this point, we need to consider what Key or Keys our `observer` is going to O
265266

266267
For example, we can Observe just one key:
267268
```swift
268-
observable.addKeyedObserver(for: "A", observer)
269+
observable.addKeyedObserver(key: "A", observer)
269270
```
270271
The above means that `observer` would only have its `onValueChanged` method invoked when the value of key *A* is modified in `observable`.
271272

272273
Likewise, if we only care about key *B*, we can do:
273274
```swift
274-
observable.addKeyedObserver(for: "B", observer)
275+
observable.addKeyedObserver(key: "B", observer)
275276
```
276277

277278
If we care about *both* known keys, we can simply register them both:
278279
```swift
279-
observable.addKeyedObserver(for: ["A", "B"], observer)
280+
observable.addKeyedObserver(keys: ["A", "B"], observer)
280281
```
281282

282283
Also, we can do something particularly clever and basically register the Observer for every Key known to its own Dictionary:
283284
```swift
284-
observable.addKeyedObserver(for: Array(observer.keyValues.keys), observer)
285+
observable.addKeyedObserver(keys: Array(observer.keyValues.keys), observer)
285286
```
286287
The above would register `observer` with `observable` for every *key* contained in `observer`'s `keyValues` dictionary.
287288

288289
Ultimately, you can register the `observer` with the `observable` for any keys you want:
289290
```swift
290-
observable.addKeyedObserver(for: "Foo", observer)
291+
observable.addKeyedObserver(key: "Foo", observer)
291292
```
292293

293294
Let's output the initial values of all of our keys before we invoke any code that would modify their values:

Sources/Observable/Keyed/KeyedObservable.swift

+43-50
Original file line numberDiff line numberDiff line change
@@ -9,120 +9,113 @@
99
/**
1010
Describes any Type (Class or Thread) to which Observers can Subscribe.
1111
- Author: Simon J. Stuart
12-
- Version: 1.1.0
12+
- Version: 2.0.0
1313
- Important: This Protocol can only be applied to Class and Thread types.
1414

1515
See the Base Implementations `ObservableClass` and `ObservableThread`
1616
*/
1717
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
1818
public protocol KeyedObservable: Observable {
19-
/**
20-
Keyed Observables must declare a `TKey` type which must conform to `Hashable`
21-
- Author: Simon J. Stuart
22-
- Version: 1.1.0
23-
*/
24-
associatedtype TKey: Hashable
25-
2619
/**
2720
Registers an Observer against this Observable Type for the given Key
2821
- Author: Simon J. Stuart
29-
- Version: 1.1.0
22+
- Version: 2.0.0
3023
- Parameters:
3124
- key: The Key for which this Observer is subscribed
3225
- observer: A reference to a Class (or Thread) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
3326

3427
Call this every time you need to register an Observer with your Observable.
3528
*/
36-
func addKeyedObserver<TObservationProtocol: AnyObject>(for key: TKey, _ observer: TObservationProtocol)
29+
func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(key: TKey, _ observer: TObservationProtocol)
3730

3831
/**
3932
Registers the Observers against this Observable Type for the given Key
4033
- Author: Simon J. Stuart
41-
- Version: 1.1.0
34+
- Version: 2.0.0
4235
- Parameters:
4336
- key: The Key for which this Observer is subscribed
4437
- observers: A reference to a Classes (or Threads) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
4538

4639
Call this every time you need to register an Observer with your Observable.
4740
*/
48-
func addKeyedObserver<TObservationProtocol: AnyObject>(for key: TKey, _ observers: [TObservationProtocol])
41+
func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(key: TKey, _ observers: [TObservationProtocol])
4942

5043
/**
5144
Registers an Observer against this Observable Type for the given Keys
5245
- Author: Simon J. Stuart
53-
- Version: 1.1.0
46+
- Version: 2.0.0
5447
- Parameters:
5548
- keys: The Keys for which this Observer is subscribed
5649
- observer: A reference to a Class (or Thread) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
5750

5851
Call this every time you need to register an Observer with your Observable.
5952
*/
60-
func addKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observer: TObservationProtocol)
53+
func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observer: TObservationProtocol)
6154

6255
/**
6356
Registers the given Observers against this Observable Type for the given Keys
6457
- Author: Simon J. Stuart
65-
- Version: 1.1.0
58+
- Version: 2.0.0
6659
- Parameters:
6760
- keys: The Keys for which this Observer is subscribed
6861
- observers: A reference to a Classes (or Threads) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
6962

7063
Call this every time you need to register an Observer with your Observable.
7164
*/
72-
func addKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observers: [TObservationProtocol])
65+
func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observers: [TObservationProtocol])
7366

7467
/**
7568
Removes an Observer from this Observable Type for the given Key
7669
- Author: Simon J. Stuart
77-
- Version: 1.1.0
70+
- Version: 2.0.0
7871
- Parameters:
7972
- key: The Key for which this Observer was subscribed
8073
- observer: A reference to a Class (or Thread) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
8174

8275
Call this if you need to explicitly unregister an Observer from your Observable.
8376
*/
84-
func removeKeyedObserver<TObservationProtocol: AnyObject>(for key: TKey, _ observer: TObservationProtocol)
77+
func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(key: TKey, _ observer: TObservationProtocol)
8578

8679
/**
8780
Removes all given Observers from this Observable Type for the given Key
8881
- Author: Simon J. Stuart
89-
- Version: 1.1.0
82+
- Version: 2.0.0
9083
- Parameters:
9184
- key: The Key for which this Observer was subscribed
9285
- observers: A reference to a Classes (or Threads) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
9386

9487
Call this if you need to explicitly unregister an Observer from your Observable.
9588
*/
96-
func removeKeyedObserver<TObservationProtocol: AnyObject>(for key: TKey, _ observers: [TObservationProtocol])
89+
func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(key: TKey, _ observers: [TObservationProtocol])
9790

9891
/**
9992
Removes an Observer from this Observable Type for the given Keys
10093
- Author: Simon J. Stuart
101-
- Version: 1.1.0
94+
- Version: 2.0.0
10295
- Parameters:
10396
- keys: The Keys for which this Observer was subscribed
10497
- observer: A reference to a Class (or Thread) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
10598

10699
Call this if you need to explicitly unregister an Observer from your Observable.
107100
*/
108-
func removeKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observer: TObservationProtocol)
101+
func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observer: TObservationProtocol)
109102

110103
/**
111104
Removes an Observer from this Observable Type for the given Keys
112105
- Author: Simon J. Stuart
113-
- Version: 1.1.0
106+
- Version: 2.0.0
114107
- Parameters:
115108
- keys: The Keys for which this Observer was subscribed
116109
- observers: A reference to a Classes (or Threads) conforming to the desired Observer Protocol, inferred from Generics as `TObservationProtocol`
117110

118111
Call this if you need to explicitly unregister an Observer from your Observable.
119112
*/
120-
func removeKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observers: [TObservationProtocol])
113+
func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observers: [TObservationProtocol])
121114

122115
/**
123116
Iterates all of the registered Observers for this Observable and invokes against them your defined Closure Method for the given Key.
124117
- Author: Simon J. Stuart
125-
- Version: 1.1.0
118+
- Version: 2.0.0
126119
- Parameters:
127120
- key: The Key to which the Observation relates.
128121
- code: The Closure you wish to invoke for each Observer
@@ -140,12 +133,12 @@ public protocol KeyedObservable: Observable {
140133
}
141134
````
142135
*/
143-
func withKeyedObservers<TObservationProtocol>(for key: TKey, _ code: @escaping (_ key: TKey, _ observer: TObservationProtocol) -> ())
136+
func withKeyedObservers<TObservationProtocol, TKey: Hashable>(key: TKey, _ code: @escaping (_ key: TKey, _ observer: TObservationProtocol) -> ())
144137

145138
/**
146139
Iterates all of the registered Observers for this Observable and invokes against them your defined Closure Method for the given Keys.
147140
- Author: Simon J. Stuart
148-
- Version: 1.1.0
141+
- Version: 2.0.0
149142
- Parameters:
150143
- keys: The Keys to which the Observation relates.
151144
- code: The Closure you wish to invoke for each Observer
@@ -163,93 +156,93 @@ public protocol KeyedObservable: Observable {
163156
}
164157
````
165158
*/
166-
func withKeyedObservers<TObservationProtocol>(for keys: [TKey], _ code: @escaping (_ key: TKey, _ observer: TObservationProtocol) -> ())
159+
func withKeyedObservers<TObservationProtocol, TKey: Hashable>(keys: [TKey], _ code: @escaping (_ key: TKey, _ observer: TObservationProtocol) -> ())
167160
}
168161

169162
/**
170163
This extension just implements the simple Macros universally for any implementation of the `KeyedObserverable` protocol
171164
- Author: Simon J. Stuart
172-
- Version: 1.1.0
165+
- Version: 2.0.0
173166
*/
174167
extension KeyedObservable {
175168
/**
176169
Simply iterates multiple observers, and for each, invokes the `addKeyedObserver` implementation taking just that one observer.
177170
- Author: Simon J. Stuart
178-
- Version: 1.1.0
171+
- Version: 2.0.0
179172
*/
180-
public func addKeyedObserver<TObservationProtocol: AnyObject>(for key: TKey, _ observers: [TObservationProtocol]) {
173+
public func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(key: TKey, _ observers: [TObservationProtocol]) {
181174
for observer in observers {
182-
addKeyedObserver(for: key, observer)
175+
addKeyedObserver(key: key, observer)
183176
}
184177
}
185178

186179
/**
187180
Simply iterates multiple keys, and for each, invokes the `addKeyedObserver` implementation taking just that one key.
188181
- Author: Simon J. Stuart
189-
- Version: 1.1.0
182+
- Version: 2.0.0
190183
*/
191-
public func addKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observer: TObservationProtocol) {
184+
public func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observer: TObservationProtocol) {
192185
for key in keys {
193-
addKeyedObserver(for: key, observer)
186+
addKeyedObserver(key: key, observer)
194187
}
195188
}
196189

197190
/**
198191
Simply iterates multiple keys and observers, and for each, invokes the `addKeyedObserver` implementation taking just that one key and observer.
199192
- Author: Simon J. Stuart
200-
- Version: 1.1.0
193+
- Version: 2.0.0
201194
*/
202-
public func addKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observers: [TObservationProtocol]) {
195+
public func addKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observers: [TObservationProtocol]) {
203196
for key in keys {
204197
for observer in observers {
205-
addKeyedObserver(for: key, observer)
198+
addKeyedObserver(key: key, observer)
206199
}
207200
}
208201
}
209202

210203
/**
211204
Simply iterates multiple observers, and for each, invokes the `removeKeyedObserver` implementation taking just that one observer.
212205
- Author: Simon J. Stuart
213-
- Version: 1.1.0
206+
- Version: 2.0.0
214207
*/
215-
public func removeKeyedObserver<TObservationProtocol: AnyObject>(for key: TKey, _ observers: [TObservationProtocol]) {
208+
public func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(key: TKey, _ observers: [TObservationProtocol]) {
216209
for observer in observers {
217-
removeKeyedObserver(for: key, observer)
210+
removeKeyedObserver(key: key, observer)
218211
}
219212
}
220213

221214
/**
222215
Simply iterates multiple keys, and for each, invokes the `removeKeyedObserver` implementation taking just that one key.
223216
- Author: Simon J. Stuart
224-
- Version: 1.1.0
217+
- Version: 2.0.0
225218
*/
226-
public func removeKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observer: TObservationProtocol) {
219+
public func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observer: TObservationProtocol) {
227220
for key in keys {
228-
removeKeyedObserver(for: key, observer)
221+
removeKeyedObserver(key: key, observer)
229222
}
230223
}
231224

232225
/**
233226
Simply iterates multiple keys, and for each, invokes the `removeKeyedObserver` implementation taking just that one key and the one observer.
234227
- Author: Simon J. Stuart
235-
- Version: 1.1.0
228+
- Version: 2.0.0
236229
*/
237-
public func removeKeyedObserver<TObservationProtocol: AnyObject>(for keys: [TKey], _ observers: [TObservationProtocol]) {
230+
public func removeKeyedObserver<TObservationProtocol: AnyObject, TKey: Hashable>(keys: [TKey], _ observers: [TObservationProtocol]) {
238231
for key in keys {
239232
for observer in observers {
240-
removeKeyedObserver(for: key, observer)
233+
removeKeyedObserver(key: key, observer)
241234
}
242235
}
243236
}
244237

245238
/**
246239
Simply iterates multiple keys, and for each, invokes the `withKeyedObservers` implementation taking just that one key.
247240
- Author: Simon J. Stuart
248-
- Version: 1.1.0
241+
- Version: 2.0.0
249242
*/
250-
public func withKeyedObservers<TObservationProtocol>(for keys: [TKey], _ code: @escaping (_ key: TKey, _ observer: TObservationProtocol) -> ()) {
243+
public func withKeyedObservers<TObservationProtocol, TKey: Hashable>(keys: [TKey], _ code: @escaping (_ key: TKey, _ observer: TObservationProtocol) -> ()) {
251244
for key in keys {
252-
withKeyedObservers(for: key, code)
245+
withKeyedObservers(key: key, code)
253246
}
254247
}
255248
}

0 commit comments

Comments
 (0)