swift 3 和 Xcode 8 中的完成处理程序错误
completion handler's error in swift 3 and Xcode 8
我在 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. 我不明白这些错误,因此无法解决。任何帮助将不胜感激。提前致谢。
对于 facebook - 问题出在关于将 objective-c 函数参数转换为 Swift 的新 Swift 规则中。
以前,如果 objective-c 代码中的参数没有可空性属性(如 nonnull
或 nullable
),Swift 会将其转换为 !
它们是非可选的(强制展开)。现在它用 ?
转换它,使它们成为可选的。这就是为什么你会收到错误。在您将其作为登录回调之前:
(FBSDKLoginManagerLoginResult!, NSError!) -> Void
现在你需要输入:
(FBSDKLoginManagerLoginResult?, Error?) -> Void
另外,如你所见,现在你将不会看到NSError
class。而不是 Swift 将放置 Error
。这也是新规则。现在 "NS" class 名称中的所有前缀都在 Swift(NSObject
-> Object
; NSError
-> Error
)。
Swift 3.0 中 facebook 登录的工作代码示例:
let manager = FBSDKLoginManager()
manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) {
(loginResult: FBSDKLoginManagerLoginResult?, error: Error?) in
}
Swift3.0 中 facebook 请求的工作代码示例:
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 class Swift
中的所有前缀
- 如果 objective-c 函数有
id
参数,在 Swift 3.0 中它将有类型 Any
而不是 AnyObject
虽然我之前不知道这个错误 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
的类型说明,问题已解决。并在整个应用程序中遵循此操作并且有效。我可以 运行 该项目没有错误,而且它正在运行。谢谢。
我在 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. 我不明白这些错误,因此无法解决。任何帮助将不胜感激。提前致谢。
对于 facebook - 问题出在关于将 objective-c 函数参数转换为 Swift 的新 Swift 规则中。
以前,如果 objective-c 代码中的参数没有可空性属性(如 nonnull
或 nullable
),Swift 会将其转换为 !
它们是非可选的(强制展开)。现在它用 ?
转换它,使它们成为可选的。这就是为什么你会收到错误。在您将其作为登录回调之前:
(FBSDKLoginManagerLoginResult!, NSError!) -> Void
现在你需要输入:
(FBSDKLoginManagerLoginResult?, Error?) -> Void
另外,如你所见,现在你将不会看到NSError
class。而不是 Swift 将放置 Error
。这也是新规则。现在 "NS" class 名称中的所有前缀都在 Swift(NSObject
-> Object
; NSError
-> Error
)。
Swift 3.0 中 facebook 登录的工作代码示例:
let manager = FBSDKLoginManager()
manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) {
(loginResult: FBSDKLoginManagerLoginResult?, error: Error?) in
}
Swift3.0 中 facebook 请求的工作代码示例:
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 class Swift 中的所有前缀
- 如果 objective-c 函数有
id
参数,在 Swift 3.0 中它将有类型Any
而不是AnyObject
虽然我之前不知道这个错误 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
的类型说明,问题已解决。并在整个应用程序中遵循此操作并且有效。我可以 运行 该项目没有错误,而且它正在运行。谢谢。