2 years ago

#70177

test-img

JacquesNorris

How to create a task stack in swift with async/await http-method

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.

swift

async-await

httprequest

dispatch-queue

0 Answers

Your Answer

Accepted video resources