Invalid conversion from throwing function of type (_,_,_) throws -> Void to non-throwing function type (NSData?, NSURLResponse?, NSError?) -> Void

IosSwiftTry CatchUrlsessionJson Serialization

Ios Problem Overview


I have written this code:

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()
    
    }

And after update to XCode 7 it gives me this error: Invalid conversion from throwing function of type (_, _, _) throws -> Void to non-throwing function type (NSData?, NSURLResponse?, NSError?) -> Void. It is in line, where is let task.

Thanks

Ios Solutions


Solution 1 - Ios

You need to implement Do Try Catch error handling as follow:

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()
    }
}

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))

Solution 2 - Ios

As Leo suggested, your problem is that you're using try, but not within the do-try-catch construct, which means that it infers that the closure is defined to throwing the error, but since it is not defined as such, you get that error.

So, add do-try-catch:

func getjson() {
    let urlPath = "https://api.whitehouse.gov/v1/petitions.json?limit=100"
    let url = URL(string: urlPath)!
    let session = URLSession.shared
    let task = session.dataTask(with: url) { data, response, error in
        print("Task completed")
        
        guard let data = data, error == nil else {
            print(error?.localizedDescription)
            return
        }
        
        do {
            if let jsonResult = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                if let results = jsonResult["results"] as? [Any] {
                    DispatchQueue.main.async {
                        self.tableData = results
                        self.indexTableView.reloadData()
                    }
                }
            }
        } catch let parseError {
            print("JSON Error \(parseError.localizedDescription)")
        }
    }
    
    task.resume()
}

Solution 3 - Ios

In Swift 2, replace all NSError with ErrorType

Try this.

  class func fetchWeatherForLocation(locationCode: String = "", shouldShowHUD: Bool = false, completionHandler: (data: NSDictionary?, error: ErrorType?) -> ()) {
    
    
    
    let url = NSURL(string: "myurl")               
    let task =  NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
        
        if let dataWithKey = data {
            
            do {
                let jsonForDataWithTemprature = try NSJSONSerialization.JSONObjectWithData(dataWithKey, options:NSJSONReadingOptions.MutableContainers)
                
                guard let arrayForDataWithKey :NSArray = jsonForDataWithTemprature as? NSArray else {
                    print("Not a Dictionary")
                    return
                }
                
                let dictionaryWithTemprature = arrayForDataWithKey.firstObject as! NSDictionary
                
                completionHandler(data: dictionaryWithTemprature, error: nil)
                
            }
            catch let JSONError as ErrorType {
                print("\(JSONError)")
            }
            
        }
    }
    
    task.resume()
}

Solution 4 - Ios

Changing the error type in the code try-catch worked for me.

"replace all NSError with ErrorType"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin MikusovicView Question on Stackoverflow
Solution 1 - IosLeo DabusView Answer on Stackoverflow
Solution 2 - IosRobView Answer on Stackoverflow
Solution 3 - IosAdarsh V CView Answer on Stackoverflow
Solution 4 - IosKishorView Answer on Stackoverflow