Home > Software engineering >  How to return variable defined in Task in Swift
How to return variable defined in Task in Swift

Time:05-11

I have a class Artist, and below is a function to create a new artist and insert it to my library array. Because insertToArtists(artist:) is a asynchronous function, I have to wrap it in Task. But I also want my newArtist to return the artist just created.

My code is like below, but Xcode told me an error: No 'init' candidates produce the expected contextual result type 'Artist'

func newArtist(name: String, notes: String, artwork: NSImage?) -> Artist {
    Task {
        let artist = Artist(name: name, notes: notes, artwork: artwork)
        await insertToArtists(artist: artist)
        return artist
    }
}

But if I make my code like this below. It won't work right. It seems that it returns artist before it's been insertToArtist(artist:). How can I return artist after it's been inserted. I would appreciate your help.

func newArtist(name: String, notes: String, artwork: NSImage?) -> Artist {
    let artist = Artist(name: name, notes: notes, artwork: artwork)
    Task {
        await insertToArtists(artist: artist)
    }
    return artist
}

CodePudding user response:

Well, it would be useful to know how newArtist is used, but I believe you will need to make it async as well.

func newArtist(name: String, notes: String, artwork: NSImage?) async -> Artist {
    let artist = Artist(name: name, notes: notes, artwork: artwork)
    await insertToArtists(artist: artist)
    return artist
}

And then use Task where you are calling newArtist

func whereYouUseNewArtist() {
   //YourCode
   Task {
      //YourCode
      x = await newArtist(name: name, notes: notes, artwork: artwork)
      //YourCode
   }
//YourCode
}

If you need to update your UI with the result of newArtist, remember to do it in the main thread. You can do it by adding @MainActor to where you use it. Example:

let artistToShowOnUI: Artist
@MainActor func whereYouUseNewArtist() {
    Task {
       artistToShowOnUI = await newArtist(name: name, notes: notes, artwork: artwork)
    }
}
  • Related