I have a async function func doWork(id: String) async throws -> String
. I want to call this function from a concurrent dispatch queue like this to test some things.
for i in 1...100 {
queue.async {
obj.doWork(id: "foo") { result, error in
...
}
}
}
I want to do this because queue.async { try await obj.doWork() }
is not supported. I get an error:
Cannot pass function of type ‘@Sendable () async throws -> Void’ to parameter expecting synchronous function type
But the compiler does not provide me with a completion handler version of doWork(id:)
. When I call it from Obj C, I am able to use the completion handler version: [obj doWorkWithId: @"foo" completionHandler:^(NSString * val, NSError * _Nullable error) { ... }]
How do I do something similar in Swift?
2
Answers
You can define a DispatchQueue. This DispatchQueue will wait for the previous task to complete before proceeding to the next.
You are initiating an asynchronous task and immediately finishing the dispatch without waiting for
doWork
to finish. Thus the dispatch queue is redundant. One could do:Or, if you wanted to catch/display the errors:
Now, generally in Swift, we would want to remain within structured concurrency and use a task group. But if you are trying to mirror what you’ll experience from Objective-C, the above should be sufficient.
Needless to say, if your Objective-C code is creating a queue solely for the purpose for calling the completion-handler rendition of
doWork
, then the queue is unnecessary there, too. But we cannot comment on that code without seeing it.