iosobjective-crestkitrestkit-0.20

RestKit Collection - The Proper Key Path?


I have the following JSON coming from my server...

{"Devices": [
  {
    "uuid": "d9084134-d5f7-43a3-9613-7faa769a822a",
    "label": "",
    "location": "a13d45f4-5ce0-48e3-bc3f-4076bb007037",
    "capability": 0
  },
  {
    "uuid": "a4ee0d3f-4a6a-4c61-81bd-3dfa9ab19e85",
    "label": "",
    "location": "a13d45f4-5ce0-48e3-bc3f-4076bb007037",
    "capability": 3
  }
]}

I'm trying to map this properly but I'm struggling with it... I have the following mappings setup...

RKEntityMapping *entityMapping = [RKEntityMapping mappingForEntityForName:@"Device" inManagedObjectStore:managedObjectStore];

    [entityMapping setIdentificationAttributes:[NSArray arrayWithObject:@"uuid"]];

    [entityMapping addAttributeMappingsFromDictionary:@{
                                                        @"uuid":                        @"uuid",
                                                        @"label":                       @"label",
                                                        @"location":                    @"location",
                                                        @"capability":                  @"capability"
                                                        }];

    // GET

    RKRequestDescriptor *getRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[entityMapping inverseMapping] objectClass:[Device class] rootKeyPath:@"Device" method:RKRequestMethodGET];
    [[RKObjectManager sharedManager] addRequestDescriptor:getRequestDescriptor];

    [[RKObjectManager sharedManager].router.routeSet addRoute:[RKRoute routeWithClass:[Device class] pathPattern:@"Devices" method:RKRequestMethodGET]];

    RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping method:RKRequestMethodGET pathPattern:@"Devices" keyPath:@"Devices" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    [[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor];

I have my keyPath set to "devices" which I would've thought would work. But RestKit isn't understanding it.

I'm using the following to get the objects from my server...

[[RKObjectManager sharedManager] getObjectsAtPath:@"Devices" parameters:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%d", clientID], @"clientId", @"topic", @"forTopic", nil] success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    ...
}... // Abbreviated for brevity.

So I believe my path "Devices" is correct for the pathPattern of "Devices". Are the parameters messing it up? I've had parameters before and it's always worked without having to specify anything in the mapping.

I'm using RestKit 0.27.1 currently.

UPDATE - Fixed JSON

I fixed the JSON as mentioned by Mahendra GP. So this is now a proper array. The RestKit log is now showing the JSON coming through in the trace log. However it still can't identify which object it is (Device).

Snippet of the log...

...and targetObject: (null)
2018-03-09 02:44:05.603734-0700 MyTestApp[31576:6868006] D restkit.object_mapping:RKMapperOperation.m:440 Finished performing object mapping. Results: (null)
2018-03-09 02:44:05.605334-0700 MyTestApp[31576:6868006] E restkit.network:RKObjectRequestOperation.m:172 GET 'http://[MY_IP]:8080/Devices?clientId=5199&forTopic=topic' (200 OK / 0 objects) [request=2.6488s mapping=0.0000s total=2.6633s]: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No response descriptors match the response loaded." 

Solution

  • I finally figured out my issue by fluke trial and error. I wasn't able to find any specific posts on SO or over on RestKit's site. Therefore I thought I would post the, simple, solution to the problem here.

    I kept getting errors that none of my response descriptors matched any of the key paths. I thought it had to do with the parameters I was passing to the GET as it would show that in the error trying to compare it to just the Devices path that the response descriptor was setup with. However this turned out not to be the issue at all.

    The issue was with my RKResponseDescriptor setup. I originally had...

      RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping method:RKRequestMethodGET pathPattern:@"Devices" keyPath:@"Devices" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    

    The solution here is the "pathPattern". This needed to be set to nil.

    I've been using RestKit for many many years. Prior to the 0.2x releases. I remembered something about RestKit being able to identify an entity and it's multiple just by pluralizing it. I finally thought that perhaps because I was specifying it in the pathPattern it was causing the issue. So once I eventually set that to nil it finally started working. I actually think the reason why was that setting it to nil was like setting it it to a wildcard for any pathPattern since my path actually had parameters tagged onto them.

    However in another use case I had I did specify the pathPattern but instead of it being the plural of the mapped entity it was something different. So instead of Devices I had something like DeviceForUser. So there seems to be a problem when specifying the plural of the entity in the pathPattern. Especially if using parameters in the getObjectsAtPath call.

    So for clarity, all of the code above is the same. It just needs this change...

      RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping method:RKRequestMethodGET pathPattern:nil keyPath:@"Devices" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    

    I hope this helps anyone else who might run into this.