mirror of
https://github.com/samsonjs/AsyncMonitor.git
synced 2026-03-25 08:25:47 +00:00
63 lines
2.7 KiB
Swift
63 lines
2.7 KiB
Swift
public import Foundation
|
|
|
|
extension KeyPath: @unchecked @retroactive Sendable where Value: Sendable {}
|
|
|
|
public extension NSObjectProtocol where Self: NSObject {
|
|
/// Returns an `AsyncSequence` of `Value`s for all changes to the given key path on this object.
|
|
///
|
|
/// - Parameters:
|
|
/// - keyPath: The key path to observe on this object. The value must be `Sendable`.
|
|
/// - options: KVO options to use for observation. Defaults to an empty set.
|
|
func values<Value: Sendable>(
|
|
for keyPath: KeyPath<Self, Value>,
|
|
options: NSKeyValueObservingOptions = []
|
|
) -> AsyncStream<Value> {
|
|
let (stream, continuation) = AsyncStream<Value>.makeStream()
|
|
let token: NSKeyValueObservation? = self.observe(keyPath, options: options) { object, _ in
|
|
continuation.yield(object[keyPath: keyPath])
|
|
}
|
|
// A nice side-effect of this is that the stream retains the token automatically.
|
|
let locker = ValueLocker(value: token)
|
|
continuation.onTermination = { _ in
|
|
locker.modify { $0 = nil }
|
|
}
|
|
return stream
|
|
}
|
|
}
|
|
|
|
@available(iOS 18, macOS 15, *)
|
|
public extension NSObjectProtocol where Self: NSObject {
|
|
/// Observes changes to the specified key path on the object and asynchronously yields each value. Values must be `Sendable`.
|
|
///
|
|
/// - Parameters:
|
|
/// - keyPath: The key path to observe on this object. The value must be `Sendable`.
|
|
/// - options: KVO options to use for observation. Defaults to an empty set.
|
|
/// - changeHandler: A closure that's executed with each new value.
|
|
func monitorValues<Value: Sendable>(
|
|
for keyPath: KeyPath<Self, Value>,
|
|
options: NSKeyValueObservingOptions = [],
|
|
changeHandler: @escaping (Value) -> Void
|
|
) -> any AsyncCancellable {
|
|
values(for: keyPath, options: options)
|
|
.monitor(changeHandler)
|
|
}
|
|
}
|
|
|
|
@available(iOS, introduced: 17, obsoleted: 18)
|
|
@available(macOS, introduced: 14, obsoleted: 15)
|
|
public extension NSObjectProtocol where Self: NSObject {
|
|
/// Observes changes to the specified key path on the object and asynchronously yields each value. Values must be `Sendable`.
|
|
///
|
|
/// - Parameters:
|
|
/// - keyPath: The key path to observe on this object. The value must be `Sendable`.
|
|
/// - options: KVO options to use for observation. Defaults to an empty set.
|
|
/// - changeHandler: A closure that's executed with each new value.
|
|
func monitorValues<Value: Sendable>(
|
|
for keyPath: KeyPath<Self, Value>,
|
|
options: NSKeyValueObservingOptions = [],
|
|
changeHandler: @escaping @Sendable (Value) -> Void
|
|
) -> any AsyncCancellable {
|
|
values(for: keyPath, options: options)
|
|
.monitor(changeHandler)
|
|
}
|
|
}
|