Mapping JSON representations to a "rich" domain model in ObjC is a bit cumbersome. Similar is true when mapping a JSON data/response to a NSMangedObject (and vise versa). There is a base framework for "remote persistence", via the CoreData API, by leveraging a custom NSIncrementalStore -> AFIncrementalStore.
For that,... a similar two-way-mapping is required, as described here.
Our CoreData offerings are leveraging the AFIncrementalStore, therefore (as with other frameworks/libraries) we need a mapping as well. We need to know the name of the entity and we need a NSDictionary
that covers the actual JSON/property mapping. It could be done with the vanialla ObjC classes:
// some mappers:
NSDictionary *task_mapper =
[NSDictionary dictionaryWithObjectsAndKeys:@"description",@"desc",@"id",@"myId", nil];
NSDictionary *project_mapper =
[NSDictionary dictionaryWithObjectsAndKeys:@"id",@"myId", nil];
// create a schema out of the mappers:
NSDictionary *schema =
[NSDictionary dictionaryWithObjectsAndKeys:task_mapper, @"Task", project_mapper, @"Project", nil];
// pass the schema to the AGCoreDataHelper class, when doing the init...
I'd like to introduce a new wrapper type, called AGEntityMapper
:
@interface AGEnityMapper : NSObject
@property NSString *name;
@property NSDictionary *mapper;
-(id) initWithName:(NSString *) name mapper:(NSDictionary *) mapper;
@end
This AGEntityMapper
would be applied onto the AGCoreDataConfig
:
@protocol AGCoreDataConfig <NSObject>
@property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (strong, nonatomic) NSURL *baseURL;
-(void)applyEntityMappers:(AGEnityMapper *)firstObject, ... NS_REQUIRES_NIL_TERMINATION;
@end
The actual code, would look like this:
EnityMapper *taskMapper =
[[EnityMapper alloc] initWithName:@"Task"
// mapping the properties on the "entity" (NSManagedObject)
// to the external representation (e.g. JSON)
mapper:@{ @"desc": @"description", @"myId": @"id"}];
EnityMapper *projectMapper =
[[EnityMapper alloc] initWithName:@"Project"
// mapping the properties on the "entity" (NSManagedObject)
// to the external representation (e.g. JSON)
mapper:@{ @"myId": @"id"}];
AGCoreDataHelper *helper = [[AGCoreDataHelper alloc] initWithConfig:^(id<AGCoreDataConfig> config) {
[config setBaseURL:[NSURL URLWithString:@"http://server.com"]];
[config applyEntityMappers:
taskMapper,
projectMapper,
nil // terminate the varargs.
];
}];