I’m relatively new to Objective-C (mainly using cocoa/apple foundation framework), but a long-time C++ programmer, so I’ll start by explaining what I’m trying to accomplish; It’s quite possible my approach isn’t the best one, so I’d love to hear any suggestions for a different approach.
I’ve got a text file in json format, just made this quick example:
"section1" : {
"director" : "Sample Name 1",
"writers" : {
"name" : "Example Name 1",
"name" : "Example Name 2",
},
},
And I’ve got a class with properties which I want to match with the data inside this file, since I’m planning to parse this file and store some of the values in an instance of this class. My class header would look roughly like this:
@interface SongData : NSObject
@property (nonatomic, copy) NSString *director;
@property (nonatomic, copy) NSArray *writers;
@end
So I’m trying to find the cleanest, somewhat “data-driven” way to store this json data into the correct properties. Basically I want a way to loop through the json “dictionary” of data, and somehow use the “keys” to match with the correct property in my class and assign the value to that property. My first crack at it, I created a dictionary where the “key” is the actual key to lookup the proper data inside the json data, and the “value” would be a pointer to the correct class property. Sort of like this:
NSDictionary *descriptionDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
director, @"name",
writers, @"writers",
nil];
Then the idea was to loop through the json data (which is stored in another NSDictionary), use each key from my “descriptionDictionary” to lookup the appropriate value in the json data, then use the matching “value” of the description dictionary based on the same key (which I was hoping is sort of a pointer to the actual class property?) and set that properties value to the value from the json data. Perhaps an example will make it a bit more clear :-). Lets assume “jsonDictionary” is the result of parsing my json data, and I’m already inside section1, so there should be a 1-1 match between keys that make up the jsonData NSDictionary and the keys that make up my descriptionDictionary NSDictionary:
[descriptionDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
value = [jsonDictionary objectForKey:propertyName];
}];
Now “value” would technically be pointing to one of my classes properties, and I want to assign relevant json data to it (ie director = @”Sample Name 1″). I know there’s problems with what I’m doing (I realize that I probably can’t just dereference a pointer to a random class property and assign an arbitrary object of unknown type to it, hoping it all matches up 🙂 but hoping my example at least illustrates what I’m trying to do so someone can tell me a better way.
Have a look at KVC (source: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueCoding/Articles/BasicPrinciples.html)
As long as your class properties have the same names as the JSON fields you can use the
setValuesForKeysWithDictionary:and pass in the JSON root dictionary.For keys/properties that are named differently you can simply override the
setValue:forUndefinedKey:and set the appropriate property yourself.Finally there is the case of a value being represented by a different type in the JSON than in the property. For example NSURL would be an NSString instead. Here you can simply check the class of the passed parameter and if it does not match the IVAR, do a conversion.