ios - how - try catch en swift
Captura una excepción para la entrada de usuario no válida en swift (3)
Estoy intentando este código que es una calculadora. ¿Cómo puedo manejar la entrada del usuario que no es válida?
// RESPUESTA: Conectando encabezado a Objective-C // https://github.com/kongtomorrow/TryCatchFinally-Swift
Aquí está la misma pregunta pero en objc pero quiero hacer esto rápidamente. Captura de NSInvalidArgumentException de NSExpression
Todo lo que quiero mostrar es un mensaje si no funciona, pero ahora recibo una excepción cuando el usuario no ingresa el formato correcto.
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")
}
Este sigue siendo un problema en Swift 2. Como se señaló, la mejor solución es usar un encabezado de conexión en puente y capturar la excepción NSException en Objective C.
https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8 describe una buena solución, pero el código exacto no se compila en Swift 2 porque try
and catch
ahora son palabras clave reservadas. Deberá cambiar la firma del método por una solución. Aquí hay un ejemplo:
// 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
Una buena solución de edición de https://github.com/kongtomorrow/TryCatchFinally-Swift :
Primero crea TryCatch.h
& TryCatch.m
y TryCatch.m
a 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();
}
}
Luego crea la clase TryCatch
en 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)
}
}
Finalmente, ¡úsalo! :)
`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)")
}
Más solución "Swifty":
@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
Esto generará el código Swift:
class func tryBlock((() -> Void)!) throws
Y puedes usarlo con try
:
do {
try TryCatch.tryBlock {
let expr = NSExpression(format: "60****2")
...
}
} catch {
// Handle error here
}