RestKit complexe et simple JSON RKObjectMapping fonctionne presque, mais

J'ai fait des searchs sur ce problème. Voici quelques découvertes qui aideront à mapper cette réponse JSON dans RestKit

L'object de réponse JSON contient trois objects de niveau supérieur: locations est un tableau object cityKey
object stateKey

Since Restkit is written in Objective-C, I looked at it as if I were going to directing cartographie de ces objects et parsingr datatables

J'ai écrit le code suivant pour mapper la partie NSDictionary de la class de classs \ Object:

  RKObjectMapping* locationMapping = [RKObjectMapping mappingForClass:[Location class]]; [locationMapping addAtsortingbuteMappingsFromDictionary:@{ @"distance": @"distance", @"major": @"major", @"minor": @"minor" }]; 

J'ai écrit le code suivant pour l'set class \ object, Emplacements: // Ceci devrait aussi être un NSDictionary

  RKObjectMapping *locationsMapping = RKObjectMapping mappingforclass: [Locations class]]; This appears to be a mapping array should be a dictionary. [locationsMapping addAtsortingbuteMappingsFromArray:@[@"locations", @"cityKey",@"stateKey"]]; 

Je vois l'erreur dans l'utilisation de Array pour l'set des locations d'objects. Cela s'exécute et renvoie un résultat partiellement réussi à partir de ce qui suit:

 RKResponseDescriptor *locationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:locationMapping method:RKRequestMethodAny pathPattern:@"/location" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; [[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor]; [[RKObjectManager sharedManager] addResponseDescriptor:locationDescriptor]; [[RKObjectManager sharedManager] postObject:nil path:(_enterLocation) parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { NSLog(@"It Worked: %@", [mappingResult array]); } failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(@"It Failed: %@", error); }]; This returns the successful responseJSONdata, but mappingResult dictionary returns: 2014-05-07 17:28:39.770 MyApp[163:60b] It Worked: { locations = ( ); } The actual JSONOBJECTWITHDATA returned as response.body is: response.body={ "locations": [  {   "distance": 0.5,   "major": 2,   "minor": 4,    },  {   "distance": 1.0,   "major": 2,   "minor": 11,    } ], "cityKey": "12", "stateKey": "41" } 

De la lecture,

La cartographie dynamic de RestKit va-t-elle résoudre ce mappage JSON complexe?

et

Envoyer des données analysées à RKMapperOperation renvoie NSUnknownKeyException

Je sais que j'ai besoin de changer mon approche de la cartographie RestKit. Pour le cas complexe

Même dans le cas simple, je returnne seulement un pointeur sur l'object.

  RKObjectMapping *statusResponseMapping = [RKObjectMapping mappingForClass:[StatusResponse class]];  [statusResponseMapping addAtsortingbuteMappingsFromDictionary:@{@"status":@"status"}]; RKResponseDescriptor *statusResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:statusResponseMapping method:RKRequestMethodPOST pathPattern:nil keyPath:@"response" statusCodes:statusCodes]; 

Je reçois la réponse correcte du server … mais seulement get un pointeur

  response.body={ "response": {  "status": "ok" } } 2014-05-07 17:11:47.362 MyApp[145:60b] It Worked: {  response = "<StatusResponse: 0x16ee2e10>"; } 

Il me manque une étape key ou une définition de mappage. Je suis presque au résultat désiré.

Que dois-je faire pour get les résultats souhaités dans les cas simples et complexes?

MISE À JOUR MA QUESTION AVEC LES NOUVELLES INFORMATIONS CI-DESSOUS

Mise à jour aujourd'hui 8 mai 2014, j'ai changé de lieuModification du code à …

 RKObjectMapping *locationsMapping = [RKObjectMapping mappingForClass:[Locations class]]; [locationsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"locations" toKeyPath:@"locations" withMapping:locationMapping]]; 

Ce qui l'a rapproché de la cartographie correcte. Le résultat était …

 2014-05-08 13:28:17.795 MyApp[165:60b] It Worked: { locations = ( "<Locations: 0x14e69a10>", "<Locations: 0x14e695c0>" ); 

Ce qui est presque correct. Il me semble qu'il manque un mapping pour cityKey et StateKey. Je n'ai pas défini la méthode Description. Voici datatables JSON brutes returnnées …

 response.body={ "locations": [ { "distance": 0.6, "major": 2, "minor": 4 }, { "distance": 1.0, "major": 2, "minor": 11 } ], "cityKey": "11", "stateKey": "21" } 

Mappage ne renvoie pas les cityKey et stateKey … quelque chose manque encore dans la définition de mappage?

MISE À JOUR LE 9 MAI 2014 APRÈS AVOIR MODIFIÉ locationmap comme suggéré

 RKObjectMapping *locationsMapping = [RKObjectMapping mappingForClass:[Locations class]]; [locationsMapping addAtsortingbuteMappingsFromArray:@[ @"cityKey",@"stateKey"]]; [locationsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"locations" toKeyPath:@"locations" withMapping:locationMapping]]; response.body={ "locations": [  {   "distance": 0.6,   "major": 2,   "minor": 4  },  {   "distance": 1.0,   "major": 2,   "minor": 11  } ], "cityKey": "10", "stateKey": "15" } 2014-05-09 13:18:17.669 MyApp[211:60b] It Worked: {  locations =   (    "<Locations: 0x1780341e0>",    "<Locations: 0x170027c40>"  ); } 

Il manque toujours cityKey et stateKey … pas sûr de ce qu'il faut essayer ensuite?

MISE À JOUR 05/12/2014 POUR S'ADRESSER AUX DESCRIPTEURS DE RÉPONSE …

J'ai eu deux descripteurs de réponse. J'ai manqué d'en postr un dans la description originale.

 RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:locationMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"locations" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];  RKResponseDescriptor *locationDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:locationsMapping method:RKRequestMethodAny pathPattern:@"/location" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];    [[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor];  [[RKObjectManager sharedManager] addResponseDescriptor:locationDescriptor]; 

J'ai changé la structure comme recommandé mais il me manque toujours les cityKey et stateKey … devrais-je utiliser un seul descripteur de réponse?

J'ai trouvé une réponse à l'utilisation de plus d'un ResponseDescriptor? ici dans cet article http://www.softwarepassion.com/parsing-complex-json-with-objective-c-and-restkit/

Quand j'ai examiné comment l'auteur a défini ses POJO, j'ai découvert qu'un seul ResponseDescriptor était requirejs. Le rest est géré dans la cartographie et la définition des relations …

MISE À JOUR LE 15 MAI 2014

J'ai testé les descripteurs de réponse. Un seul travaillait réellement pour générer le résultat "Ça a marché". Le file locationDescriptor ne fonctionnait pas du tout. Il a généré une erreur lorsqu'il est utilisé seul. Il a été ignoré lorsqu'il est utilisé comme une partie de la paire. Le descripteur qui fournissait systématiquement le "Ça marche" avec datatables d'location était responseDescriptor avec le path de key comme @ "locations".

J'ai lu http://blog.mobilejazz.cat/ios-using-kvc-to-parse-json/

J'ai une question à propos de "… est la sortie de journal attendue d'une class personnalisée que vous créez mais qui n'a pas d'implémentation de méthode de description." Qu'entend-on par implémentation de la méthode de description? Que dois-je append pour modifier ce qui suit dans un NSArray ou un NSDictionary de résultats de mappage? Pourriez-vous partager un exemple basé sur les locations ci-dessous?

 2014-05-09 13:18:17.669 MyApp[211:60b] It Worked: {  locations =   (    "<Locations: 0x1780341e0>",    "<Locations: 0x170027c40>"  ); 

MISE À JOUR LE 16 MAI 2014 AJOUTÉ SUGGÉRÉ DESCRIPTION DE NSSTRING AUX FICHIERS DE MISE EN ŒUVRE DE CLASSE

 response.body={ "response": { "status": "ok" } } 2014-05-16 10:32:26.260 MyApp[202:60b] It Worked: { response = "status: ok"; } 

Par conséquent, je count la mise en œuvre de la méthode de description NSSsortingng répondu et fonctionne correctement.

LA DEUXIÈME PARTIE DE LA MISE À JOUR EST AVEC LES DESCRIPTEURS DE LA MÉTHODE EN PLACE JE PEUX VOIR QUE JE NE ME PROCURE PAS LE JSON MAPPED AUX VALEURS DE LA STRUCTURE DES DONNÉES AU LIEU J'AI OBTENIR NULL

 response.body={ "locations": [ { "distance": 0.0, "major": 2, "minor": 8, }, { "distance": 3.5, "major": 2, "minor": 9, }, { "distance": 2.6575364531836625, "major": 2, "minor": 10, } ], "cityKey": "10", "stateKey": "21" } 2014-05-16 09:48:08.328 MyApp[189:60b] It Worked: { locations = ( "location: (null) city: (null) state: (null)", "location: (null) city: (null) state: (null)", "location: (null) city: (null) state: (null)" ); } 

Le premier problème est que je devrais get un location {distance, majeur, mineur} pour les trois locations dans le tableau de dictionarys et un cityKey et un stateKey. Voici le code de mappage

 RKObjectMapping* locationMapping = [RKObjectMapping mappingForClass:[Location class]]; [locationMapping addAtsortingbuteMappingsFromDictionary:@{ @"distance": @"distance", @"major": @"major", @"minor": @"minor" }]; RKObjectMapping *locationsMapping = [RKObjectMapping mappingForClass:[Locations class]]; [locationsMapping addAtsortingbuteMappingsFromArray:@[ @"cityKey",@"stateKey"]]; [locationsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"locations" toKeyPath:@"locations" withMapping:locationMapping]]; //05/16/2014 this ResponseDesciptor is working RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:locationsMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"locations" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; [[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor]; 

Pourquoi renvoie-t-il plusieurs cityKey et stateKey pour chaque location? Pourquoi les résultats sont-ils nuls lorsque datatables JSON sont renvoyées?

MISE À JOUR LE 19 MAI 2014 EXCEPTION JETÉE lorsque keyPath est défini sur zéro et non sur "locations"

 2014-05-19 10:53:53.902 MyApp[245:4907] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Locations 0x17022d960> valueForUndefinedKey:]: this class is not key value coding-compliant for the key locations.' *** First throw call stack: 

