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
}
ただし、完了ブロックは「スロー」を宣言していないため、コンパイルされません。正確なエラーは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)
}
これですべてが正常にコンパイルされますが、 によってスローされる NSError が失われましたNSJSONSerialization.JSONObjectWithData
。
潜在的にスローされた NSError をキャプチャしてNSJSONSerialization.JSONObjectWithData
、完了ブロックの署名を変更せずに完了ブロックに伝播できることはありましたか?