2016-09-15 5 views
18

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

Snapshot for error in afnetworking post method

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

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

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

И есть также же, как ошибка в Facebook входа в систему ,

Facebook Login error

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

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!' 

Это все ошибки, связанные с обработчиком блоков в быстрой 3. Я не понимаю, ошибки и так, что не может решить. Любая помощь будет оценена. Заранее спасибо.

ответ

13

Хотя я не знал об ошибке до того, что 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 и решаемой задачи. И последовал за этим в целом приложении, и это сработало. Я могу запустить проект без ошибок, а также работать. Благодарю.

+0

Половина вашего ответа помогла мне ОЧЕНЬ много. Я надеялся, что вы поможете мне заполнить вторую половину. У меня есть метод делегата, который принимает NSError из объектива c, но когда я его конвертирую в swift, я не могу определить синтаксис, он жалуется, что мой класс не соответствует протоколу, из которого он пришел ... –

+0

@LenaBru Поскольку NSError становится Ошибка в быстром 3, поэтому соответствующим образом измените свой метод. – Max

+0

, чтобы получить член userInfo, я должен отдать его «как! NSError» ... это так ужасно ... –

14

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

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

(FBSDKLoginManagerLoginResult!, NSError!) -> Void 

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

(FBSDKLoginManagerLoginResult?, Error?) -> Void 

Кроме того, как вы видите, теперь вы не увидите NSError класс. Вместо этого Swift поставит Error. Это также новое правило. Теперь все «NS» с префиксом в именах классов удаляется в Swift (NSObject ->Object; NSError ->Error).

Пример рабочего кода для 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 типа вместо объектива-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 } 

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

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

  1. параметры затворов являются необязательными, если в Objective-C не указаны допустимость пустых атрибутов
  2. Всех «NS» префиксы вынимаются цель -c классы Swift
  3. Если цель-с функцией имел id параметр, в Swift 3.0 он будет иметь тип Any вместо AnyObject
+0

не сработал. Пытался. – Max

+0

@Max см. Пример кода из моего проекта, который работает. Я также указал определение типа параметров обратного вызова, чтобы показать, что это такое, но это необязательно. –

+0

Да, я поставил такие же, как и ваши, а также ошибка. Затем я удалил: FBSDKLoginManagerLoginResult? и: Ошибка? то ошибка исчезла. – Max

Смежные вопросы