I have been testing the async/await functionality previewed in the Swift 5.5 release, but I am unable to collect the results from an async function and display them using SwiftUI. Here is my code:
import SwiftUI
struct AsyncTestView: View {
@State var text: String?
// Async function
func asyncGetText() async -> String {
Thread.sleep(forTimeInterval: 10)
return "My text"
}
// Stores the result of async function
func fetchText() async {
let text = await asyncGetText()
DispatchQueue.main.async {
self.text = text
}
}
var body: some View {
Text(text ?? "Loading")
.onAppear(perform: fetchText)
}
}
This results in the following error:
'async' call in a function that does not support concurrency
Add 'async' to function 'fetchText()' to make it asynchronous
Adding async
to the fetchText()
function then results in the following error on the .onAppear()
function:
Invalid conversion from 'async' function of type '() async -> ()' to synchronous function type '() -> Void'
In this article, they use the @asyncHandler
tag to annotate the fetchText
function, however this results in the warning: '@asyncHandler' has been removed from the language'
.
As per new informations in WWDC session Meet async/await in Swift WWDC21, at 23m:28s this is now done using:
Task {
someState = await someAsyncFunction()
}
Screenshot from the session.
Note that there are more ways to instantiate a task. This is the most basic. You can use Task.detached
as well and both ways can get a priority argument.
Check both the Task docs and the session
Check Explore structured concurrency in Swift WWDC21 at around 23:05 (I recommend the whole session!) for more info.