投掷函数类型(_,_,_)的无效转换抛出 - > Void到非投掷函数类型(NSData?,NSURLResponse?,NSError?) - > Void

Mar*_*vic 34 ios swift xcode7

我写了这段代码:

func getjson() {
        let urlPath = "https://api.whitehouse.gov/v1/petitions.json?limit=100"
        let url = NSURL(string: urlPath)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
            print("Task completed")
            if(error != nil) {
                print(error!.localizedDescription)
            }
            let err: NSError?
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary {
                if(err != nil) {
                    print("JSON Error \(err!.localizedDescription)")
                }
                if let results: NSArray = jsonResult["results"] as? NSArray {
                    dispatch_async(dispatch_get_main_queue(), {
                        self.tableData = results
                        self.Indextableview.reloadData()
                    })
                }
            }
        })

        task.resume()

    }
Run Code Online (Sandbox Code Playgroud)

在更新到XCode 7之后,它给了我这个错误:从抛出类型(_,_,_)抛出函数的无效转换抛出 - > Void到非投掷函数类型(NSData?,NSURLResponse?,NSError?) - > Void.这是排队,在哪里让任务.

谢谢

Leo*_*bus 47

您需要实现Do Try Catch错误处理,如下所示:

import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

extension URL {
    func asyncDownload(completion: @escaping (_ data: Data?, _ response: URLResponse?, _ error: Error?) -> ()) {
        URLSession.shared
            .dataTask(with: self, completionHandler: completion)
            .resume()
    }
}
Run Code Online (Sandbox Code Playgroud)
let jsonURL = URL(string: "https://api.whitehouse.gov/v1/petitions.json?limit=100")!
let start = Date()
jsonURL.asyncDownload { data, response, error in

    print("Download ended:", Date().description(with: .current))
    print("Elapsed Time:", Date().timeIntervalSince(start), terminator: " seconds\n")
    print("Data size:", data?.count ?? "nil", terminator: " bytes\n\n")

    guard let data = data else {
        print("URLSession dataTask error:", error ?? "nil")
        return
    }

    do {
        let jsonObject = try JSONSerialization.jsonObject(with: data)
        if let dictionary = jsonObject as? [String: Any],
            let results = dictionary["results"] as? [[String: Any]] {
            DispatchQueue.main.async {
                results.forEach { print($0["body"] ?? "", terminator: "\n\n") }
      //        self.tableData = results
      //        self.Indextableview.reloadData()
            }
        }
    } catch {
        print("JSONSerialization error:", error)
    }
}
print("\nDownload started:", start.description(with: .current))
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法将错误进一步传递到链上?因为我的“getjson”函数在一个单独的类中。而且我不想打印错误描述,而是在 UIAlertController 中向用户显示它。但是 UIAlertController 只能通过调用“getjson”函数从 UIViewController 显示。 (2认同)

Rob*_*Rob 8

正如Leo所建议的,你的问题是你正在使用try,但不是在do- try- catch构造中,这意味着它推断闭包被定义为抛出错误,但由于它没有被定义,所以你得到了这个错误.

所以,添加do- try- catch:

func getjson() {
    let urlPath = "https://api.whitehouse.gov/v1/petitions.json?limit=100"
    let url = NSURL(string: urlPath)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url!) { data, response, error in
        print("Task completed")

        guard data != nil && error == nil else {
            print(error?.localizedDescription)
            return
        }

        do {
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
                if let results = jsonResult["results"] as? NSArray {
                    dispatch_async(dispatch_get_main_queue()) {
                        self.tableData = results
                        self.Indextableview.reloadData()
                    }
                }
            }
        } catch let parseError as NSError {
            print("JSON Error \(parseError.localizedDescription)")
        }
    }

    task.resume()
}
Run Code Online (Sandbox Code Playgroud)