-
-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add variadic generics version of Defaults.updates()
#191
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -292,13 +292,64 @@ extension Defaults { | |
} | ||
} | ||
|
||
// We still keep this as it can be useful to pass a dynamic array of keys. | ||
/** | ||
Observe updates to multiple stored values. | ||
|
||
- Parameter keys: The keys to observe updates from. | ||
- Parameter initial: Trigger an initial event on creation. This can be useful for setting default values on controls. | ||
|
||
```swift | ||
Task { | ||
for await (foo, bar) in Defaults.updates([.foo, .bar]) { | ||
print("Values changed:", foo, bar) | ||
} | ||
} | ||
``` | ||
*/ | ||
public static func updates<each Value: Serializable>( | ||
_ keys: repeat Key<each Value>, | ||
initial: Bool = true | ||
) -> AsyncStream<(repeat each Value)> { | ||
.init { continuation in | ||
func getCurrentValues() -> (repeat each Value) { | ||
(repeat self[each keys]) | ||
} | ||
|
||
var observations = [DefaultsObservation]() | ||
|
||
if initial { | ||
continuation.yield(getCurrentValues()) | ||
} | ||
|
||
for key in repeat (each keys) { | ||
let observation = DefaultsObservation(object: key.suite, key: key.name) { _, _ in | ||
continuation.yield(getCurrentValues()) | ||
} | ||
|
||
observation.start(options: []) | ||
observations.append(observation) | ||
} | ||
|
||
let immutableObservations = observations | ||
|
||
continuation.onTermination = { _ in | ||
// `invalidate()` should be thread-safe, but it is not in practice. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious about this. I thought that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not 100% sure. I have seen KVO crashes in some of my apps that may have been caused by some threading problems in macOS. I prefer to keep it limited to this code until I can 100% confirm it. This is just a precaution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it! Thanks for the explanation! |
||
DispatchQueue.main.async { | ||
for observation in immutableObservations { | ||
observation.invalidate() | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
// We still keep this as it can be useful to pass a dynamic array of keys. | ||
/** | ||
Observe updates to multiple stored values without receiving the values. | ||
|
||
- Parameter keys: The keys to observe updates from. | ||
- Parameter initial: Trigger an initial event on creation. This can be useful for setting default values on controls. | ||
|
||
```swift | ||
Task { | ||
for await _ in Defaults.updates([.foo, .bar]) { | ||
|
@@ -307,7 +358,7 @@ extension Defaults { | |
} | ||
``` | ||
|
||
- Note: This does not include which of the values changed. Use ``Defaults/updates(_:initial:)-88orv`` if you need that. You could use [`merge`](https://github.com/apple/swift-async-algorithms/blob/main/Sources/AsyncAlgorithms/AsyncAlgorithms.docc/Guides/Merge.md) to merge them into a single sequence. | ||
- Note: This does not include which of the values changed. Use ``Defaults/updates(_:initial:)-l03o`` if you need that. | ||
*/ | ||
public static func updates( | ||
_ keys: [_AnyKey], | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I'm intentionally not using CompositeDefaultsObservation for simplicity, as it's not really needed here.