I have a class which serializes and deserializes with NSCoder
/NSKeyedArchiver
and NSKeyedUnarchiver
. I have unit tests that are designed to check for my handling of various errors inside my serialization format (which is not a simple archive but contains archives).
However, since I upgraded to Swift 2/iOS 9, the tests are displaying some unusual behaviour. Previously, the test for invalid archives failed as deserializing an invalid archive threw an Objective-C exception, as the docs state, that crashed the program as Swift cannot catch them. This is fine, I intended to fix the test at some point in the future.
Now, the test passes. When fed my random or deterministic garbage, I instead receive nil
back from unarchiveObjectWithData
rather than an exception. I've checked the docs for this method and there's no behaviour change listed.
Frankly, I find this behaviour change to be extremely suspicious as there's no mention anywhere of how or why this change occurred. My previously failing unit tests are just now passing with no apparent reason why.
So is this the new expected behaviour (that it returns nil
)? If not, how can I get the actual expected behaviour (the Obj-C exception) rather than the nil
for an invalid archive?
Swift2/iOS9 introduces undocumented throws
class method in NSKeyedUnarchiver
:
extension NSKeyedUnarchiver {
@warn_unused_result
public class func unarchiveTopLevelObjectWithData(data: NSData) throws -> AnyObject?
}
But it doesn't seems to work if the data is completely wrong format: It returns nil
without error.
let dat = "test".dataUsingEncoding(NSUTF8StringEncoding)!
try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(dat) // -> `nil`
Errors are thrown only when the unarchiver found some invalid entities (e.g. unknown class name) while decoding. I think it's a kind of bug or it's accidentally released with incomplete implementations.
Anyway, if you want Objective-C exception, you can just construct NSKeyedUnarchiver
:
let dat = "test".dataUsingEncoding(NSUTF8StringEncoding)!
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat) // -> throws Objective-C exception
But, there is no throws
initializer... yet?
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