【问题标题】:How to Return HTTP Request Data in a Function Call in Swift?如何在 Swift 的函数调用中返回 HTTP 请求数据?
【发布时间】:2022-01-14 05:50:07
【问题描述】:

我想做一个通用的 HTTP 请求函数。我看到的代码不会将数据返回给调用者。相反,它会在函数中打印出错误代码或解析的 JSON 对象。就我而言,我想将(数据、响应、错误)返回给调用者。

func performHTTPRequest(urlString: String) -> (Data, URLResponse, Error) {
    
    
   if let url = URL(string: urlString) {
       
       let session = URLSession(configuration: .default)
       
       let task = session.dataTask(with: url) {(data, response, error) in

       // some logic

       }

       task.resume()

   }

}

问题是三个变量(数据、响应、错误)在闭包之外不可用。如果我将它们分配给闭包内的全局变量,编译器会抱怨全局变量不在范围内。

另外,我应该将返回(数据、响应、错误)语句放在哪里?在 task.resume() 之前还是之后?谢谢

【问题讨论】:

  • 你想使用异步版本的 URLSession 的数据任务。

标签: swift http request


【解决方案1】:

简短的回答是,你不能。您可以使用 Swift 5.5 中新的 async/await 语法来模拟同步网络调用。 (我还没有机会在我自己的项目中使用 async/await,所以我必须查一下以指导您。)

如果没有 async/await,您将需要重构您的函数以获取完成处理程序。然后,一旦数据任务完成,您将使用结果调用完成处理程序。

这个问题一直出现在 SO 上。您应该能够找到几十个为异步网络编写基于完成处理程序的函数的示例。

【讨论】:

  • 谢谢。即使使用完成处理程序,返回的 json 对象也只存在于会话的上下文中。无法复制到处理程序方法中的全局变量。看来我必须使用委托/协议设计模式将数据传递给调用者。这是正确的吗?
【解决方案2】:

例如你可以这样做

struct Message: Decodable {
  var username: String
  var message: String
}

enum RequestError: Error {
  case invalidURL
  case missingData
}


func performHTTPRequest(urlString: String) async throws -> Message{

  guard let url = URL(string: urlString) else {throw RequestError.invalidURL}
  guard let (data, response) = try? await URLSession.shared.data(from: url) else{throw RequestError.invalidURL}
  guard (response as? HTTPURLResponse)?.statusCode == 200 else {throw RequestError.invalidURL}
  let decoder = JSONDecoder()
  guard let jsonResponse = try? decoder.decode(Message.self, from: data) else {throw RequestError.missingData}
  return jsonResponse
   
}

并调用函数

do {
    try await performHTTPRequest(urlString: "wwww.url.com")
} catch RequestError.invalidURL{
    print("invalid URL")
} catch RequestError.missingData{
    print("missing data")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2021-06-28
    • 2021-08-14
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    相关资源
    最近更新 更多