I am trying this code that is a calculator. How can I handle input from the user that is not valid?
//ANSWER: Bridging header to Objective-C// https://github.com/kongtomorrow/TryCatchFinally-Swift
Here is the same question but in objc but I want to do this in swift. Catching NSInvalidArgumentException from NSExpression
All I want to show is a message if it doesn't work, but now I am getting an exception when the user doesn't input the correct format.
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")
}
                More "Swifty" solution:
@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
This will generate Swift code:
class func tryBlock((() -> Void)!) throws
And you can use it with try:
do {
    try TryCatch.tryBlock {
        let expr = NSExpression(format: "60****2")
        ...
    }
} catch {
    // Handle error here
}
                        A nice solution editing from https://github.com/kongtomorrow/TryCatchFinally-Swift:
First create TryCatch.h & TryCatch.m and bridge them to 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();
    }
}
Then create the class TryCatch in Swift:
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)
    }
}
Finally, use it! :)
`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)")
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With