从 '(_, _, _) throws -> ()' 类型的抛出函数到非抛出函数类型 '(URLResponse?, Data?, Error?) -> Void 的无效转换
Posted
技术标签:
【中文标题】从 \'(_, _, _) throws -> ()\' 类型的抛出函数到非抛出函数类型 \'(URLResponse?, Data?, Error?) -> Void 的无效转换【英文标题】:Invalid conversion from throwing function of type '(_, _, _) throws -> ()' to non-throwing function type '(URLResponse?, Data?, Error?) -> Void从 '(_, _, _) throws -> ()' 类型的抛出函数到非抛出函数类型 '(URLResponse?, Data?, Error?) -> Void 的无效转换 【发布时间】:2017-05-30 17:50:19 【问题描述】:我正在尝试按照 Ray Wenderlich 网站上的教程学习使用 Instruments。示例代码是用 Swift 2 编写的,我相信在我被允许运行它之前,我必须将代码迁移到最新的 Swift 版本。我已经完成了转换错误的一半,但我对以下代码区域感到困惑:
class Flickr
let processingQueue = OperationQueue()
func searchFlickrForTerm(_ searchTerm: String, completion : @escaping (_ results: FlickrSearchResults?, _ error : NSError?) -> Void)
let searchURL = flickrSearchURLForSearchTerm(searchTerm)
let searchRequest = URLRequest(url: searchURL)
NSURLConnection.sendAsynchronousRequest(searchRequest, queue: processingQueue) response, data, error in
if error != nil
completion(nil,error as! NSError)
return
var JSONError : NSError?
let resultsDictionary = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
if JSONError != nil
completion(nil, JSONError)
return
switch (resultsDictionary!["stat"] as! String)
case "ok":
print("Results processed OK")
case "fail":
let APIError = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:resultsDictionary!["message"]!])
completion(results: nil, error: APIError)
return
default:
let APIError = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:"Unknown API response"])
completion(nil, APIError)
return
let photosContainer = resultsDictionary!["photos"] as! NSDictionary
let photosReceived = photosContainer["photo"] as! [NSDictionary]
let flickrPhotos : [FlickrPhoto] = photosReceived.map
photoDictionary in
let photoID = photoDictionary["id"] as? String ?? ""
let title = photoDictionary["title"] as? String ?? ""
let farm = photoDictionary["farm"] as? Int ?? 0
let server = photoDictionary["server"] as? String ?? ""
let secret = photoDictionary["secret"] as? String ?? ""
let flickrPhoto = FlickrPhoto(photoID: photoID, title: title, farm: farm, server: server, secret: secret)
return flickrPhoto
DispatchQueue.main.async(execute:
completion(FlickrSearchResults(searchTerm: searchTerm, searchResults: flickrPhotos), nil)
)
fileprivate func flickrSearchURLForSearchTerm(_ searchTerm:String) -> URL
let escapedTerm = searchTerm.addingPercentEscapes(using: String.Encoding.utf8)!
let URLString = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=\(apiKey)&text=\(escapedTerm)&per_page=30&format=json&nojsoncallback=1"
return URL(string: URLString)!
我收到以下代码行的错误:
NSURLConnection.sendAsynchronousRequest(searchRequest, queue: processingQueue) response, data, error in
if error != nil
completion(nil,error as! NSError)
return
我对如何使用 do、try、catch 进行修改感到有些困惑,因此我们将不胜感激任何帮助,以便我可以运行应用程序以使用 Instruments。
这里是教程的链接:https://www.raywenderlich.com/97886/instruments-tutorial-with-swift-getting-started
【问题讨论】:
问题是你有try
可以抛出错误,但你没有捕捉到它,所以它假设闭包因此需要允许抛出错误,它不会.只需do
-catch
try
在闭包中抛出的错误或使用try?
,不会抛出错误。
【参考方案1】:
用这个替换你的 Flickr 类。
class Flickr
let processingQueue = OperationQueue()
func searchFlickrForTerm(_ searchTerm: String, completion : @escaping (_ results: FlickrSearchResults?, _ error : NSError?) -> Void)
let searchURL = flickrSearchURLForSearchTerm(searchTerm)
let searchRequest = URLRequest(url: searchURL)
NSURLConnection.sendAsynchronousRequest(searchRequest, queue: processingQueue) response, data, error in
guard let data = data, error == nil else
completion(nil, error as NSError?)
return
guard let jsonObject = try? JSONSerialization.jsonObject(with: data,
options: JSONSerialization.ReadingOptions(rawValue: 0)),
let resultsDictionary = jsonObject as? Dictionary<String, Any>
else
return
switch (resultsDictionary["stat"] as! String)
case "ok":
print("Results processed OK")
case "fail":
let APIError = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:resultsDictionary["message"]!])
completion(nil, APIError)
return
default:
let APIError = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:"Unknown API response"])
completion(nil, APIError)
return
let photosContainer = resultsDictionary["photos"] as! NSDictionary
let photosReceived = photosContainer["photo"] as! [NSDictionary]
let flickrPhotos : [FlickrPhoto] = photosReceived.map
photoDictionary in
let photoID = photoDictionary["id"] as? String ?? ""
let title = photoDictionary["title"] as? String ?? ""
let farm = photoDictionary["farm"] as? Int ?? 0
let server = photoDictionary["server"] as? String ?? ""
let secret = photoDictionary["secret"] as? String ?? ""
let flickrPhoto = FlickrPhoto(photoID: photoID, title: title, farm: farm, server: server, secret: secret)
return flickrPhoto
DispatchQueue.main.async(execute:
completion(FlickrSearchResults(searchTerm: searchTerm, searchResults: flickrPhotos), nil)
)
fileprivate func flickrSearchURLForSearchTerm(_ searchTerm:String) -> URL
let escapedTerm = searchTerm.addingPercentEscapes(using: String.Encoding.utf8)!
let URLString = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=\(apiKey)&text=\(escapedTerm)&per_page=30&format=json&nojsoncallback=1"
return URL(string: URLString)!
抱歉,间距都搞砸了,但问题是您没有正确处理错误。当您执行 JSONSerialization 时,它可能会抛出,因此您必须将其包装在 do catch 块中,或者您可以使用 !如果抛出错误,则忽略抛出和崩溃,或者?如果失败则返回 nil。
【讨论】:
以上是关于从 '(_, _, _) throws -> ()' 类型的抛出函数到非抛出函数类型 '(URLResponse?, Data?, Error?) -> Void 的无效转换的主要内容,如果未能解决你的问题,请参考以下文章
从 '(_) throws -> ()' 类型的抛出函数到非抛出函数类型 '(DataSnapshot) -> Void' 的无效转换
从 '(_) throws -> Void' 类型的抛出函数到非抛出函数类型 '([UNNotificationRequest]) -> Void 的无效转换
Alamofire 4从“(_) throws ->()”类型的抛出函数到非抛出函数类型“(DataResponse <Any>)-> Void”的无效转换
无法使用类型为“(NSMutableURLRequest,(_,_,_) throws -> _)”的参数列表调用“dataTaskWithRequest”
iOS 9(Swift 2.0):无法使用类型为“(NSURL,(_,_,_)throws-> Void)”的参数列表调用“dataTaskwithURL”