Is it possible to get the current task from within an async function?
I found withUnsafeCurrentTask(body:) and UnsafeCurrentTask. The documentation of UnsafeCurrentTask says:
[...] use the task property of UnsafeCurrentTask to access an instance of Task that you can store long-term and interact with outside of the closure body. [...]
However, it looks like this property is not available (Xcode 13 Beta 3) and I think it is also not mentioned in the Proposal.
Context: I want to get the current task during the execution of the closure that I pass to Task.init(priority:operation:) to be able to cancel the current task later.
Given below is my understanding (I could be wrong):
You could use try Task.checkCancellation to check if the current task is cancelled, and I don't think you need to pass it around. If a parent task is cancelled all it's child tasks would be cancelled.
The problem is that this Task I have does not have a parent Task. I use Task.checkCancellation() to check for cancellation but I want to get the Task to be able to cancel the Task in the first place.
The thing is that I call a method which does not use the new concurrency features from Swift and which may want to cancel the current task asynchronously. I want to give this method a Task so that it can cancel it. Because I need to call this method from inside the operation closure from Task.init(priority:operation:) I can't use the Task returned from the initializer.
I'm also facing a similar use case, I'm not sure what's the best design.
I access the AuthorizationController environment from a SwiftUI view.
In this view, when a button is tapped, I call a function that looks like this:
func doSomething() {
Task {
do {
let result = try await featureModel.doSomething(
with: authorizationController
)
} catch {
print(error)
}
}
}
Inside the feature model (which is an ObservableObject), I want to access this Task and be able to cancel it.
I could create a Published property inside the feature model that stores the Task and every view that interacts with it must do featureModel.currentTask = Task { ... }, but this doesn't seem like good design (me or some other developer might forget to assign the task to the property).
I could also move the whole Task { ... } closure to inside featureModel.doSomething(with:) and not make it async but this would mean I can't return something inside of it and I would have to introduce a completion closure parameter to it to complete with the result.
The ideal design IMO is to keep featureModel.doSomething(with:) and regardless from which Task it's called from, it can get it at run-time and cancel it.
Does Swift have this ability or another possible solution that I'm not aware of?