Remove observeOnce method that’s not necessary

This commit is contained in:
Max Radermacher
2025-05-13 13:46:41 -05:00
committed by GitHub
parent c9d1f7a370
commit e006f4e129
2 changed files with 8 additions and 43 deletions

View File

@@ -6,18 +6,17 @@
import Foundation
import SignalServiceKit
class AppActivePrecondition: Precondition {
private let appContext: AppContext
struct AppActivePrecondition: Precondition {
private let _precondition: NotificationPrecondition
init(appContext: AppContext) {
self.appContext = appContext
self._precondition = NotificationPrecondition(
notificationName: UIApplication.didBecomeActiveNotification,
isSatisfied: { appContext.isAppForegroundAndActive() },
)
}
@MainActor
func waitUntilSatisfied() async -> WaitResult {
if appContext.isAppForegroundAndActive() {
return .satisfiedImmediately
}
await NotificationCenter.default.observeOnce(UIApplication.didBecomeActiveNotification)
return .wasNotSatisfiedButIsNow
return await self._precondition.waitUntilSatisfied()
}
}

View File

@@ -12,40 +12,6 @@ import Foundation
// possible risk of deadlock. These methods also ensure that
// the notifications are always fired on the main thread.
extension NotificationCenter {
/// Waits until `name`/`object` is posted.
public func observeOnce(_ name: Notification.Name, object: Any? = nil) async {
await withCheckedContinuation { continuation in
// Concurrency in this method is nontrivial. There are at least two
// relevant race conditions:
//
// (1) Multiple threads could post a notification at the same time, and
// this will trigger multiple callbacks, even if you call `removeObserver`
// as quickly as possible. We guard against this with an atomic
// compare-and-swap to set the observer to nil.
//
// (2) When initially registering the observer, it's possible that another
// thread could be posting the notifiation at the same time. If the
// notification callback happens before we've assigned the initial value to
// the atomic observer value, we'll drop that notification. We avoid that
// problem by ensuring that the `addObserver` call and assignment of the
// observer happen atomically.
//
// Memory management in this method is also non-trivial. The observer
// captured in the block must be set to nil to avoid leaking memory.
let observer = AtomicOptional<NSObjectProtocol>(nil, lock: .init())
_ = observer.map { _ in
return addObserver(forName: name, object: object, queue: nil, using: { [weak self] notification in
guard let observer = observer.swap(nil) else {
return
}
self?.removeObserver(observer)
continuation.resume(returning: ())
})
}
}
}
public func postOnMainThread(_ notification: Notification) {
DispatchQueue.main.async {
self.post(notification)