Я стремлюсь к следующему использованию:
Код: Выделить всё
@MainActor func waitForLifecycleEvent(_ applicationState: UIApplication.State = .active) async
core/kotlinx.coroutines/suspend- cancellable-coroutine.html)
Чтобы вы могли реализовать это следующим образом: https://gist.github.com/kibotu/bd4eb5d3 ... 103a827df8
Где вы можете использовать добавление обратного вызова, но также иметь возможность снова правильно очистить.
В Swift у нас есть withTaskCancellationHandler, который может обрабатывать отмену, но не поддерживает обратный вызов, поскольку эта операция возвращается немедленно.
И у нас есть withCheckedThrowingContinuation, который обрабатывает обратные вызовы, но не обрабатывает отмену, что означает, что у нас нет возможности выполнить очистку снова. p>
И даже объединения этих двух было бы недостаточно из-за того, что переменные I распределяются между задачами, поэтому для очистки во всех случаях нам дополнительно понадобится объект-оболочка с deinit, чтобы очистка.
Мой первый грубый, казалось бы, рабочий подход выглядит так:
Код: Выделить всё
import UIKit
@MainActor
public func waitForLifecycleEvent(_ applicationState: UIApplication.State = .active) async {
// Return immediately if already in foreground
if UIApplication.shared.applicationState == applicationState { return }
let wrapper = ObserverWrapper()
do {
try await withTaskCancellationHandler(
operation: {
// Wait for notification asynchronously.
try await withCheckedThrowingContinuation { continuation in
switch applicationState {
case .active:
// Register for the notification.
let observer = NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main) { _ in
continuation.resume()
}
wrapper.observer = observer
case .inactive, .background:
// Register for the notification.
let observer = NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { _ in
continuation.resume()
}
wrapper.observer = observer
@unknown default:
CorePlugin.logInfo("[waitForLifecycleEvent] unknown default \(applicationState)")
}
}
}, onCancel: {
// Cancellation handler is called if the task is cancelled. We need to unregister observer.
wrapper.observer.map(NotificationCenter.default.removeObserver)
})
} catch {
// ignore
}
}
enum AwaitForForegroundError: Error {
case cancelled
}
private final class ObserverWrapper {
var observer: NSObjectProtocol?
deinit {
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
Заранее спасибо
Подробнее здесь: https://stackoverflow.com/questions/786 ... inin-swift
Мобильная версия