在Swift 2中,如何将JSON解析错误返回到完成块?

And*_*y S 11 try-catch swift2

我想在Swift 2中创建一个函数,该函数从URL获取数据并使用NSURLSession将其作为JSON对象返回.起初,这看起来非常简单.我写了以下内容:

func getJson(url:NSURL, completeWith: (AnyObject?,NSURLResponse?,NSError?)->Void) -> NSURLSessionTask? {

    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url) {
        (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

        if error != nil {
            completeWith(nil, response, error)
        }

        if let data = data {

            do {
                let object:AnyObject? = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
            } catch let caught as NSError {
                completeWith(nil, response, caught)
            }

            completeWith(object, response, nil)

        } else {
            completeWith(nil, response, error)
        }
    }

    return task
}
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译,因为完成块不会声明"抛出".确切的错误是Cannot invoke 'dataTaskWithURL' with an argument list of type '(NSURL, (NSData?, NSURLResponse?, NSError?) throws -> Void)'.即使我在我的do/catch语句中捕获所有错误,Swift仍然希望将NSError传播到链中.我可以看到它的唯一方法是使用try!,像这样:

if let data = data {

    let object:AnyObject? = try! NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
    completeWith(object, response, nil)

} else {
    completeWith(nil, response, error)
}
Run Code Online (Sandbox Code Playgroud)

现在一切都编译得很好,但我已经失去了被抛出的NSError NSJSONSerialization.JSONObjectWithData.

是否可以捕获可能引发的NSError NSJSONSerialization.JSONObjectWithData并将其传播到完成块而不修改完成块的签名?

Ser*_*sky 21

我认为,你的捕获并非详尽无遗,所以你需要这样的东西:

do
{
  let object:AnyObject? = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
  completeWith(object, response, nil)
} catch let caught as NSError {
  completeWith(nil, response, caught)
} catch {
  // Something else happened.
  // Insert your domain, code, etc. when constructing the error.
  let error: NSError = NSError(domain: "<Your domain>", code: 1, userInfo: nil)
  completeWith(nil, nil, error)
}
Run Code Online (Sandbox Code Playgroud)