Files
letro-ios/ElementX/Sources/Other/Extensions/Observable.swift
Doug a67559299a Update the template screen to use the new(ish) Observation framework. (#4077)
* Update the template screen to use the new(ish) Observation framework.

* Add a variant of deferFulfillment that supports observables.

* Update snapshot fulfilment to work with either a publisher or a stream.
2025-04-30 16:49:23 +01:00

38 lines
1.3 KiB
Swift

//
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import Foundation
extension Observable {
/// Creates an async stream for the specified property on this object. We probably won't need this once SE-0475 is available:
/// https://github.com/swiftlang/swift-evolution/blob/main/proposals/0475-observed.md
///
/// - Parameter property: The key path to the property you would like to observe.
func observe<Value>(_ property: KeyPath<Self, Value>) -> AsyncStream<Value> {
AsyncStream { continuation in
var isActive = true
@Sendable func observe() {
let value = withObservationTracking {
self[keyPath: property]
} onChange: {
// Dispatch the update as this is willSet not didSet.
DispatchQueue.main.async {
guard isActive else { return }
observe()
}
}
continuation.yield(value)
}
continuation.onTermination = { _ in isActive = false }
observe()
}
}
}