Skip to content

Feedback on AsyncLet #2

@malhal

Description

@malhal

Hi Eric I saw your blog post linked in iOS Dev Weekly - Issue 595. I had a play around with the project, trying all the different versions of the download and thought it might help to send a few comments along.

When async/await was added to SwiftUI and we got the .task and .task(id:) modifiers, those are instead of Task { } because as you've noticed, that is fire and forget. With .task(id:) it saves you from having to hold onto a task handle in a @State, like you are doing in CancelTaskView fileDownloadTask. To use these modifiers all you need to do is set a bool in the button press , e.g. isDownloading, to bounce it over to task(id:isDownloading) which is an async context with lifetime tied to the View. What happens is when the View appears the task is started, it's cancelled when it disappears and also if the id param changes, it is cancelled and restarted, so it would look like this:

Button("Download") {
    isDownloading.toggle()
}
.task(id:isDownloading) {
    if (!isDownloading) {
       return
    }
    do {
       result = try await downloadFile()
    }
    catch {
        errorMessage = error.description
     }
}

Since now we have an async context tied to the view on screen, there is now no need to use a reference type to achieve the same thing, i.e. an ObservableObject. We can simply set our results or errors on an @State. The actual async function can be anywhere you like, some like to put it as a static func on the downloaded model type, so it can be tested independently.

(And by the way I noticed a serious mistake at in line 16 of CancelTaskMultipleView if you init an object in a View struct like as an @ObservedObject instead of @StateObject it is lost and reinit every time the View struct is recreated. It's best to never init any objects in a View's init or in body, even things like NSFormatters or NSPredicates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions