Getting “this class is not key value coding-compliant for the key id.” when requesting RestKit loadObjectsAtResourcePath

StackOverflow https://stackoverflow.com/questions/8871459

Question

I'm trying to deserialise JSON data into my iPhone application using RestKit's RKObjectManager.

My current issue is the app crashes with a :

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Course 0x6e71b10> valueForUndefinedKey:]: this class is not key value coding-compliant for the key id.'

when I call:

[manager loadObjectsAtResourcePath:@"/courses" delegate:nil];

My domain class - Course.h looks like

#import <Foundation/Foundation.h>



@interface Course : NSObject  {

}

@property(nonatomic) NSInteger *id;

@property(nonatomic, retain) NSString *name;

-(id)initWithIdAndName: (NSInteger *)inId inName:(NSString *)inName;
@end

and the Course.m looks like

#import "Course.h"
#import "NSDictionary+RKAdditions.h"


@implementation Course {

}
@synthesize name = _name;
@synthesize id = _id;

- (id)initWithIdAndName:(NSInteger *)inId inName:(NSString *)inName {
    _name = inName;
    _id = inId;
    return self;

}

#pragma mark NSCoding Protocol


- (void)encodeWithCoder:(NSCoder *)encoder;
{
[encoder encodeInteger:[self id] forKey:@"id"];
[encoder encodeObject:[self name] forKey:@"name"];
}

- (id)initWithCoder:(NSCoder *)decoder;
{
if ( ![super init] )
    return nil;

[self setId:[decoder decodeIntForKey:@"id"]];
[self setName:[decoder decodeObjectForKey:@"name"]];


return self;
}

@end 

The Json data retrieved from the server is

{"courses":[{"id":1,"name":"course 1"},{"id":2,"name":"course 2"}]}

And the RKObjectManager is invoked using the following code:

RKObjectMapping* courseMapping = [RKObjectMapping mappingForClass:[Course class]];
[courseMapping mapKeyPath:@"id" toAttribute:@"id"];
[courseMapping mapKeyPath:@"name" toAttribute:@"name"];


RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:@"http://firstbit/of/url"];

[manager.mappingProvider setMapping:courseMapping forKeyPath:@"courses"];
[manager loadObjectsAtResourcePath:@"/endpoint" delegate:nil];

Any ideas on this one?

Was it helpful?

Solution

It might help others, but I had this problem and the reason was that I was using NSInteger in my object definition. RestKit cannot map to NSInteger, only NSNumber.

OTHER TIPS

I got the same error, although my issue was simply forgetting to remove the @dynamic directive with @synthesize in changing my test from using CoreData.


I am posting this as an alternative answer. The answers so far are totally correct. There is one more permutation that took me awhile to find. The simulator may have cached a bundle resource for the program. If this bundle resource is out of date you can get a conflict. The easiest solution: "uninstall" the app from the simulator (and potentially other apps that may have a same name bundle). Once I did this, I found the real issue immediately as I had not correctly attached my bundle to the parent project form an sdk project.

Might be worth checking the JSON your getting back is valid & in the format (keys / value types), you expect - I've had this exact same issue with RESTKit before

I use 'JSON Validator' & 'Visual JSON', both free on the Mac App Store

Alternatively make sure your CoreData Entity allows to-many mappings for courses

This one probably seems obvious, but it got me for two days...

Make sure all the classes in your RKObjectMappings are correct! It was one little typo where I was using the parent class for a nested element's mapping, in a line of code I never looked at because I assumed it was definitely correct, and it was making the whole thing crash.

Unfortunately, this error can come up due to a number of issues that have to do with attribute or relationship mappings.

This includes typos in any of your attribute names.

Remember, an attribute or relationship mapping isn't correct unless it aligns with your API. For example, I just ran into this error because of something like the following:

Each Restaurant model has a foreign key relationship to the Location model.

[restaurantMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"location" toKeyPath:@"location" withMapping:locationMapping]];

But the API I'm using returns something like the following JSON data for a Restaurant object:

{
    "id": 42,
    "resource_uri": "http://example.com/api/v1/restaurants/42",
    "location": "http://example.com/api/v1/locations/987"
}

RestKit is looking for a full response like the following:

{
    "id": 42,
    "resource_uri": "http://example.com/api/v1/restaurants/42",
    "location": {
        "id": 987,
        "resource_uri": "http://example.com/api/v1/locations/987"
    }
}

Note the different location value.

I imagine you could also alter RestKit to handle former API response, but that mismatch of expectations could cause this type of error.

The accepted answer state that RestKit cannot map to NSInteger which I found it's not entirely true because I've encountered the the same problem recently and solved it just by remove the * of the NSInteger property.

I use @property(nonatomic) NSInteger id; instead of @property(nonatomic) NSInteger *id;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top