Objective-C DRY JSON Mapping and Object Creation
I am trying to dynamically map JSON information into different objects. But I can't figure out quite how to get the whole pointer situation under control, as what I was hoping would work does not.
So far my methodology has been to create a dictionary for each object, mapping the variable pointers to the equivalent JSON keys. In my JSON mapper, I have a method, parseJSONFromDictionary:withObject
that is supposed to iterate over the dictionary returned by SBJSON's JSONValue and assign the appropriate values to the appropriate variables in the given object.
-(NSObject *)parseJSONFromDictionary:(NSDictionary *)dict withObject:(NSObject *)start{
for (NSString *key in dict) {
if ([[self.mappings objectForKey:key] isMemberOfClass:[NSString class]]) {
start.[self.mappings objectForKey:key] = [[dict valueForKey:key] stringValue];
}
}
return start;
}
mappings
is th开发者_如何学JAVAe dictionary that has the variables and json keys, and the dict
is what gets returned from the json parser.
The big problem is that I can't do start.[self.mappings objectForKey:key]
. I don't know much about C, and clearly I don't know enough about pointers, so how would I go about creating this kind of system? I know that's not the right way to do this, but what is the right way? I know it can be done, as RestKit does it, but they don't support OAuth so I sadly can't use their lovely framework.
The reason I'm going this route is because the API I'm working with is currently in its alpha stage. I want to be able to easily adapt to any future changes without having to rewrite many lines of code. I also want to start programming DRY-ly. I know JSON parsing is very repetitive, and I'd like to find a way to reduce the amount of overhead.
Thanks for any and all help!
EDIT: It seems there is some confusion as to what I'm asking. I do not need help parsing JSON. I'm using SBJSON already. I do not need help making requests, I am already using JDG's OAuthConsumer framework. I can only use frameworks that support OAuth 2.0.
I do need help figuring out how to prevent this:
-(Class1 *)parseJsonForClass1:(NSString *)inputString {
NSDictionary *outputDict = [inputString JSONValue];
Class1 *instance1 = [self mapObjectsForClass1From:outputDict];
return instance1;
}
-(Class2 *)parseJsonForClass2:(NSString *)inputString {
NSDictionary *outputDict = [inputString JSONValue];
Class2 *instance2 = [self mapObjectsForClass2From:outputDict];
return instance2;
}
-(Class3 *)parseJsonForClass3:(NSString *)inputString {
NSDictionary *outputDict = [inputString JSONValue];
Class2 *instance3 = [self mapObjectsForClass3From:outputDict];
return instance3;
}
-(Class1 *)mapObjectsForClass1From:(NSDictionary *)dict {
Class1 *object1 = [[Class1 alloc] init];
object1.name = [[dict valueForKey:@"name"] stringValue];
object1.date = [[dict valueForKey:@"date"] stringValue];
object1.objId = [[dict valueForKey:@"id"] intValue];
return object1;
}
-(Class2 *)mapObjectsForClass2From:(NSDictionary *)dict {
Class2 *object2 = [[Class2 alloc] init];
object2.something = [[dict valueForKey:@"something"] stringValue];
object2.title = [[dict valueForKey:@"title"] stringValue];
object2.imageUrl = [[dict valueForKey:@"image_url"] stringValue];
return object2;
}
-(Class3 *)mapObjectsForClass3From:(NSDictionary *)dict {
Class3 *object3 = [[Class3 alloc] init];
object3.foo = [[dict valueForKey:@"bar"] stringValue];
object3.flag = [[dict valueForKey:@"is_member"] boolValue];
object3.obj1 = [[Class1 alloc] init];
object3.obj1 = [self mapOjectsForClass1From:[dict objectForKey:@"name1"]];
return object3;
}
So please let me know if you have any suggestions on how to combine these kinds of methods into 1 method...
I know this is an old thread but thought to put this here, the code here in https://github.com/mystcolor/JTObjectMapping would be able help in object mapping. You will want to have the mappings and your custom object ready before you use this. I found this on googling ....havent used it though. Need to try it out.
You could use KVC. Create a setter for each value in the JSON dictionary that you want to insert into your object and use -setValue:forKey:
to actually set the values e.g.
-(NSObject *)parseJSONFromDictionary:(NSDictionary *)dict withObject:(NSObject *)start
{
for (NSString *key in [dict allKeys])
{
NSString* propertyName = [[self mappings] objectForKey: key];
[start setValue: [dict objectForKey: key] forKey: propertyName];
// the above line will throw an exception if start does not have a set accessor for property
}
return start;
}
I actually recently saw someone doing this using Objective Resources. While it's a nice way to access objects, some of the implementation can get messy. And you have to use everything the server sends you, whether you like it or not. I'm going to stay away from this right now.
Also look at HTTPRiot which takes care of most of the communications effort off your shoulder, handles connections asynchronously, etc. This Tutorial about JSON communications with iOS (Ruby bent, but minimal) shows how to use it; some of the code is outdated, but overall gets the message through.
精彩评论