Isn't the real problem that this is a misuse of Task? A Task, as you've discovered, is not really of itself a thing you can await. If the goal is to run slow code in the background, use an actor. Then you can cleanly call an actor method with await.
let myActor = MyActor()
await myActor.doFirStuff()
await myActor.doAirportStuff()
self.isVerifyingRoute = false
However, we also need to make sure we're on the main thread when we talk to self
— something that your code omits to do. Here's an example:
actor MyActor {
func doFirStuff() async {
print("starting", #function)
await Task.sleep(2 * 1_000_000_000)
print("finished", #function)
}
func doAirportStuff() async {
print("starting", #function)
await Task.sleep(2 * 1_000_000_000)
print("finished", #function)
}
}
func test() {
let myActor = MyActor()
Task {
await myActor.doFirStuff()
await myActor.doAirportStuff()
Task { @MainActor in
self.isVerifyingRoute = false
}
}
}
Everything happens in the right mode: the time-consuming stuff happens on background threads, and the call to self
happens on the main thread. A cleaner-looking way to take care of the main thread call, in my opinion, would be to have a @MainActor
method:
func test() {
let myActor = MyActor()
Task {
await myActor.doFirStuff()
await myActor.doAirportStuff()
self.finish()
}
}
@MainActor func finish() {
self.isVerifyingRoute = false
}
I regard that as elegant and clear.