I have a function that takes 2 callbacks. I want to convert this into async/await. But how can I await while continuously returning the progress also?
I am using https://github.com/yannickl/AwaitKit to get rid of callbacks.
typealias GetResultCallBack = (String) -> Void
typealias ProgressCallBack = (Double) -> Void
func getFileFromS3(onComplete callBack: @escaping GetResultCallBack,
progress progressCallback: @escaping ProgressCallBack) {
}
I am using it like this:
getFileFromS3() { [weak self] (result) in
guard let self = self else { return }
// Do something with result
} progress: { [weak self] (progress) in
guard let self = self else { return }
DispatchQueue.main.async { [weak self] in
guard let self = self else {return}
// Update progress in UI
}
}
Here is what converted code looks without progress reporting:
func getFileFromS3() -> Promise<String> {
return async {
// return here
}
}
2
Answers
You could use a technique similar to this:
https://developer.apple.com/documentation/foundation/urlsession/3767352-data
As you can see from the signature…
…it is async, but it also takes a delegate object:
https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate
As you can see, that delegate receives callbacks for task progress. You can declare something similar, and thus feed that info from the delegate over to the main actor and the interface.
I took a while but I finally achieved this result, first you have to start the task setting a delegate:
In your delegate you subscribe to the progress update:
Don’t forget that "progressObservation" needs to be a strong reference