Why must I wrap a call to call to an async/await method in a Task?

Trying to to convert my old URL functionality to SwiftUI with async/await. While the skeleton below works, am puzzled as to why I must place my call to the method within a Task? When I don't use Task I get the error:

Cannot pass function of type '() async -> Void' to parameter expecting synchronous function type

From the examples I've seen, this wasn't necessary.

So I either I've misunderstood something, or I am doing this incorrectly, and am looking for little but of guidance.

Thank you

Within my SwiftUI view:

Button {
	Task {
		let request = xFile.makePostRequest(xUser: xUser, script: "requestTicket.pl")
		var result = await myNewURL.asyncCall(request: request)
		print("\(result)")
	}
}

From a separate class:

class MyNewURL: NSObject, ObservableObject {
	func asyncCall(request: URLRequest) async -> Int {
		
		do {
			let (data, response) = try await URLSession.shared.data(for: request)
			guard let httpResponse = response as? HTTPURLResponse
			else {
				print("error")
				return -1
			}
			if httpResponse.statusCode == 200 {
				...
			}
		} catch {
			return -2
		}
		return 0
	}
}
Answered by szymczyk in 759522022

You have to wrap calls to async functions in a Task block if the function or closure where you make the call does not support Swift's async await syntax. If you are getting build errors if you remove the Task block, it's a sign the function or closure does not support the async await syntax. See the following article for additional explanation:

https://www.swiftdevjournal.com/fixing-the-async-call-in-a-function-that-doesnt-support-concurrency-error-in-swift/

SwiftUI has a .task modifier you can use to make an async call from a SwiftUI view. You may be able to use it to avoid having to wrap your button code in a Task block. See the following article for an introduction to the .task modifier:

https://www.hackingwithswift.com/quick-start/concurrency/how-to-run-tasks-using-swiftuis-task-modifier

Accepted Answer

You have to wrap calls to async functions in a Task block if the function or closure where you make the call does not support Swift's async await syntax. If you are getting build errors if you remove the Task block, it's a sign the function or closure does not support the async await syntax. See the following article for additional explanation:

https://www.swiftdevjournal.com/fixing-the-async-call-in-a-function-that-doesnt-support-concurrency-error-in-swift/

SwiftUI has a .task modifier you can use to make an async call from a SwiftUI view. You may be able to use it to avoid having to wrap your button code in a Task block. See the following article for an introduction to the .task modifier:

https://www.hackingwithswift.com/quick-start/concurrency/how-to-run-tasks-using-swiftuis-task-modifier

Why must I wrap a call to call to an async/await method in a Task?
 
 
Q