在Swift 2、我怎样才能return JSON 解析错误到完成块?
In Swift 2, how can I return JSON parsing errors to the completion block?
我想在 Swift 2 中创建一个函数,它使用 NS 从 URL 和 returns 中获取数据作为 JSON object URL会议。起初,这似乎很简单。我写了以下内容:
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
}
但是,这不会编译,因为完成块没有声明 "throws"。确切的错误是 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)
}
现在一切都编译得很好,但我丢失了 NSJSONSerialization.JSONObjectWithData
抛出的 NSError。
我是否可以捕获 NSJSONSerialization.JSONObjectWithData
可能抛出的 NSError 并将其传播到完成块而不修改完成块的签名?
我想,你的收获并不详尽,所以你需要这样的东西:
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)
}
解决 Jguffey 的问题。当我尝试像这样调用函数时,我看到了同样的错误:
let taskResult = getJson(url!) {
(any: AnyObject,resp: NSURLResponse,error: NSError) in
应该是这样的:
let taskResult = getJson(url!) {
(any: AnyObject?,resp: NSURLResponse?,error: NSError?) in
NSJSONSerialization 抛出 ErrorType 而不是 NSError。
所以正确的代码是
do {
let object:AnyObject? = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
} catch let caught as ErrorType {
completeWith(nil, response, caught)
}
您还将方法签名更改为 ErrorType。
因此,接受的答案将始终进入 "something else happened" 块,永远不会报告 NSJSONSerialization.JSONObjectWithData 抛出的错误。
我想在 Swift 2 中创建一个函数,它使用 NS 从 URL 和 returns 中获取数据作为 JSON object URL会议。起初,这似乎很简单。我写了以下内容:
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
}
但是,这不会编译,因为完成块没有声明 "throws"。确切的错误是 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)
}
现在一切都编译得很好,但我丢失了 NSJSONSerialization.JSONObjectWithData
抛出的 NSError。
我是否可以捕获 NSJSONSerialization.JSONObjectWithData
可能抛出的 NSError 并将其传播到完成块而不修改完成块的签名?
我想,你的收获并不详尽,所以你需要这样的东西:
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)
}
解决 Jguffey 的问题。当我尝试像这样调用函数时,我看到了同样的错误:
let taskResult = getJson(url!) {
(any: AnyObject,resp: NSURLResponse,error: NSError) in
应该是这样的:
let taskResult = getJson(url!) {
(any: AnyObject?,resp: NSURLResponse?,error: NSError?) in
NSJSONSerialization 抛出 ErrorType 而不是 NSError。
所以正确的代码是
do {
let object:AnyObject? = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
} catch let caught as ErrorType {
completeWith(nil, response, caught)
}
您还将方法签名更改为 ErrorType。
因此,接受的答案将始终进入 "something else happened" 块,永远不会报告 NSJSONSerialization.JSONObjectWithData 抛出的错误。