As others have said, you need to wrap your async call into a custom Observable
. However, instead of using the type erased class, I'd recommend creating a Single
:
extension Single {
static func fromAsync<T>(_ fn: @escaping () async throws -> T) -> Single<T> {
.create { observer in
let task = Task {
do { try await observer(.success(fn())) }
catch { observer(.failure(error))}
}
return Disposables.create { task.cancel() }
}
}
}
A Single
suits better, since it models an observable that emits exactly one element, which means in the first place better semantics, better transmitting of the intent, and increased compiler support when creating and consuming the observable.
Usage:
let fetchAuthSession = Single.fromAsync { try await Amplify.Auth.fetchAuthSession() }
, or (functional programming style):
let fetchAuthSession = Single.fromAsync(Amplify.Auth.fetchAuthSession)