NSKeyedUnarchiver unarchivedObjectOfClass implementation gives error

456 views Asked by At

I am updating an old Objective C app that uses 'NSKeyedUnarchiver unarchiveObjectWithData' which is now deprecated. The app archives an array consisting of custom objects that contain (among other things) another array of a different custom object. I have implemented NSSecureCoding in the 2 object's .h files and added the '+ (BOOL)supportsSecureCoding' override in both .m files.

My updated archiving code works correctly with the old deprecated NSKeyedUnarchiver unarchiveObjectWithData method:

        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.myArray
                                             requiringSecureCoding:YES
                                                             error:&error];
        BOOL success = [data writeToFile:pathToArchiveFile
                                 options:NSDataWritingAtomic
                                   error:&error];

However, with my updated unarchive code I get an error

        NSData *data = [NSData dataWithContentsOfFile: pathToArchiveFile
                                              options:NSDataReadingMappedIfSafe
                                                error:&error];
        self.myArray = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSArray class]
                                                          fromData:data
                                                             error:&error];

The error is ..."value for key 'NS.objects' was of unexpected class 'MyClass... Allowed classes are '{( "NSArray...

If I change to unarchivedObjectOfClass:[MyClass class] the error is ..."value for key 'root' was of unexpected class 'NSArray...Allowed classes are '{( "MyClass...

Something is going wrong with the unarchiving of arrays containing custom classes, but I don't see how to fix it and the available documentation is pretty weak. I am assuming that the archive code is correct, as the deprecated unArchive method seems to work correctly with it.

1

There are 1 answers

0
Fauad Anwar On

Try following, this worked for me.

For an array of custom class objects, we have to use unarchivedObjectOfClasses and pass a set to it.

Considering that your "Custom" class has implemented NSSecureCoding and added the '+ (BOOL)supportsSecureCoding' method.

NSError *error;

NSData *data = [NSData dataWithContentsOfFile: pathToArchiveFile options:NSDataReadingMappedIfSafe error:&error];

NSSet *classes = [NSSet setWithObjects:NSArray.class, Custom.class, nil];

NSArray *data = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:&error];