I recently changed my http request method to async/await in swift.
func httpRequest(requestType:HTTPRequestType, parameter:Parameter = Parameter()) async throws -> Data {
// do some preparation depending on requestType and parameter,
// e.G. find the right URL, setting http-method to POST / GET / DELETE / PUT and generate headers and body
let (data, response):(Data, URLResponse) = try await {
do {
return try await self.httpSession.data(for: request)
} catch {
throw HTTPRequestError.noNetwork // check for network errors
}
}()
// Handle Response and return Data-Object or throw, for example if login is not correct
}
It all works fine, as long as I call ONE function - for example
func login(username:String, password:String) async throws {
let dataCredentials = try await httpRequest(requestType: .login)
let credentials = try await decodeData(dataCredentials)
// Request own userdata
let dataUserdata = try await httpRequest(requestType: .requestOwnUserData)
let userdata = try await decodeData(dataUserData)
// Request users notifications
let dataNotifications = try await httpRequest(requestType: .requestUserNotifications)
let notifications = try await decodeData(dataNotifications)
// and some more actions
}
This so far works very well - I do get a problem though as soon as the user presses another button. This - obviously - creates a new task that does not "queue" in the login, but creates a separate thread that is being worked on. It might happen though that there are dependencies - so I want to make sure that all task are being send to the server in that order that my user performed them. For now, I call my requests like this:
Button(action: {
Task {
do {
try await login(username: username, password: password)
} catch let error {
// handle error
}
}
}, label: {
Text("Login")
})
In a perfect world I could also count how many tasks are left there, but that's not essential. Though - in this case I could/would also split up my login() into severals tasks.
async/await. In traditionalURLSessionTaskpatterns, when you start a network request, it is asynchronous. Start more requests, and they will run concurrently. Typically, you simply would not allow them to tap more buttons until they had successfully signed in. You wouldn't just add the requests before you successfully logged in, because what if login failed?Taskreference andawaitit, e.g., stackoverflow.com/a/70703295/1271826.