0

I have a response descriptor that maps a response using a keyPath such as @"rootKey.subKey", where rootKey is a dictionary and subKey is an array. e.g.

{rootKey:{subKey:[@"object1", @"object2",...,]}}

But some times I get the following response:

{rootKey:@""}

And my app crashes with an exception that NSString isn't key value coding-compliant for the key 'subKey'.

Any ideas how can I handle such situations?

Wain
  • 118,658
  • 15
  • 128
  • 151
Shuaib
  • 11
  • 1
  • 3

2 Answers2

0

Best option, fix the JSON.

Fallback option, use a dynamic mapping to check what has been received and create a mapping on the fly to handle it.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • I actually tried that, but it seems like the crash still happens even if in such a case I return a 'nil' response mapping to use when no 'subKey' is pressent i.e. root object is string. – Shuaib Oct 07 '14 at 18:36
  • So that's the entire JSON and you only want that one sub key? Fix the response (should return an http status code to indicate no content in this case). – Wain Oct 07 '14 at 18:40
  • Any hints on a solution other than fixing the api response? If all fails I might go ahead and make a complex relationship based mapping to be able to detect when expected object isn't there. – Shuaib Oct 07 '14 at 18:42
  • You could look at creating a mapping which creates an error object when the dynamic mapping finds no real content and then handle the error object in the success callback. – Wain Oct 07 '14 at 21:02
0

The way I handled it was to create a response descriptor for the top level key, i.e. @"rootKey", instead of @"rootKey.subKey", and created a top level object that only has a single relationship property "subKeys". Then I created a dynamic mapping which based on the representation of the top level objects, either returns a mapping for the subKeys, or nil:

RKEntityMapping *responseMapping = [RKEntityMapping mappingForEntityForName:@"RootObject" inManagedObjectStore:managedObjectStore];
[responseMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"subKeys" toKeyPath:@"subKeys" withMapping:subKeysMapping]];

RKDynamicMapping* dynamicMapping = [RKDynamicMapping new];
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
    if ([representation isKindOfClass:[NSDictionary class]]) {
        return responseMapping;
    }
    return nil;
}];

return dynamicMapping;

This leads to having an unnecessary top level object (RootObject) but handles the response gracefully when instead of a key-value object, I get a string.

Shuaib
  • 11
  • 1
  • 3