如何表示 nil Error Swift 完成块
Posted
技术标签:
【中文标题】如何表示 nil Error Swift 完成块【英文标题】:how to represent nil Error Swift completion block 【发布时间】:2018-03-28 21:27:34 【问题描述】:您好,我在 swift 中有一个 Web 服务工作者对象,它将完成块传递给调用者视图控制器。代码如下:
func getFlightData(for airportCode: String, minutesBehind:String, minutesAhead:String, completion: (([Flight], NSError) -> Void)?)
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "xxxxxxx.com"
urlComponents.path = "/1/airports/"+airportCode+"/flights/flightInfo"
urlComponents.queryItems = [
URLQueryItem(name: "city", value: airportCode),
URLQueryItem(name: "minutesBehind", value: minutesBehind),
URLQueryItem(name: "minutesAhead", value: minutesAhead)
]
guard let url = urlComponents.url else fatalError("Could not create URL from components")
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("xxxxxxxxx", forHTTPHeaderField: "Authorization")
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request) (responseData, response, responseError) in
DispatchQueue.main.async
if let error = responseError
//completion block???
else if let jsonData = responseData
let decoder = JSONDecoder()
do
let posts = try decoder.decode([Flight].self, from: jsonData)
//completion?(posts, nil) ???? what to pass for Error? Successful call
catch
self.showError()
else
//completion block???
self.showError()
task.resume()
调用成功时,我在完成块错误参数中传递了什么值。我不能通过 nil,因为 swift 不允许我这样做。有人可以建议一种更好的方法来进行此 API 调用吗?如何发送完成块等。
【问题讨论】:
【参考方案1】:它不接受nil
,因为您的参数NSError
不是可选的。
声明你的方法签名喜欢
func getFlightData(for airportCode: String, minutesBehind:String, minutesAhead:String, completion: (([Flight], NSError?) -> Void)?)
....
它应该可以工作
【讨论】:
不要使用NSError
; Error
协议更灵活,更符合 Swift 的习惯。
这不是问题,我不知道他的其余实现。如果他使用NSError
可能有一些原因
NSError
符合Error
,因此任何采用Error
的东西都可以接受NSError
。没有理由在 Swift API 中使用 NSError
。
假设......是的......仍然不知道,只是回答他的问题【参考方案2】:
将完成块声明为采用Error?
而不是NSError
,然后您将能够在成功的情况下将nil
传递给它。 ?
是使参数可选的原因,这使得它可以包含 nil
。 (另外,使用 Error
而不是 NSError
,因为它是惯用的 Swift 错误类型)。
或者,您可以让您的完成块采用 Result
枚举,您可以这样定义:
public enum Result<T>
case success(T)
case error(Error)
public func unwrap() throws -> T
switch self
case let .success(ret):
return ret
case let .error(error):
throw error
然后您可以使用.success
或.error
情况,具体取决于操作是成功还是失败。
【讨论】:
完成!我的响应数据呢?我该如何发送?万一出现错误? @AckmanResult
类型用于响应数据和错误相互排斥的情况。如果您可能想在出现错误时读取响应数据,请坚持使用元组实现,但使用 Error?
而不是 NSError
。
我已经做到了,你能在我的代码中告诉我如何进行这些更改吗?我仍然很困惑。我应该保留错误吗?或将 Result 保留在我的完成块中。我对 swift 还很陌生,很难理解这一点
如果您希望能够同时传递响应数据和错误,那么就按照您所做的那样做,但是将NSError
替换为Error?
。您可以完全按照您所做的那样使用它,除了现在您可以传递nil
而不会出现编译器错误。如果收到错误意味着响应数据不相关(常见情况),则使用Result
枚举代替传递响应或错误。
在你的回答中你说“(另外,使用 NSError 而不是 Error,因为它是惯用的 Swift 错误类型)。”您不是说“(另外,使用Error
而不是NSError
,因为它是惯用的Swift 错误类型)”吗?以上是关于如何表示 nil Error Swift 完成块的主要内容,如果未能解决你的问题,请参考以下文章
而委托为 nil 或未实现外围设备:didDiscoverCharacteristicsForService:error: (Corebluetooth, Swift)
使用 NSError 的 Objective C 到 Swift 完成语法