Search code examples
cocoansarraynsdictionaryplistnsobject

How to iterate concisely through @properties on an NSObject subclass to set properties from a plist?


Say I have a subclass of NSObject (let's call it 'BSObject') with the following properties:

NSString *name;
NSNumber *num;

I have an NSMutableArray of BSObjects (let's call that one 'BSCollection').

For storage on disk, I have a property list which is an array of dictionaries. The BSCollection is represented by the root object (an array), and each element of the array is a dictionary representing a BSObject. The key of the dictionary is the property name, and the value is the value of the BSObject.

Example plist with two BSObjects:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>name</key>
        <string>this is a name</string>
        <key>num</key>
        <integer>34</integer>
    </dict>
    <dict>
        <key>name</key>
        <string>this is another name</string>
        <key>num</key>
        <integer>22222</integer>
    </dict>
</array>
</plist>

Now I want to load the plist into a BSCollection of BSObjects as concisely as possible. I know I could do something like this for each key / value pair:

BSCollection = [BSCollection alloc] init];
if ([[NSFileManager defaultManager] fileExistsAtPath:URL]) {
  NSArray *rawXML = [[NSArray alloc] initWithContentsOfFile:URL];
  for (NSDictionary *object in rawXML) {
    BSObject *new = [[BSObject alloc] init];
    new.name = [new objectForKey:@"name"];
    new.num = [new objectForKey:@"num"];
    [BSCollection addObject:new];
  }
}

BUT: the property of BSObject and the key of the NSDictionary are the same! Is there a way that I can take advantage of this fact? I believe in procedural languages, I would use something like "exec()" to get the value out of the property name, assuming I could somehow get an array of properties on an object? I'm afraid I'm not really sure what I am looking for, hence my Google searches have come up empty.


Solution

  • Your code example is messed up, but what you want is something like:

    [new setValuesForKeysWithDictionary:dict];