Search code examples
iosobjective-cnskeyedarchivernskeyedunarchivernssecurecoding

Unarchive custom object with secure coding in iOS


I'm encoding an array of objects that conform to NSSecureCoding successfully like this.

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array requiringSecureCoding:YES error:nil];

How do I unarchive this data? I'm trying like this but it's returning nil.

NSError *error = nil;
NSArray<MyClass *> *array = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSArray class] fromData:data error:&error];

This is the error it returns.

The data couldn’t be read because it isn’t in the correct format.


Solution

  • Here is a simple example

    @interface Secure:NSObject<NSSecureCoding> {
        NSString* name;
    }
    @property NSString* name;
    @end
    
    @implementation Secure
    @synthesize name;
    
    // Confirms to NSSecureCoding
    + (BOOL)supportsSecureCoding {
        return true;
    }
    
    - (void)encodeWithCoder:(nonnull NSCoder *)coder {
        [coder encodeObject:self.name forKey: @"name"];
    }
    
    - (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
        self = [self init];
        if (self){
            self.name = [coder decodeObjectOfClass:[NSString class] forKey:@"name"];
        }
        return  self;
    }
    
    @end
    

    Usage

    Secure *archive = [[Secure alloc] init];
        archive.name = @"ARC";
    NSArray* array = @[archive];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array requiringSecureCoding:YES error:nil];
    NSArray<Secure *> *unarchive = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSObject class] fromData:data error:nil];
    NSLog(@"%@", unarchive.firstObject.name);