Reputation: 808
I'm unable to map my JSON to Core Data with RestKit. RK logging is saying:
Did not find mappable relationship value keyPath.
I'm clearly doing something wrong.
Log:
2012-11-20 15:40:36.525 eMobile[44849:12603] T restkit.object_mapping:RKObjectMappingOperation.m:342 Mapping attribute value keyPath 'OBJECTCLASS' to 'type'
2012-11-20 15:40:36.525 eMobile[44849:12603] T restkit.object_mapping:RKObjectMappingOperation.m:359 Skipped mapping of attribute value from keyPath 'OBJECTCLASS to keyPath 'type' -- value is unchanged (SFAACCOUNT)
2012-11-20 15:40:36.525 eMobile[44849:12603] T restkit.object_mapping:RKObjectMappingOperation.m:342 Mapping attribute value keyPath 'TIMESTAMP' to 'timestamp'
2012-11-20 15:40:36.526 eMobile[44849:12603] T restkit.object_mapping:RKObjectMappingOperation.m:352 Mapped attribute value from keyPath 'TIMESTAMP' to 'timestamp'. Value: 2012-11-20T15:40:08Z
2012-11-20 15:40:36.526 eMobile[44849:12603] D restkit.object_mapping:RKObjectMappingOperation.m:483 Did not find mappable relationship value keyPath 'VALUES'
2012-11-20 15:40:36.526 eMobile[44849:12603] D restkit.object_mapping:RKObjectMappingOperation.m:662 Finished mapping operation successfully...
2012-11-20 15:40:36.526 eMobile[44849:12603] T restkit.object_mapping:RKObjectMapper.m:293 Examining keyPath 'VALUES' for mappable content...
2012-11-20 15:40:36.527 eMobile[44849:12603] D restkit.object_mapping:RKObjectMapper.m:303 Found unmappable value at keyPath: VALUES
2012-11-20 15:40:36.527 eMobile[44849:12603] D restkit.object_mapping:RKObjectMapper.m:367 The following operations are in the queue: (
)
2012-11-20 15:40:36.527 eMobile[44849:12603] D restkit.object_mapping:RKObjectMapper.m:382 Finished performing object mapping. Results: {
JSONDATA = (
"<EntityClass: 0x127da9e0> (entity: EntityClass; id: 0x127527d0 <x-coredata://E20EA003-1D5A-4B27-92DF-DFD8BE7074CB/EntityClass/p2> ; data: {\n timestamp = \"2012-11-20T15:40:08Z\";\n type = VCFUND;\n values = \"<relationship fault: 0x12703200 'values'>\";\n})",
"<EntityClass: 0x127da6b0> (entity: EntityClass; id: 0x12695dc0 <x-coredata://E20EA003-1D5A-4B27-92DF-DFD8BE7074CB/EntityClass/p1> ; data: {\n timestamp = \"2012-11-20T15:40:08Z\";\n type = SFAACCOUNT;\n values = \"<relationship fault: 0x11efb910 'values'>\";\n})"
);
}
2012-11-20 15:40:36.530 eMobile[44849:11603] (
"<EntityClass: 0x126b7400> (entity: EntityClass; id: 0x127527d0 <x-coredata://E20EA003-1D5A-4B27-92DF-DFD8BE7074CB/EntityClass/p2> ; data: <fault>)",
"<EntityClass: 0x127de030> (entity: EntityClass; id: 0x12695dc0 <x-coredata://E20EA003-1D5A-4B27-92DF-DFD8BE7074CB/EntityClass/p1> ; data: <fault>)"
)
JSON sample:
{
"JSONDATA": [
{
"OBJECTCLASS": "VCFUND",
"DESCRIPTION": {
"VALUES": [
{
"DATA": [
{
"NAME": "Fund 1",
"VALUE": "Buyout Fund 1"
},
{
"NAME": "Fund 2",
"VALUE": "Buyout Fund 2"
},
{
"NAME": "Fund 3",
"VALUE": "Buyout Fund 3"
}
],
"IQID": "059386B4D26249358C68E978D3C10C84"
}
]
},
"TIMESTAMP": "2012-11-17T22:03:55Z"
},
{
"OBJECTCLASS": "PROPERTIES",
"DESCRIPTION": {
"VALUES": [
{
"DATA": [
{
"NAME": "Property 1",
"VALUE": "Buyout Property 1"
},
{
"NAME": "Property 2",
"VALUE": "Buyout Property 2"
},
{
"NAME": "Property 3",
"VALUE": "Buyout Property 3"
}
],
"IQID": "456789087654678909876589098"
}
]
},
"TIMESTAMP": "2012-11-17T22:03:55Z"
}
]
}
Here is my mapping:
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"AppCD.sqlite"];
RKManagedObjectMapping* entityClassItemValueMapping = [RKManagedObjectMapping mappingForClass:[EntityClassItemValue class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
entityClassItemValueMapping.primaryKeyAttribute = @"name";
[entityClassItemValueMapping mapKeyPath:@"NAME" toAttribute:@"name"];
[entityClassItemValueMapping mapKeyPath:@"VALUE" toAttribute:@"value"];
RKManagedObjectMapping* entityClassItemMapping = [RKManagedObjectMapping mappingForClass:[EntityClassItem class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
entityClassItemMapping.primaryKeyAttribute = @"iqid";
[entityClassItemMapping mapKeyPath:@"IQID" toAttribute:@"iqid"];
RKManagedObjectMapping* entityClassMapping = [RKManagedObjectMapping mappingForClass:[EntityClass class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
entityClassMapping.primaryKeyAttribute = @"type";
[entityClassMapping mapKeyPath:@"OBJECTCLASS" toAttribute:@"type"];
[entityClassMapping mapKeyPath:@"TIMESTAMP" toAttribute:@"timestamp"];
[entityClassMapping mapKeyPath:@"VALUES" toRelationship:@"values" withMapping:entityClassItemMapping];
[entityClassItemMapping mapKeyPath:@"DATA" toRelationship:@"entityClassItemValues" withMapping:entityClassItemValueMapping];
[[RKObjectManager sharedManager].mappingProvider setMapping:entityClassMapping forKeyPath:@"JSONDATA"];
[[RKObjectManager sharedManager].mappingProvider setMapping:entityClassItemMapping forKeyPath:@"VALUES"];
[[RKObjectManager sharedManager].mappingProvider setMapping:entityClassItemValueMapping forKeyPath:@"DATA"];
[[objectManager client] setValue:[cookies objectForKey:@"Cookie"] forHTTPHeaderField:@"Cookie"];
NSDictionary *params = [[NSDictionary alloc] initWithObjectsAndKeys:query, @"Targ", @"", @"Query", @"F285E67F2C8CEC9837B68", @"$SESSION", @"3A7037FA806156C4", @"VERSION", nil];
[objectManager loadObjectsAtResourcePath:URL_DATA usingBlock:^(RKObjectLoader *loader) {
loader.method = RKRequestMethodPOST;
loader.params = params;
loader.mappingProvider = [RKObjectManager sharedManager].mappingProvider;
loader.onDidLoadObjects = loadBlock;
loader.onDidFailWithError = failBlock;
}];
My CoreData models are:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class EntityClassItem;
@interface EntityClass : NSManagedObject
@property (nonatomic, retain) NSString * timestamp;
@property (nonatomic, retain) NSString * type;
@property (nonatomic, retain) NSSet *values;
@end
@interface EntityClass (CoreDataGeneratedAccessors)
- (void)addValuesObject:(EntityClassItem *)value;
- (void)removeValuesObject:(EntityClassItem *)value;
- (void)addValues:(NSSet *)values;
- (void)removeValues:(NSSet *)values;
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class EntityClassItem;
@interface EntityClass : NSManagedObject
@property (nonatomic, retain) NSString * timestamp;
@property (nonatomic, retain) NSString * type;
@property (nonatomic, retain) NSSet *values;
@end
@interface EntityClass (CoreDataGeneratedAccessors)
- (void)addValuesObject:(EntityClassItem *)value;
- (void)removeValuesObject:(EntityClassItem *)value;
- (void)addValues:(NSSet *)values;
- (void)removeValues:(NSSet *)values;
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class EntityClassItem;
@interface EntityClassItemValue : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * value;
@property (nonatomic, retain) EntityClassItem *entityClassItem;
Upvotes: 2
Views: 2678
Reputation: 808
I figured it out after a lot of debugging and re-reading of the docs. It was a lack of understanding on my part around:
mapKeyPath:@"foo" toRelationship:@"bar" withMapping:fooBar];
As the docs clearly state, mapKeyPath must match both the property of the object you are mapping to in addition to the node in the JSON payload. My payload's case didn't match so it was failing.
Upvotes: 1