Using decodeInteger
on a non-integer key would raise an exception. Sadly, it's an NSException
which Swift cannot handle directly (see references below).
You need to first write a wrapper to handle ObjC exceptions in ObjC and bridge it over to Swift (inspired by this answer):
/// -------------------------------------------
/// ObjC.h
/// -------------------------------------------
#import <Foundation/Foundation.h>
@interface ObjC : NSObject
+ (BOOL)catchException:(void(^)())tryBlock error:(__autoreleasing NSError **)error;
@end
/// -------------------------------------------
/// ObjC.m
/// -------------------------------------------
#import "ObjC.h"
@implementation ObjC
+ (BOOL)catchException:(void(^)())tryBlock error:(__autoreleasing NSError **)error {
@try {
tryBlock();
return YES;
}
@catch (NSException *exception) {
NSMutableDictionary * userInfo = [NSMutableDictionary dictionaryWithDictionary:exception.userInfo];
[userInfo setValue:exception.reason forKey:NSLocalizedDescriptionKey];
[userInfo setValue:exception.name forKey:NSUnderlyingErrorKey];
*error = [[NSError alloc] initWithDomain:exception.name
code:0
userInfo:userInfo];
return NO;
}
}
@end
Now you can catch the exception in Swift:
do {
try ObjC.catchException {
let age = aDecoder.decodeInteger(forKey: "firstName")
}
} catch {
print(error.localizedDescription)
}
References: Using ObjectiveC with Swift: Adopting Cocoa Design Patterns
Although Swift error handling resembles exception handling in Objective-C, it is entirely separate functionality. If an Objective-C method throws an exception during runtime, Swift triggers a runtime error. There is no way to recover from Objective-C exceptions directly in Swift. Any exception handling behavior must be implemented in Objective-C code used by Swift.