在swift中捕获无效用户input的exception

我正在尝试这是一个计算器的代码。 我如何处理无效的用户input?

//解答:将头部桥接到Objective-C // https://github.com/kongtomorrow/TryCatchFinally-Swift

这是同样的问题,但在objc,但我想迅速做到这一点。 捕获NSExpression中的NSInvalidArgumentException

所有我想要显示的是一个消息,如果它不起作用,但现在我得到一个exception,当用户没有input正确的格式。

import Foundation var equation:NSString = "60****2" // This gives a NSInvalidArgumentException', let expr = NSExpression(format: equation) // reason: 'Unable to parse the format string if let result = expr.expressionValueWithObject(nil, context: nil) as? NSNumber { let x = result.doubleValue println(x) } else { println("failed") } 

这仍然是Swift 2中的一个问题。如上所述,最好的解决scheme是使用桥接头并在Objective C中捕获NSException。

https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8描述了一个很好的解决scheme,但是精确的代码在Swift 2中不能编译,因为trycatch现在是保留关键字。 您需要更改方法签名以解决此问题。 这是一个例子:

 // https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8 @interface TryCatch : NSObject + (void)tryBlock:(void (^)())try catchBlock:(void (^)(NSException *))catch finallyBlock:(void (^)())finally; @end @implementation TryCatch + (void)tryBlock:(void (^)())try catchBlock:(void (^)(NSException *))catch finallyBlock:(void (^)())finally { @try { try ? try() : nil; } @catch (NSException *e) { catch ? catch(e) : nil; } @finally { finally ? finally() : nil; } } @end 

更多“Swifty”解决scheme:

 @implementation TryCatch + (BOOL)tryBlock:(void(^)())tryBlock error:(NSError **)error { @try { tryBlock ? tryBlock() : nil; } @catch (NSException *exception) { if (error) { *error = [NSError errorWithDomain:@"com.something" code:42 userInfo:@{NSLocalizedDescriptionKey: exception.name}]; } return NO; } return YES; } @end 

这将生成Swift代码:

 class func tryBlock((() -> Void)!) throws 

你可以try使用它:

 do { try TryCatch.tryBlock { let expr = NSExpression(format: "60****2") ... } } catch { // Handle error here } 

一个很好的解决scheme从https://github.com/kongtomorrow/TryCatchFinally-Swift编辑:

首先创buildTryCatch.hTryCatch.m并将它们桥接到Swift:

TryCatch.h

 #import <Foundation/Foundation.h> void tryCatch(void(^tryBlock)(), void(^catchBlock)(NSException *e), void(^finallyBlock)()); 

TryCatch.m

 #import <Foundation/Foundation.h> void tryCatch(void(^tryBlock)(), void(^catchBlock)(NSException *e), void(^finallyBlock)()) { @try { tryBlock(); } @catch (NSException *exception) { catchBlock(exception); } @finally { finallyBlock(); } } 

然后在Swift中创buildTryCatch类:

 func `try`(`try`:()->()) -> TryCatch { return TryCatch(`try`) } class TryCatch { let tryFunc : ()->() var catchFunc = { (e:NSException!)->() in return } var finallyFunc : ()->() = {} init(_ `try`:()->()) { tryFunc = `try` } func `catch`(`catch`:(NSException)->()) -> TryCatch { // objc bridging needs NSException!, not NSException as we'd like to expose to clients. catchFunc = { (e:NSException!) in `catch`(e) } return self } func finally(finally:()->()) { finallyFunc = finally } deinit { tryCatch(tryFunc, catchFunc, finallyFunc) } } 

最后用它! 🙂

 `try` { let expn = NSExpression(format: "60****2") //let resultFloat = expn.expressionValueWithObject(nil, context: nil).floatValue // Other things... }.`catch` { e in // Handle error here... print("Error: \(e)") }