Since Swift currently doesn't have try-catch, how am I supposed to prevent crashes with bad data in this line of code?
var myObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) as MyClass
UPDATE
I created a very simple case in a playground for demonstration. Assume we don't know what's in data
, how can I catch the SIGABRT on the second line? Is there no way to check to make sure it is possible to unarchive an NSData object before calling unarchiveObjectWithData
?
var data = "foo bar".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
if let unarc = NSKeyedUnarchiver.unarchiveObjectWithData(data) { // Execution was interrupted: signal SIGABRT
}
I think your best bet for now, until Apple updates the implementation of NSKeyedUnarchiver to not use exceptions or adds exception support to Swift, you are going to have to use an Objective-C wrapper to try-catch.
You can see an example of a wrapper here: https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8
Essentially, you can introduce a single Objective-C function or class that will allow you to use a try-catch block from Swift. I like implementing the above example as an initializer to make it cleaner in Swift:
// In Objective-C
// ----------------------
@interface try: NSObject
- (id)initWithTry:(void(^)())try catch:(void(^)(NSException *exception))catch finally:(void(^)())finally;
@end
@implementation try
- (id)initWithTry:(void(^)())try catch:(void(^)(NSException *exception))catch finally:(void(^)())finally
{
self = [super init];
if (self) {
@try {
try ? try() : nil;
}
@catch (NSException *exception) {
catch ? catch(exception) : nil;
}
@finally {
finally ? finally() : nil;
}
}
return self;
}
@end
// From Swift (make sure you import the objc header in your bridging header
// ----------------------
var data = "foo bar".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
try(
try: { () -> Void in
if let unarc: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) { // Execution was interrupted: signal SIGABRT
println(unarc)
}
},
catch: { exception in
println("Failed to parse data: \(exception)")
},
finally: nil
)
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