繁体   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