无法通过完成处理程序使用函数 [英] Can't get throws to work with function with completion handler
问题描述
我正在尝试使用完成处理程序将throws
添加到现有函数中,但是我不断收到警告,提示no calls throwing functions occur within try expression
.在引发错误的部分中,出现错误消息
I'm trying to add a throws
to my existing function with a completion handler but I keep getting a warning saying no calls throwing functions occur within try expression
. In the section where I throw the errors, I get an error saying
从类型为(()throwing-> Void'的throwing函数到非throwing函数类型的无效转换.
enum LoginError: ErrorType {
case Invalid_Credentials
case Unable_To_Access_Login
case User_Not_Found
}
@IBAction func loginPressed(sender: AnyObject) {
do{
try self.login3(dict, completion: { (result) -> Void in
if (result == true)
{
self.performSegueWithIdentifier("loginSegue", sender: nil)
}
})
}
catch LoginError.User_Not_Found
{
//deal with it
}
catch LoginError.Unable_To_Access_Login
{
//deal with it
}
catch LoginError.Invalid_Credentials
{
//deal with it
}
catch
{
print("i dunno")
}
}
func login3(params:[String: String], completion: (result:Bool) throws -> Void)
{
//Request set up
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves) as? NSDictionary
if let parseJSON = json
{
let userID = parseJSON["user_id"] as? Int
let loginError = parseJSON["user_not_found"] as? String
let validationError = parseJSON["invalid_credentials"] as? String
let exception = parseJSON["unable_to_access_login"] as? String
var responseArray = [(parseJSON["user_id"] as? Int)]
if userID != nil
{
dispatch_async(dispatch_get_main_queue()) {
completion(result:true)
}
}
else if loginError != ""
{
dispatch_async(dispatch_get_main_queue()){
completion(result: false)
self.loginErrorLabel.text = loginError
throw LoginError.User_Not_Found
}
}
else if validationError != ""
{
dispatch_async(dispatch_get_main_queue()){
completion(result:false)
self.validationErrorLabel.text = validationError
throw LoginError.Invalid_Credentials
}
}
else if exception != nil
{
dispatch_async(dispatch_get_main_queue()){
completion(result:false)
self.exceptionErrorLabel.text = "Unable to login"
throw LoginError.Unable_To_Access_Login
}
}
}
else
{
}
}
catch let parseError {
// Log the error thrown by `JSONObjectWithData`
})
task.resume()
}
推荐答案
您可以做的就是将错误封装到一个可抛出的闭包中,如以下代码所示,以实现所需的功能:
What you can do is encapsulating the error into a throwable closure like in the following code to achieve what you want:
func login3(params:[String: String], completion: (inner: () throws -> Bool) -> ()) {
let task = session.dataTaskWithRequest(request, completionHandler: { data, response, error -> Void in
let json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves) as? NSDictionary
if let parseJSON = json {
let userID = parseJSON["user_id"] as? Int
let loginError = parseJSON["user_not_found"] as? String
let validationError = parseJSON["invalid_credentials"] as? String
let exception = parseJSON["unable_to_access_login"] as? String
var responseArray = [(parseJSON["user_id"] as? Int)]
if userID != nil {
dispatch_async(dispatch_get_main_queue()) {
completion(inner: { return true })
}
}
else if loginError != ""
{
dispatch_async(dispatch_get_main_queue()) {
self.loginErrorLabel.text = loginError
completion(inner: { throw LoginError.User_Not_Found })
}
}
else if validationError != ""
{
dispatch_async(dispatch_get_main_queue()) {
self.validationErrorLabel.text = validationError
completion(inner: {throw LoginError.Invalid_Credentials})
}
}
else if exception != nil
{
dispatch_async(dispatch_get_main_queue()){
self.exceptionErrorLabel.text = "Unable to login"
completion(inner: {throw LoginError.Unable_To_Access_Login})
}
}
}
else
{
}
}
task.resume()
}
您可以通过以下方式调用它:
And the you can call it like in the following way:
self.login3(dict) { (inner: () throws -> Bool) -> Void in
do {
let result = try inner()
self.performSegueWithIdentifier("loginSegue", sender: nil)
} catch let error {
print(error)
}
}
诀窍是login3
函数需要一个名为'inner'
的类型为() throws -> Bool
的附加闭包.这个闭包要么提供计算结果,要么抛出.在计算过程中,闭包本身是通过以下两种方式之一构造的:
The trick is that the login3
function takes an additional closure called 'inner'
of the type () throws -> Bool
. This closure will either provide the result of the computation, or it will throw. The closure itself is being constructed during the computation by one of two means:
- 如果发生错误:
inner: {throw error}
- 成功的情况下:
inner: {return result}
- In case of an error:
inner: {throw error}
- In case of success:
inner: {return result}
我强烈建议您撰写一篇精彩的文章,内容涉及在异步调用中使用try/catch
使用尝试/使用异步闭包在Swift中捕获
I strongly recommend you an excellent article about using try/catch
in async calls Using try / catch in Swift with asynchronous closures
希望这对您有所帮助.
这篇关于无法通过完成处理程序使用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!