Эквивалент suspendCancellableCoroutine из Kotlinin Swift?IOS

Программируем под IOS
Ответить
Anonymous
 Эквивалент suspendCancellableCoroutine из Kotlinin Swift?

Сообщение Anonymous »

Как лучше всего преобразовать системный обратный вызов, например добавить NotificationCenter.default.addObserver, а также удалить прослушиватель при ошибке/отмене, завернутый в асинхронную функцию?
Я стремлюсь к следующему использованию:

Код: Выделить всё

@MainActor func waitForLifecycleEvent(_ applicationState: UIApplication.State = .active) async
В котлине есть [suspendCancellableCoroutine](https://kotlinlang.org/api/kotlinx.coro ... oroutines-
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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»