我试图用一个完成处理程序向现有函数添加一个throws
,但是我一直收到一个no calls throwing functions occur within try expression
的警告。
从类型为'()throwing -〉Void'的引发函数到非引发函数类型的转换无效。
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()
}
4条答案
按热度按时间bxpogfeg1#
您可以做的是将错误封装到一个可抛出的闭包中,如以下代码所示,以实现所需的效果:
你可以用下面的方式来称呼它:
技巧是
login3
函数接受一个额外的闭包'inner'
,其类型为() throws -> Bool
。这个闭包要么提供计算结果,要么抛出。闭包本身在计算过程中通过以下两种方法之一构造:inner: {throw error}
inner: {return result}
我强烈推荐一篇关于在异步调用Using try / catch in Swift with asynchronous closures中使用
try/catch
的优秀文章。我希望这对你有帮助。
mzaanser2#
你问X我回答Y,但以防万一...
总是有可能将抛出功能添加到函数中,而不是添加到完成处理程序中:
然后,您可以从IBAction内部调用它:
deikduxw3#
我对Swift 2.0还没有做过太多的工作,请你带着一点怀疑阅读下面的内容:
您创建了一个“dataTask”
task
,它的完成处理程序中有一个throw,但login3方法中唯一的实际代码是task.resume()
。完成处理程序在login3
返回之前不会执行。(实际上,它是另一个对象的参数,因此编译器不知道该代码会发生什么。)据我所知,你的
login3
方法的自上而下的主体必须包含一个throw。因为它是一个异步方法,你不能这样做。因此,不要让你的login3
函数throw。相反,让它传递一个error对象给它的完成处理程序。oiopk7p54#
在我的印象中,这是由函数的签名引起的。在
@IBAction func loginPressed(sender: AnyObject)
中,当调用login3
时,你不必使用try,因为函数本身没有被标记为throw,而是完成处理程序被标记为throw。但事实上,login3
的完成闭包永远不会throw,因为你在do {} catch {}
块中执行所有的throw函数。因此,您可以尝试从login3
完成闭包中删除throws
注解,如果您在login3
中捕获到错误并得到相应的结果,也可以调用闭包。这样,您可以在do {} catch {}
块中处理login3
内部的所有抛出函数,并使用合适的值调用完成处理程序。通常,我也不知道您是否可以像在@IBAction中那样在没有前面的
do {}
块的情况下进行捕获。