1

Yesterday I updated to Xcode 8.2 which forced me to update to Swift 3.0 syntax. In my app I have this function:

func performGetRequest(_ targetURL: URL!, completion:@escaping (_ data: Data?, _ HTTPStatusCode: Int, _ error: NSError?) -> Void)
{
    let request = NSMutableURLRequest(url: targetURL)
    request.httpMethod = "GET"

    let sessionConfiguration = URLSessionConfiguration.default

    let Session = URLSession(configuration: sessionConfiguration)

    let tasksession = Session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: NSError?) -> Void in
        if data != nil{
            DispatchQueue.main.async(execute: { () -> Void in
            completion(data: data, HTTPStatusCode: (response as! HTTPURLResponse).statusCode, error: error)})
        }
        else
        {
            print("Connection Lost")
        }

    })
    tasksession.resume()
}

And I get this error:

Cannot invoke 'dataTask' with an argument list of type '(with: NSMutableURLRequest, completionHandler: (Data?, URLResponse?, NSError?) -> Void)'

Please, would someone help me to correct it?

Cœur
  • 37,241
  • 25
  • 195
  • 267
bero
  • 13
  • 4
  • Xcode 8.2 doesn't force you to update to Swift 3.0, you can still use Swift 2.3. But Xcode 8.3 will force you to move to Swift 3.x. – Cœur Dec 16 '16 at 05:00

1 Answers1

2

For Swift 3 it is batte if you check Apple Documentation, Now dataTask(with:completionHandler:) will take URLRequest as first argument and the completionHandler is changed to (Data?, URLResponse?, Error?) -> Void. So make instance of URLRequest instead of NSMutableURLRequest and made changes of completionHandler also. In Swift 3 with most of the public API they have changed NSError to Error. So batter if you use Error too.

func performGetRequest(_ targetURL: URL!, completion:@escaping (_ data: Data?, _ HTTPStatusCode: Int, _ error: Error?) -> Void) {

    let request = URLRequest(url: targetURL)
    request.httpMethod = "GET"

    let sessionConfiguration = URLSessionConfiguration.default

    let Session = URLSession(configuration: sessionConfiguration)

    let tasksession = Session.dataTask(with: request) { data, response, error in
        if data != nil{
            DispatchQueue.main.async {
                completion(data: data, HTTPStatusCode: (response as! HTTPURLResponse).statusCode, error: error)
            }
        }
        else
        {
            print("Connection Lost")
            DispatchQueue.main.async {
                completion(data: nil, HTTPStatusCode: (response as! HTTPURLResponse).statusCode, error: error)
            }
        }

    }
    tasksession.resume()
}

Note: You need to call your completionHendler with all possible ways, you haven't called it when you are receiving nil data you need to call it inside the else block also with nil as data value.

Edit: You can call this function like this.

self.performGetRequest(url) { (data, status, error) in
    if error != nil {
        print(error?.localizedDescription)
        return
    }
    //Use data here
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183