Reputation: 91681
I have this code and it works:
Foo *foo = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:&error];
However, it gives me this warning:
'unarchiveTopLevelObjectWithData:error:' is deprecated: first deprecated in iOS 12.0 - Use +unarchivedObjectOfClass:fromData:error: instead
When I try to make that simple replacement with:
Foo *foo = [NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error];
... it fails with the following error:
The data couldn’t be read because it isn’t in the correct format.
How do I properly replace this deprecated method with a non-deprecated method?
Upvotes: 1
Views: 1304
Reputation: 91681
This is probably because your object conforms to NSCoding
, but it should be conforming to NSSecureCoding
.
If you look at the documentation for unarchivedObjectOfClass:fromData:error:, you'll notice it says:
Important
Make sure you have adopted NSSecureCoding in the types you decode. If any call to a decode-prefixed method fails, the default decodingFailurePolicy sets the error rather than throwing an exception. In this case, the current and all subsequent decode calls return 0 or nil.
Thus you'll need to do the following to switch over to the un-deprecated function:
[NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:&error]
to [NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error]
, as the deprecation warning says.Support secure coding:
NSCoding
to NSSecureCoding
for your top-level object.Add the property:
@property (class, readonly) BOOL supportsSecureCoding;
Implement the method:
+ (BOOL)supportsSecureCoding {
return YES;
}
If your object has any other properties that are NSCoding
repeat all these steps for them so they end up conforming to NSSecureCoding
. For example, if there was a property @property (nonatomic, strong) Bar *bar;
on your Foo
object that is being encoded, you'd need to ensure that Bar
also conforms to NSSecureCoding
and not just NSCoding
.
(Optional) Change your encoding call to require secure coding (i.e. the second parameter can be YES
):
[NSKeyedArchiver archivedDataWithRootObject:self requiringSecureCoding:YES error:&error];
It seems like Apple wants people to switch from NSCoding
to NSSecureCoding
, and the problem above would have been more obvious to resolve if NSCoding
was deprecated too.
Upvotes: 2