Подтвердить что ты не робот

Ошибка обработчика завершения в быстрых 3 и Xcode 8

У меня есть рабочий проект в Xcode 7.3 с быстрой версией 2.2. Теперь я обновил Xcode 8 и перешел на быстрый 3. Теперь мой проект содержит ошибки специально для блоков, таких как блок успеха afnetworking.

Снимок для ошибки в методе postnetworking post

Что дает ошибку как

Cannot convert value of type '() -> ()' to expected argument type '((URLSessionDataTask, Any?) -> Void)?'

Я не понимаю, как это решить, чтобы работать как быстро.

И есть также такая же ошибка при входе в Facebook.

Ошибка входа в систему Facebook

Что дает ошибку как

Cannot convert value of type '(FBSDKLoginManagerLoginResult!, NSError!) -> Void' to expected argument type 'FBSDKLoginManagerRequestTokenHandler!'

и

Cannot convert value of type '(_, _, NSError!) -> Void' to expected argument type 'FBSDKGraphRequestHandler!'

Все ошибки связаны с блоками обработчика в swift 3. Я не понимаю ошибки и поэтому не могу их решить. Любая помощь будет оценена. Спасибо заранее.

4b9b3361

Ответ 1

Хотя я не знал об ошибке до того, что Xcode хочет сообщить мне об ошибке, но я удалил спецификацию типа с объектом и работал.

Как

manager.post(methodname, parameters: param, progress: nil, success:{ (dataTask, responseObj) in

                if let dict : NSDictionary = responseObj as? NSDictionary {

                    print("Response of \(methodname) : \(dict)")

                    if dict.object(forKey: "response") as? String == "success" {
                        CompletionHandler(true, dict)
                    } else {
                        CompletionHandler(false, dict)
                    }


                }

        })

Здесь в отношении ошибки вопроса указывается в dataTask и responseObj, которые указаны с указанным типом. После удаления типа он работал нормально.

То же, что и при входе в facebook

@IBAction func fbLoginClicked(_ sender: AnyObject) {

        let app = UIApplication.shared.delegate as! AppDelegate

        app.fbLoginManager = FBSDKLoginManager()
        app.fbLoginManager.logOut()
        app.fbLoginManager.loginBehavior = FBSDKLoginBehavior.native


        app.fbLoginManager.logIn(withReadPermissions: ["email"], from: self, handler: { (result, error) -> Void in
            if error != nil {
                print(error?.localizedDescription)
            } else {

                if (result! as FBSDKLoginManagerLoginResult).isCancelled == true {

                } else {

                    self.fetchFacebookUserDetail()
                }
            }
        })

    }

Здесь также я удалил спецификацию типа result и error и проблема решена. И последовал за этим в целом приложении, и это сработало. Я могу запустить проект без ошибок, а также работать. Спасибо.

Ответ 2

Для facebook - проблема заключается в новых правилах Swift о преобразовании параметров функции objective-c в Swift.

Ранее, если параметры в коде objective-c не имели атрибутов нулевой видимости (например, nonnull или nullable), Swift преобразует его с помощью !, делая их необязательными (принудительное разворачивание). Теперь он преобразует его с помощью ?, делая их необязательными. Вот почему вы получаете ошибку. Перед тем, как отправить запрос для входа в систему:

(FBSDKLoginManagerLoginResult!, NSError!) -> Void

Теперь вам нужно поставить:

(FBSDKLoginManagerLoginResult?, Error?) -> Void

Кроме того, как вы видите, теперь вы не увидите класс NSError. Вместо этого Swift поместит Error. Это также новое правило. Теперь все "NS", префиксные в именах классов, удаляются в Swift (NSObjectObject; NSErrorError).

Пример рабочего кода для входа в facebook в Swift 3.0:

let manager = FBSDKLoginManager()

manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) {
    (loginResult: FBSDKLoginManagerLoginResult?, error: Error?) in

}

Пример рабочего кода для запроса facebook в Swift 3.0:

let request = FBSDKGraphRequest()

request.start {
     (connection: FBSDKGraphRequestConnection?, result: Any?, error: Error?) in

}

Как вы видите, теперь он использует тип Any вместо objective-c id. В Swift 2.2 он использовал AnyObject. Это также новое правило преобразования Swift.

Вам не нужно указывать тип параметров обратного вызова. Я сделал это в коде, чтобы выделить их реальные типы. Таким образом, вы можете просто написать код без них:

let manager = FBSDKLoginManager()

manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) { (loginResult, error) in }


let request = FBSDKGraphRequest()

request.start { (connection, result, error) in }

Но вы должны помнить, что теперь они являются необязательными.

В заключение некоторые правила преобразования, которые могут повлиять на ваш код обратного вызова:

  • Параметры закрытия необязательны, если в objective-c не указаны атрибуты недействительности
  • Все префиксы "NS" удаляются для классов objective-c в Swift
  • Если функция objective-c имела параметр id, в Swift 3.0 он будет иметь тип Any вместо AnyObject