Tofu
Tofu

Reputation: 3613

NSPropertyListSerialization dataWithPropertyList returns error 3851

I'm trying to write binary data to file with NSPropertyListSerialization using format NSPropertyListBinaryFormat_v1_0 but the NSData just returns nil and error returns 3851.

#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding, NSSecureCoding>{
    NSString* nsname;
}

-(id)initWithname:(NSString*)nameofperson;
-(NSString*)getname;
@end

@implementation Person

-(id)initWithname:(NSString*)nameofperson{
        self = [super init];
    if(self){
        self->nsname = [[NSString alloc] initWithString:nameofperson];
    }
    return self;
}
- (NSString *)getname{
    return nsname;
}
+(BOOL)supportsSecureCoding{
    return YES;
}
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
    [coder encodeObject:nsname forKey:@"nsname"];
}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
    self = [super init];
    if(self){
        self->nsname = [coder decodeObjectForKey:@"nsname"];
    }
    return self;
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person* a = [[Person alloc] initWithname:@"Nina"];
        Person* b = [[Person alloc] initWithname:@"macbook"];
        NSArray<Person*>* writing = [[NSArray alloc] initWithObjects:a,b, nil];
        NSFileHandle* handle = [NSFileHandle fileHandleForWritingAtPath:@"temp.txt"];
        NSError* error = nil;
        NSData* data = [NSPropertyListSerialization dataWithPropertyList:writing format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];
        if(data == nil){
            NSLog(@"error %ld",(long)[error code]);
        }
        [handle writeData:data];
        [handle closeFile];
    }
    return 0;
}

Error: write2[25205:2894550] Error: Error Domain=NSCocoaErrorDomain Code=3851 "Property list invalid for format: 200 (property lists cannot contain objects of type 'CFType')" UserInfo={NSDebugDescription=Property list invalid for format: 200 (property lists cannot contain objects of type 'CFType')}

EDIT: I did get the code working with NSMutableArray but what if I want to write individual objects to file then read them back individually as well? For instance:

Person* a,b,c;
NSData* data = archivedDatWithRootObject:a;
[handle writeData:data];
data = archivedDatWithRootObject:b;
[handle writeData:data];
data = archivedDatWithRootObject:c;
[handle writeData:data];

Then I can read them back Person by Person? If I write them individually do I still read them back as an array?

Upvotes: 0

Views: 940

Answers (1)

vadian
vadian

Reputation: 285069

You cannot serialize a custom class with NSPropertyListSerialization, you have to use NSKeyedArchiver

Replace the line

NSData* data = [NSPropertyListSerialization dataWithPropertyList:writing format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];

with

NSData* data = [NSKeyedArchiver archivedDataWithRootObject:writing requiringSecureCoding:YES error:&error];

Side note: Consider to use synthesized properties in your class. Your syntax looks pretty old-fashioned (pre-ARC)

Upvotes: 1

Related Questions