JSON Dictionary
prefect42 opened this issue · 4 comments
Not all APIs respond with a JSON object that has the needed data on the top level. Some have a "data" object. Some have an object with their own name "profile", "message", etc.
It would be great to
a Be able to forward the data path through a parameter
b Have the parser identify that the heirarchy is deeper and automatically try to parse the appropriate key if the top level object fails.
// Appendix
Hey Oliver. First of all great job on the framework
I think you misunderstood me yesterday. I was not talking about a mapping on an attribute.
That does indeed work very well as you proved with your tests.
I was talking about a raw dictionary that is used to update a managed object.
In
+ (instancetype)updatedObjectWithRawJSONDictionary:(NSDictionary *)rawDictionary
relationshipUpdateLevel:(NSInteger)relationshipUpdateLevel
inManagedObjectContext:(NSManagedObjectContext *)context
{
SLAttributeMapping *attributeMapping = [self attributeMapping];
SLObjectConverter *objectConverter = [self objectConverter];
if (![rawDictionary isKindOfClass:NSDictionary.class]) {
NSLog(@"WARNING: JSON Object is not a NSDictionary (%@)", rawDictionary);
return nil;
}
Class modelClass = [objectConverter subclassForRawJSONDictionary:rawDictionary] ?: self;
NSString *uniqueKeyForJSONDictionary = [self objectDescription].uniqueIdentifierOfJSONObjects;
NSString *modelClassName = NSStringFromClass(modelClass);
NSString *managedObjectUniqueKey = [attributeMapping convertJSONObjectAttributeToManagedObjectAttribute:uniqueKeyForJSONDictionary];
id JSONObjectID = rawDictionary[uniqueKeyForJSONDictionary];
id managedObjectID = [objectConverter managedObjectObjectFromJSONObjectObject:JSONObjectID
forManagedObjectAttribute:managedObjectUniqueKey];
if (!managedObjectID) {
NSLog(@"WARNING: JSON Object did not have an id (%@)", rawDictionary);
return nil;
}
......
}
you are just checking if the rawDictionary is an NSDictionary. If it is you assume you can just parse for the unique id.
But what if the NSDictionary is like so:
{
"profile": {
......
}
}
How can tell your parser to expect the data object in profile?
With the referenced commit, I added some tests verifying the already implemented behavior as mentioned by a). Feel free to register any custom attribute mapping like:
[self registerAttributeName:@"otherString" forJSONObjectKeyPath:@"some_dictionary.string_value"];
Regarding b, SLRESTfulCoreData has rich support for to one relationships that are encoded in a JSON dictionary. Making any other guesses about attributes not being encoded in the top level JSON object is not supported by design.
Please read the update on the original issue!
Thanks!
For me, returning a profile from for example a route /bla/profile
and returning it with a JSON object like
{
"profile": {
}
}
feels kind of redundant for me and that is why there is no support for this. To solve this, you could implement
- (void)updateWithRawJSONDictionary:(NSDictionary *)d
{
[super updateWithRawJSONDictionary:d[@"profile"]];
}
in your NSManagedObject subclass.
Thats very good. Thank you very much.