objective-cencryptionnsdictionaryplistnsvalue

How to store objects in plist


I have some CGPoints that I need to store in a NSDictionary then write to a file. Later, I need to be able to load the file into a NSDictionary and access the CGPoint within.

self.dict is the NSDictionary I want to store points in.

- (void)setPoint:(CGPoint)point forKey:(NSString *)key {
    NSValue *value = [NSValue valueWithCGPoint:point];
    [self.dict setValue:value forKey:key];
}

I also want the information to be encrypted. So I convert the NSDictionary to NSData to encrypt it.

- (void)encryptDictionaryWithKey:(NSData *)key writeToFile:(NSString *)file {
    NSData *encryptedDict = [[NSKeyedArchiver archivedDataWithRootObject:self] encryptWithKey:key];
    [encryptedDict writeToFile:file atomically:YES];
}

Then to get the information from the file, decrypt it, and put it in NSDictionary form:

+ (NSDictionary *)dictionaryWithContentsOfEncryptedData:(NSData *)data     decryptWithKey:(NSData *)key {
    NSData *decryptedData = [data decryptedWithKey:key];
    return (NSDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:decryptedData];
}

I can put some other values (like NSNumber) into the NSDictionary, encrypt it and write it to file, then get it from file and decrypt it... and the value is still in tact. So my code seems to be fine. But it won't work with NSValue.

I use this to get CGPoint from NSValue. At this point, self.plist may have been (but not necessarily) encrypted, written to file, then set to an unencrypted version of the file.

- (CGPoint)pointForKey:(NSString *)key {
    NSValue *value = [self.prefs objectForKey:key];
    return [value CGPointValue];
}

This code only returns 0,0 (and value == nil) if self.plist has been encrypted, written to file, then loaded from the file and unencrypted.

So the NSValue with CGPoint seems to be set to nil during the process of writing to the file. I have no idea what I did wrong, so any help is appreciated . Thanks!


Solution

  • You can convert the CGPoint into an object that can be stored in a plist. For example, the CGPointCreateDictionaryRepresentation() function will convert a CGPoint into an NSDictionary (or rather, a CFDictionaryRef which can be cast to an NSDictionary). You can store that in the plist, and then convert it back to a CGPoint using the CGPointMakeWithDictionaryRepresentation() companion function when you are loading the plist.