Проблемы с Swift3: невозможно понять новый синтаксис

Вчера я обновился до Xcode 8.2, который заставил меня обновить синтаксис Swift 3.0. В моем приложении у меня есть эта функция:

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

И я получаю эту ошибку:

Невозможно вызвать 'dataTask' с помощью списка аргументов типа '(с помощью: NSMutableURLRequest, completeHandler: (Data?, URLResponse?, NSError?) → Void)'

Пожалуйста, поможете мне исправить это?

Ответ 1

Для Swift 3 это батта, если вы проверите Apple Documentation, теперь dataTask(with:completionHandler:) возьмет URLRequest в качестве первого аргумента, а completionHandler изменен на (Data?, URLResponse?, Error?) -> Void. Поэтому сделайте экземпляр URLRequest вместо NSMutableURLRequest и внесите изменения completionHandler. В Swift 3 с большей частью публичного API они изменили NSError на Error. Так что тесто, если вы используете Error тоже.

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

Примечание.. Вы должны вызывать ваш completionHendler всеми возможными способами, вы не вызывали его, когда вы получаете данные nil, которые вам нужно вызвать в блоке else, также с помощью nil как значение данных.

Изменить: Вы можете вызвать эту функцию следующим образом.

self.performGetRequest(url) { (data, status, error) in
    if error != nil {
        print(error?.localizedDescription)
        return
    }
    //Use data here
}