CODE RAISING IT Ligne de code RestKit 364

 if ([self.dataSource respondsToSelector:@selector(mappingOperationShouldSetUnchangedValues:)] && [self.dataSource mappingOperationShouldSetUnchangedValues:self]) return YES; id currentValue = [self.destinationObject valueForKeyPath:keyPath]; if (currentValue == [NSNull null]) { currentValue = nil; } 

Fichiers d'en-tête de class

 #import <Foundation/Foundation.h> @class Location; @interface Locations : NSObject @property (nonatomic, copy) Location *location; @property (nonatomic, copy) NSSsortingng *cityKey; @property (nonatomic, copy) NSSsortingng *stateKey; @end 

Fichier de mise en place des classs

 #import "Locations.h" @implementation Locations -(NSSsortingng *)description { return [NSSsortingng ssortingngWithFormat:@"location: %@ cityKey: %@ stateKey: %@", self.location, self.cityKey, self.stateKey]; } @end 

EMPLACEMENTS CHANGÉS CLASS PROPRIÉTÉ DE

 @property (nonatomic, copy) Location *location; 

À

 @property (nonatomic, copy) NSMutableArray *locations; 

REÇU LE RÉSULTAT DÉSIRÉ lorsque keyPath est nul

 response.body={ "locations": [ { "distance": 0.0, "major": 2, "minor": 8 }, { "distance": 3.5, "major": 2, "minor": 9 }, { "distance": 2.6575364531836625, "major": 2, "minor": 10 } ], "cityKey": "1", "stateKey": "1" } 2014-05-19 14:19:45.040 MyApp[290:60b] It Worked: { "<null>" = "location: (\n \"distance: 0 major: 2 minor: 8 \",\n \"distance: 3.5 major: 2 minor: 9 \",\n \"distance: 2.657536453183662 major: 2 minor: 10 \"\n) cityKey: 1 stateKey: 1"; } 

Qui a résolu ce problème.

Lorsque vous créez des locationsMapping , @"locations" doit être ajouté en tant que relation à l'aide de locationMapping (pas directement en tant qu'atsortingbut).

Vous devriez avoir un descripteur de réponse qui utilise locationsMapping .

Ce:

 2014-05-07 17:11:47.362 MyApp[145:60b] It Worked: { response = "<StatusResponse: 0x16ee2e10>"; } 

est la sortie de journal attendue d'une class personnalisée que vous créez mais qui n'a pas d'implémentation de méthode de description .


 RKObjectMapping *locationsMapping = [RKObjectMapping mappingForClass:[Locations class]]; [locationsMapping addAtsortingbuteMappingsFromArray:@[@"cityKey", @"stateKey"]]; [locationsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"locations" toKeyPath:@"locations" withMapping:locationMapping]]; 

Dans votre class " Locations , ajoutez:

 - (NSSsortingng *)description { return [NSSsortingng ssortingngWithFormat:@"city:%@ state:%@ locations:%@", self.cityKey, self.stateKey, self.locations]; } 

et une méthode similaire à la class de Location .