完成处理程序在swift 3和Xcode 8中的错误

时间:2016-09-15 10:32:06

标签: ios facebook afnetworking swift3 xcode8

我在Xcode 7.3中使用swift 2.2版本进行了工作。现在我已经更新了Xcode 8并迁移到了swift 3.现在我的项目包含了专门针对像afnetworking成功块这样的块的错误。

Snapshot for error in afnetworking post method

其中错误为

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

我不明白如何按照swift 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!'

这个所有错误都与swift 3中的处理程序块有关。我不明白错误,因此无法解决。任何帮助将不胜感激。提前谢谢。

2 个答案:

答案 0 :(得分:14)

对于facebook - 问题在于关于将objective-c函数参数转换为Swift的新Swift规则。

以前,如果objective-c代码中的参数没有可归属性属性(如nonnullnullable),则Swift会将其转换为!,使其不可选(强制解包)。现在它用?转换它,使它们成为可选项。这就是你收到错误的原因。在您作为登录回调之前:

(FBSDKLoginManagerLoginResult!, NSError!) -> Void

现在你需要把:

(FBSDKLoginManagerLoginResult?, Error?) -> Void

此外,如您所见,现在您将看不到NSError课程。而不是Swift会放Error。这也是新规则。现在,在Swift中删除了所有" NS" 类名称前缀(NSObject - > Object; NSError - > {{ 1}})。

在Swift 3.0中登录facebook的工作代码示例:

Error

Swift 3.0中facebook请求的工作代码示例:

let manager = FBSDKLoginManager()

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

}

如您所见,现在它使用let request = FBSDKGraphRequest() request.start { (connection: FBSDKGraphRequestConnection?, result: Any?, error: Error?) in } 类型而不是objective-c Any。在Swift 2.2中,它使用id。这也是新的Swift转换规则。

您无需指定回调参数类型。我在代码中用它来突出显示它们的真实类型。所以你可以在没有它们的情况下编写代码:

AnyObject

但是你需要记住它们现在是可选的。

总结一些转换规则可能会影响您的回调代码:

  1. 如果在objective-c中未指定nullability attributes
  2. ,则闭包参数是可选的
  3. 为Swift中的objective-c类删除所有" NS" 前缀
  4. 如果objective-c函数具有let manager = FBSDKLoginManager() manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) { (loginResult, error) in } let request = FBSDKGraphRequest() request.start { (connection, result, error) in } 参数,则在Swift 3.0中它将具有类型id而不是Any

答案 1 :(得分: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)
                    }


                }

        })

此处针对问题错误,dataTaskresponseObj指定了类型。删除类型后它工作正常。

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

    }

此处我还删除了resulterror的类型说明,问题已解决。并在整个应用程序中遵循这一点,它工作。我可以毫无错误地运行项目,并且它正在运行。感谢。