我在Xcode 7.3中使用swift 2.2版本进行了工作。现在我已经更新了Xcode 8并迁移到了swift 3.现在我的项目包含了专门针对像afnetworking成功块这样的块的错误。
其中错误为
Cannot convert value of type '() -> ()' to expected argument type '((URLSessionDataTask, Any?) -> Void)?'
我不明白如何按照swift 3来解决这个问题。
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中的处理程序块有关。我不明白错误,因此无法解决。任何帮助将不胜感激。提前谢谢。
答案 0 :(得分:14)
对于facebook - 问题在于关于将objective-c函数参数转换为Swift的新Swift规则。
以前,如果objective-c代码中的参数没有可归属性属性(如nonnull
或nullable
),则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
但是你需要记住它们现在是可选的。
总结一些转换规则可能会影响您的回调代码:
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)
}
}
})
此处针对问题错误,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
的类型说明,问题已解决。并在整个应用程序中遵循这一点,它工作。我可以毫无错误地运行项目,并且它正在运行。感谢。