In SwiftUI, the new task modifier handles creating a new task on a UI action or on view appearance. It also ensures that a task isn't restarted on a second action if the task from the first action is still in progress.
What is the best way of getting the same behavior in non-SwiftUI code? Here's my best attempt:
class Controller: UIViewController {
var task: Task? = nil
// ...
func didTapStart() {
guard self.task == nil || self.task.isCancelled else { return }
self.task = Task { .... }
}
}
Will this work? Will isCancelled be true when a task successfully completes, or only if it's explicitly cancelled? Is there a better way?
adamkemp
(Adam Kemp)
2
In C# the pattern I used to use was this (adapted to Swift concurrency):
func didTapStart() {
disableStartButton();
Task {
// ... await whatever
enableStartButton();
}
}
You could also do things like enable a spinner, show a progress bar, or whatever makes sense. The idea is that it's better to indicate to the user that something happened (visually) and that further UI actions won't do anything rather than let them keep tapping the button and wonder "is it working? did I just make it happen twice? what's going on?"