Obtenir "cette classe n'est pas compatible avec le codage des valeurs de clé pour l'ID de clé."lors de la demande de RestKit loadObjectsAtResourcePath

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

Question

J'essaie de désérialiser les données JSON dans mon application iPhone à l'aide du RKObjectManager de RestKit.

Mon problème actuel est que l'application plante avec un:

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

quand j'appelle:

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

Ma classe de domaine - Course.h ressemble à

#import <Foundation/Foundation.h>



@interface Course : NSObject  {

}

@property(nonatomic) NSInteger *id;

@property(nonatomic, retain) NSString *name;

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

et Course.m ressemble à

#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 

Les données Json récupérées sur le serveur sont

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

Et le RKObjectManager est appelé en utilisant le code suivant:

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];

Des idées sur celui-ci?

Était-ce utile?

La solution

Cela pourrait aider les autres, mais j'ai eu ce problème et la raison était que j'utilisais NSInteger dans ma définition d'objet. RestKit ne peut pas mapper vers NSInteger, uniquement NSNumber .

Autres conseils

J'ai eu la même erreur, même si mon problème était simplement d'oublier de supprimer la directive @dynamic avec @synthesize en modifiant mon test en utilisant CoreData.


Je publie ceci comme réponse alternative.Les réponses à ce jour sont totalement correctes.Il y a une autre permutation qui m'a pris du temps à trouver.Le simulateur peut avoir mis en cache une ressource de bundle pour le programme.Si cette ressource de bundle est obsolète, vous pouvez obtenir un conflit.La solution la plus simple: «désinstaller» l'application du simulateur (et potentiellement d'autres applications qui peuvent avoir un ensemble de même nom).Une fois que j'ai fait cela, j'ai trouvé le vrai problème immédiatement car je n'avais pas correctement attaché mon bundle au projet parent d'un projet sdk.

Cela pourrait valoir la peine de vérifier le JSON que votre retour est valide et dans le format (clés / types de valeur), vous vous attendez - j'ai eu exactement le même problème avec RESTKit avant

J'utilise 'JSON Validator' et 'Visual JSON', tous deux gratuits sur le Mac App Store

Vous pouvez également vous assurer que votre entité CoreData autorise les mappages à plusieurs pour les courses

Celui-ci semble probablement évident, mais il m'a eu pendant deux jours ...

Assurez-vous que toutes les classes de vos RKObjectMappings sont correctes!C'était une petite faute de frappe où j'utilisais la classe parente pour le mappage d'un élément imbriqué, dans une ligne de code que je n'ai jamais regardée parce que je supposais que c'était définitivement correct, et cela faisait planter le tout.

Malheureusement, cette erreur peut survenir en raison d'un certain nombre de problèmes liés aux mappages d'attributs ou de relations .

Cela inclut les fautes de frappe dans l'un de vos noms d'attribut.

N'oubliez pas qu'un mappage d'attribut ou de relation n'est pas correct à moins qu'il s'aligne sur votre API .Par exemple, je viens de rencontrer cette erreur à cause de quelque chose comme ce qui suit:

Chaque modèle Restaurant a une relation de clé étrangère avec le modèle Location.

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

Mais l'API que j'utilise renvoie quelque chose comme les données JSON suivantes pour un objet Restaurant:

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

RestKit recherche une réponse complète comme la suivante:

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

Notez les différentes valeurs de location.

J'imagine que vous pourriez également modifier RestKit pour gérer l'ancienne réponse de l'API, mais cette inadéquation des attentes pourrait provoquer ce type d'erreur.

La réponse acceptée indique que RestKit ne peut pas mapper à NSInteger, ce que j'ai trouvé que ce n'est pas tout à fait vrai car j'ai rencontré le même problème récemment et je l'ai résolu simplement en supprimant le * de la propriété NSInteger.

J'utilise @property(nonatomic) NSInteger id; au lieu de @property(nonatomic) NSInteger *id;

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top