/Volumes/MyData/AppDevXcode7/Training/iOS8.0Dev/connecting_swift/connecting_swift/JSONViewController.swift:28:78:抛出类型'(_,_,_)抛出函数的转换无效 - > _'到非投掷函数类型'(NSData?,NSURLResponse?,NSError?) - >空隙'
@IBAction func callURLButtonTapped(sender: AnyObject){
urlTextField.resignFirstResponder()
let requestedURL = NSURL(string: urlTextField.text!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(requestedURL!, completionHandler: {data, response, error in
if let actualError = error {
let errorResponse = "Response status: \(actualError.description)"
self.responseText.text = errorResponse
}else{
var parseError: NSError?
let jsonArray = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError ) as! NSDictionary
if let actualParseError = parseError {
let errorResponse = "Response status: \(actualParseError.description)"
self.responseText.text = errorResponse
}else{
dispatch_async(dispatch_get_main_queue(), {
let httpResponse = response as! NSHTTPURLResponse
let responseStatus = "Response status: \(httpResponse.statusCode)"
self.responseStatusLabel.text = responseStatus
let responseAsString = jsonArray.description
self.responseText.text = responseAsString
})
}
}
})
task.resume()
}
答案 0 :(得分:1)
当前Swift编译器中的错误消息并不总是指示问题的根本原因。 (特别是在这样的情况下,如果在闭包内深处传递类型检查错误并传递给某个函数,则会给出关于闭包函数而不是根本原因的错误消息。) File bugs当你看到这些类型的错误时,Apple可以更好地提供好的错误消息。
在这里,对于新的错误处理语法存在问题是正确的,但它得到的位置错误(因为嵌套的闭包事件)。 你的问题就在这一行:
let jsonArray = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError ) as! NSDictionary
NSJSONSerialization.JSONObjectWithData(_:options:error:)
调用是使用Swift 2.0转换为throws
函数的方法之一。所以你需要这样称呼它:
let jsonArray = try NSJSONSerialization.JSONObjectWithData(data, options: [] ) as! NSDictionary
另请注意,nil options
参数变为空OptionSetType
字面值(空括号),因为选项集是Swift 2中的实际集。
但是等等......你仍然在这里得到一个编译错误,因为data
是一个必须被检查/解包的可选项。而且你需要一个合适的地方来处理你的错误。让我们改进这个方法来处理正确位置的所有内容:
@IBAction func callURLButtonTapped(sender: AnyObject){
urlTextField.resignFirstResponder()
let requestedURL = NSURL(string: urlTextField.text!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(requestedURL!, completionHandler: {data, response, error in
// First, make sure we have real data, and handle the error if not.
// (That's a better use of the API contract than checking the error parameter, because the error parameter is not guaranteed to be non-nil in all cases where correct data is received.)
// Use a guard clause to keep the "good path" less indented.
guard let actualData = data else {
self.responseText.text = "Response status: \(error!.description)"
return
}
do {
// Use do/try/catch to call the new throwing API.
// Use the new OptionSetType syntax, too.
let jsonArray = try NSJSONSerialization.JSONObjectWithData(actualData, options: [])
dispatch_async(dispatch_get_main_queue(), {
let httpResponse = response as! NSHTTPURLResponse
self.responseStatusLabel.text = "Response status: \(httpResponse.statusCode)"
self.responseText.text = jsonArray.description
})
} catch let parseError {
// No need to treat as NSError and call description here, because ErrorTypes are guaranteed to be describable.
self.responseText.text = "Response status: \(parseError)"
}
})
task.resume()
}
答案 1 :(得分:0)
在Swift 2,XCode 7中,Apple用ErrorType替换了NSError。
您在自己的代码中明确使用NSError。这适用于大多数情况(如分配)但不是全部。 用ErrorType替换您自己的NSError用法。