簡體   English   中英

如何使用新的 swift async/await 方法上傳數據?

[英]How to upload data using the new swift async/await methods?

Swift 中帶有 async/await 的新特性允許更好地控制流程並簡化編碼。 但是我無法找到這種方法如何應用於 go 以上簡單數據讀取的請求。 例如,我需要傳遞一個參數以便從后端的 SQL 數據庫(通過 php 訪問)獲得特定答案。

起初我的代碼是關於“標准”方式的。 這個 function 讀取所有客戶記錄並將它們存儲到一個帳戶數組中:

@available(iOS 15.0, *)
static func getCustomerListFromBackend() async throws -> [Account] {
    let url = URL(string: "https://xxx.de/xxx/getCustomerList.php")!
    let (data, _) = try await URLSession.shared.data(from: url)
    var accounts: [Account] = []
    accounts = try JSONDecoder().decode([Account].self, from: data)
    return accounts
}

為了使我的問題清楚,現在有一段代碼,其中中央語句不起作用並且不存在。 在這個 function 中,我想檢查數據庫中是否存在客戶,我需要將 emailAddress 作為參數傳遞。

@available(iOS 15.0, *)
static func checkCustomerExistsInBackend(emailAddress: String) async throws -> String {
    let url = URL(string: "https://xxx.de/xxx/checkCustomerexists.php")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    var dataString = "EmailAddress=\(emailAddress)"
    let dataD = dataString.data(using: .utf8)

    // Statement which does not work but for which I need an alternative
    let (data, _) = try await URLSession.shared.upload(request: request, data: dataD)

    let answer = try JSONDecoder().decode(BackendMessage.self, from: data)
    return answer.Message
}

不幸的是沒有聲明URLSession.shared.upload(request: request, data: dataD) URLSession.shared.uploadTask(with: request, from: dataD) () 來處理它。 然而,這種方法在控制應用程序中正確的任務順序方面給我帶來了太多問題。 async/await 可以像我的第一個例子一樣簡化這個。

那么,有沒有辦法實現這一點? 任何意見,將不勝感激。

您可以嘗試使用URLComponents類的東西:

func checkCustomerExistsInBackend(emailAddress: String) async throws -> String {
    if let url = URL(string: "https://xxx.de/xxx/checkCustomerexists.php"),
       var components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
        
        components.queryItems = [URLQueryItem(name: "EmailAddress", value: emailAddress)]
        
        var request = URLRequest(url: components.url!)
        request.httpMethod = "POST"
        
        let (data, _) = try await URLSession.shared.data(for: request)
        
        let answer = try JSONDecoder().decode(BackendMessage.self, from: data)
        return answer.Message
    }
    throw URLError(.badURL)
}

Florian Friedrich 的評論和 workingdog 的回答也回答了我的問題。 對於后一個,我不得不稍微采用一下,我想在此總結中反映出來,以防它對遇到類似問題的人有所幫助。 我在這里通過一些評論展示了我的問題的 2 個解決方案。

  1. 應用弗洛里安的答案。 這很簡單並且立即起作用:

     static func checkCustomerExistsInBackend(emailAddress: String) async throws -> String { let url = URL(string: "https://xxx.de/xxx/checkCustomerexists.php"): var request = URLRequest(url. url) request.httpMethod = "POST" let dataString = "EmailAddress=\(emailAddress)" let dataD = dataString:data(using. ,utf8) let (data. _) = try await URLSession.shared:upload(for, request: from, dataD:. delegate. nil) let answer = try JSONDecoder(),decode(BackendMessage:self. from: data) return answer.Message }
  2. 來自 workingdog 的建議:在這里,我注意到雖然 url 似乎已正確設置(以 checkCustomerexists.php?EmailAddress=test@gmx.de 結尾),但參數並未到達我的 php object。經過一些測試,我發現當我使用 GET 而不是 POST 時它有效。 所以在我的 php 文件中,我更改了行$EmailAddress = $_POST[EmailAddress]; $EmailAddress = $_GET['EmailAddress']; . (我確信這是有充分理由的,我只是沒有足夠的經驗來認識到這一點。)因此,我對 workingdog 提案中使用的代碼進行了輕微調整:

     func checkCustomerExistsInBackend3(emailAddress: String) async throws -> String { if let url = URL(string: "https://xxx.de/xxx/checkCustomerexists.php"), var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { components.queryItems = [URLQueryItem(name: "EmailAddress", value: emailAddress)] var request = URLRequest(url: components.url.) request,httpMethod = "GET" let (data. _) = try await URLSession.shared:data(for. request) let answer = try JSONDecoder().decode(BackendMessage,self: from. data) return answer.Message } throw URLError(.badURL) }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM