RestKit - Relashionship Mapping with CoreData - Response Error - objective-c

I have a Guest entity and inside guest is a City entity. I've setup a relashionship in CoreData and RestKit using the RKRelationshipMapping.
I've mapped a single entity correctly, but when I use RKRelationshipMapping to add a City Entity it seems to generate a this error while calling the following method with the #"cityId" property:
-[RKPropertyInspector classForPropertyNamed:ofEntity:]: unrecognized selector sent to instance
My mapping code:
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:self.serverBaseAddress]];
objectManager.managedObjectStore = [RKManagedObjectStore defaultStore];
[RKObjectManager setSharedManager:objectManager];
RKEntityMapping *cityEMapping = [RKEntityMapping mappingForEntityForName:self.cityEntityName inManagedObjectStore:[RKManagedObjectStore defaultStore]];
[cityEMapping addAttributeMappingsFromDictionary:#{
#"id" : #"cityId",
#"name" : #"name"
}];
RKEntityMapping *guestEMapping = [RKEntityMapping mappingForEntityForName:self.entityName inManagedObjectStore:[RKManagedObjectStore defaultStore]];
[guestEMapping addAttributeMappingsFromDictionary:#{
#"name" : #"name",
#"photo" : #"photo",
#"comment" : #"comment",
#"id" : #"guestId",
#"date" : #"date"
}];
[guestEMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"city"
toKeyPath:#"city"
withMapping:cityEMapping]];
guestEMapping.identificationAttributes = #[ #"guestId" ];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:guestEMapping method:RKRequestMethodAny pathPattern:self.postGetAddress keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
And where the app stops: (propertyClass receiving 0x00 in propertyClass = [[RKPropertyInspector sharedInspector]...)
- (Class)classForKeyPath:(NSString *)keyPath
{
NSArray *components = [keyPath componentsSeparatedByString:#"."];
Class propertyClass = self.objectClass;
for (NSString *property in components) {
propertyClass = [[RKPropertyInspector sharedInspector] classForPropertyNamed:property ofClass:propertyClass isPrimitive:nil];
if (! propertyClass) propertyClass = [[RKPropertyInspector sharedInspector] classForPropertyNamed:property ofEntity:self.entity];
if (! propertyClass) break;
}
return propertyClass;
}
And here is the json:
[{"id":"3","name":"Convidado3","city":{"id":"2","name":"São Paulo"},"date":"Data2","comment":"comentario3","photo":":P"},
{"id":"2","name":"Convidado2","city":{"id":"1","name":"Rio de Janeiro"},"date":"Data2","comment":"comentario2","photo":":|"},
{"id":"1","name":"Convidado1","city":{"id":"1","name":"Rio de Janeiro"},"date":"Data1","comment":"comentario1","photo":":)"},
{"id":"5","name":"Convidado5","city":{"id":"4","name":"Vitória"},"date":"Data4","comment":"comentario5","photo":":K"},
{"id":"4","name":"Convidado4","city":{"id":"3","name":"Belo Horizonte"},"date":"Data3","comment":"comentario4","photo":";)"}]
The entity Guest has a relationship called city which is connected to the City Entity through a relationship called guests in the following manner:
Guest.....City
city<--->>guests
If I simply remove the relationship it works ok, without city sub object...
Any help or suggestions appreciated...

I've solved the problem:
After going through all the steps in debug, I changed the following line
From:
RKEntityMapping *cityEMapping = [RKEntityMapping mappingForEntityForName:self.cityEntityName inManagedObjectStore:[RKManagedObjectStore defaultStore]];
To:
RKEntityMapping *cityEMapping = [RKEntityMapping mappingForEntityForName:#"City" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
And it worked!
I don't understand the problem, as I checked the value of self.cityEntityName during debug and it is #"City", so technically it should work. As for the line:
RKEntityMapping *guestEMapping = [RKEntityMapping mappingForEntityForName:self.entityName inManagedObjectStore:[RKManagedObjectStore defaultStore]];
works just fine... without any changes, I don't know what to say. Thanks for the suggestions.

Related

RestKit using cached or old response descriptor

On my main controller, the RESTKIT is working fine:
My code and response descriptor looks like this:
// register mappings with the provider using a response descriptor
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:workOrderMapping
method:RKRequestMethodGET
pathPattern:#"/api/workorder/GetWorkOrderListSimple"
keyPath:nil
statusCodes:nil];
[objectManager addResponseDescriptor:responseDescriptor];
[[RKObjectManager sharedManager] getObjectsAtPath:#"/api/workorder/GetWorkOrderListSimple"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"It Worked");
_workOrders = mappingResult.array;
[self.tableView reloadData];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"error': %#", error);
}];
So this first call works fine, however, on my 2nd controller, it seems to be somehow reusing this old response descriptor, I created a new one, but in the error message it's still referencing GetWorkOrderListSimple, when I clearly told it to use GetWorkOrderDetail.
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:workOrderBigMapping
method:RKRequestMethodGET
pathPattern:#"/api/workorder/GetWorkOrderDetail"
keyPath:nil
statusCodes:nil];
However for some reason, here is my error message, can anyone point me in the right direction for debugging? Thanks!!!
A 200 response was loaded from the URL 'http://xxxxxxx.ws/api/workorder/GetWorkOrderDetail?workOrderId=116194', which failed to match all (1) response descriptors:
http://xxxxxxx.ws pathPattern=/api/workorder/GetWorkOrderListSimple statusCodes=(null)> failed to match: response path '/api/workorder/GetWorkOrderDetail?workOrderId=116194' did not match the path pattern '/api/workorder/GetWorkOrderListSimple'.
I have the same "loading" or "setup" code in the Viewdidload of each view controller, there are two view controllers
I call configureRestKit in every Viewdidload, should I not? Should this be in the app delegate or somewhere else?
I thought since I was configuring the kit in each view controller viewdidload it would be a fresh one every time
- (void)configureRestKit
{
// initialize AFNetworking HTTPClient
NSURL *baseURL = [NSURL URLWithString:#"http://xxxxxxxx.ws"];
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
// initialize RestKit
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
// setup object mappings
RKObjectMapping *workOrderBigMapping = [RKObjectMapping mappingForClass:[WorkOrderBig class]];
[workOrderBigMapping addAttributeMappingsFromArray:#[#"WorkOrderId", #"Job", #"Address", #"Supervisor", #"PO", #"Priority", #"Status", #"ReceivedDate"]];
RKObjectMapping *workOrderDetailMapping = [RKObjectMapping mappingForClass:[WorkOrderDetail class]];
[workOrderDetailMapping addAttributeMappingsFromArray:#[#"WorkOrderDetailId", #"WorkOrderId", #"WorkOrderProblemId", #"DetailDescription", #"ProductId", #"Qty", #"PONumber", #"Code", #"ProductDescription", #"UOM", #"Price", #"OriginalPrice", #"PctMarkup", #"LineItem", #"OriginalTotal", #"TotalPrice"]];
RKObjectMapping *workOrderProblemMapping = [RKObjectMapping mappingForClass:[WorkOrderProblem class]];
[workOrderProblemMapping addAttributeMappingsFromArray:#[#"WorkOrderId", #"WorkOrderProblemId", #"Description", #"SpanishDescription", #"Action", #"LineItem"]];
//Define Relationships
[workOrderBigMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"Details"
toKeyPath:#"Details"
withMapping:workOrderBigMapping]];
[workOrderBigMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"Problems"
toKeyPath:#"Problems"
withMapping:workOrderProblemMapping]];
// register mappings with the provider using a response descriptor
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:workOrderBigMapping
method:RKRequestMethodGET
pathPattern:#"/api/workorder/GetWorkOrderDetail"
keyPath:#"/api/workorder/GetWorkOrderDetail"
statusCodes:nil];
[objectManager addResponseDescriptor:responseDescriptor];
- (void)loadWorkOrders
{
NSString *WorkOrderId = [NSString stringWithFormat:#"%i", _workOrderId];
NSMutableDictionary *params =[[NSMutableDictionary alloc] init];
[params setValue:WorkOrderId forKey:#"workOrderId"];
[[RKObjectManager sharedManager] getObjectsAtPath:#"/api/workorder/GetWorkOrderDetail"
parameters:params
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"It Worked");
_workOrders = mappingResult.array;
//paint screen
WorkOrderBig *mainWorkOrder = [_workOrders objectAtIndex:0];
self.lblWorkOrderId.text = mainWorkOrder.WorkOrderId;
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"What do you mean by 'there is no coffee?': %#", error);
}];
}
I call configureRestKit in every Viewdidload, should I not?
Based on your configuration, yes, you should
Should this be in the app delegate or somewhere else?
No, the app delegate is for application level event management, not data configuration
So, your configuration is almost fine, the problem is your usage: [RKObjectManager sharedManager]. When you call sharedManager you will always get back the first object manager that was created - not the one that was 'locally' created.
You should be using an #property on each of your view controllers to store the objectManager that they create and then using self.objectManager instead of [RKObjectManager sharedManager].

RestKit nested relationships

Working with RestKit, I'm trying to map the following JSON.
{
"userID": 1,
"collections": [
{
"collectionID": 120,
"friends": [
{
"friendID": 6,
"orders": [
{
"orderID": 1,
"name": "Small"
}
]
}
]
},
{
"collectionID": 123,
"friends": [
{
"friendID": 6,
"orders": [
{
"orderID": 2,
"name": "Medium"
}
]
}
]
}
]
}
I'm utilising RestKit and MagicalRecord - setup code, mapping and relationships below
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Model" ofType:#"momd"]];
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:#"db.sqlite"];
[managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:nil];
[managedObjectStore createManagedObjectContexts];
// Configure MagicalRecord to use RestKit's Core Data stack
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:managedObjectStore.persistentStoreCoordinator];
[NSManagedObjectContext MR_setRootSavingContext:managedObjectStore.persistentStoreManagedObjectContext];
[NSManagedObjectContext MR_setDefaultContext:managedObjectStore.mainQueueManagedObjectContext];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:#"http://127.0.0.1:3500"]];
objectManager.managedObjectStore = managedObjectStore;
RKEntityMapping *appMapping = [RKEntityMapping mappingForEntityForName:#"App" inManagedObjectStore:managedObjectStore];
appMapping.identificationAttributes = #[ #"userID" ];
RKEntityMapping *collectionMapping = [RKEntityMapping mappingForEntityForName:#"Collection" inManagedObjectStore:managedObjectStore];
collectionMapping.identificationAttributes = #[ #"collectionID" ];
[collectionMapping addAttributeMappingsFromArray:#[#"collectionID"]];
RKEntityMapping *friendMapping = [RKEntityMapping mappingForEntityForName:#"Friend" inManagedObjectStore:managedObjectStore];
friendMapping.identificationAttributes = #[ #"friendID" ];
[friendMapping addAttributeMappingsFromArray:#[#"friendID"]];
RKEntityMapping *orderMapping = [RKEntityMapping mappingForEntityForName:#"Order" inManagedObjectStore:managedObjectStore];
orderMapping.identificationAttributes = #[ #"orderID" ];
[orderMapping addAttributeMappingsFromArray:#[#"orderID", #"name"]];
RKRelationshipMapping *appCollectionRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:#"collections" toKeyPath:#"collections" withMapping:collectionMapping];
[appMapping addPropertyMapping:appCollectionRelationship];
RKRelationshipMapping *collectionFriendRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:#"friends" toKeyPath:#"friends" withMapping:friendMapping];
[collectionMapping addPropertyMapping:collectionFriendRelationship];
RKRelationshipMapping *friendsOrderRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:#"orders" toKeyPath:#"orders" withMapping:orderMapping];
[friendsOrderRelationship setAssignmentPolicy:RKUnionAssignmentPolicy];
[friendMapping addPropertyMapping:friendsOrderRelationship];
Then, querying the /test route on my API (which outputs the JSON block above) with the below console out...
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:appMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
[objectManager getObjectsAtPath:#"/test" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
App *app = [mappingResult firstObject];
for (Collection *collection in app.collections) {
NSLog(#"collectionID = %#", collection.collectionID);
for (Friend *friend in collection.friends) {
NSLog(#"friendID = %#", friend.friendID);
for (Order *order in friend.orders) {
NSLog(#"Name = %#", order.name);
}
}
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {}];
Provides the following output - notice both Name's are Medium, not one Small and the other Medium.
collectionID = 120
friendID = 6
Name = Medium
Name = Small
collectionID = 123
friendID = 6
Name = Medium
Name = Small
Why would this be happening? I'm going to guess that it's because both friend ID's are the same, even though they're under different collections...
This is because you have identificationAttributes = #[ #"friendID" ]; and the default relationship connection rule for relationships rather than replacement. So, the second mapping finds the friend created by the first mapping and replaces the order relationship contents.
You can't realistically change the unique identifier based on the JSON you show, but you might want to examine that (in relation to your object graph requirements).
Also / alternatively, see this answer for details of how to change the relationship assignment policy so that the original relationship contents aren't lost.

Restkit 0.20 keypath error 1001

I used Restkit 0.20 (first time) for posting objects to a Rails server via JSON, and I 've been stuck for the last days with an annoying mapping error. Got 2 objects Picture and Item.
Picture
{
"base64" : null,
"id" : 1,
"created_at" : "2013-08-28T15:08:49Z",
"user_nickname" : "user_name",
"tag" : "ALPHA",
"nbitems" : null,
"path" : {
"url" : "https://www.mywebsite/pictures/1/default.jpg"
},
"updated_at" : "2013-08-28T15:08:49Z",
"user_id" : 1
}
Item
{
"base64" : null,
"picture_id" : 1,
"id" : 1,
"created_at" : "2013-08-28T15:10:54Z",
"itemurl" : {
"url" : "https://www.mywebsite/pictures/1/item1.png"
},
"nickname" : "",
"user_id" : 1,
"updated_at" : "2013-08-28T15:10:54Z"
}
Here's my mapping in the AppDelegate.m
//Mapping users
RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([User class]) inManagedObjectStore:manager.managedObjectStore];
[userMapping addAttributeMappingsFromDictionary:#{
#"id" : #"user_id",
#"email" : #"email",
#"nickname" : #"nickname",
#"created_at" : #"createdAt"
}];
userMapping.identificationAttributes = #[ #"user_id" ];
//Mapping paths
RKEntityMapping *pathMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Path class]) inManagedObjectStore:manager.managedObjectStore];
[pathMapping addAttributeMappingsFromDictionary:#{
#"url" : #"url"
}];
//Mapping itemURL
RKEntityMapping *itemURLMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([ItemURL class]) inManagedObjectStore:manager.managedObjectStore];
[pathMapping addAttributeMappingsFromDictionary:#{
#"url" : #"url"
}];
//Mapping pictures
RKEntityMapping *pictureMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Picture class]) inManagedObjectStore:managedObjectStore];
[pictureMapping addAttributeMappingsFromDictionary:#{
#"id" : #"picture_id",
#"user_id" : #"user_id",
#"user_nickname" : #"user_nickname",
#"nbitems" : #"nbitems",
#"tag" : #"tag",
#"base64" : #"base64",
#"created_at" : #"createdAt"
}];
pictureMapping.identificationAttributes = #[ #"picture_id"];
[pictureMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"path" toKeyPath:#"path" withMapping:pathMapping]];
[manager addResponseDescriptorsFromArray:#[
[RKResponseDescriptor responseDescriptorWithMapping:pictureMapping
pathPattern:#"pictures"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]
]];
RKObjectMapping *pictureRequestMapping = [RKObjectMapping requestMapping];
[pictureRequestMapping addAttributeMappingsFromArray:#[#"user_id", #"user_nickname", #"tag", #"base64", #"path"]];
RKRequestDescriptor *pictureRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:pictureRequestMapping objectClass:[Picture class] rootKeyPath:#"picture" method:RKRequestMethodAny];
[manager addRequestDescriptor:pictureRequestDescriptor];
//Mapping items
RKEntityMapping *itemMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Item class]) inManagedObjectStore:managedObjectStore];
itemMapping.identificationAttributes = #[ #"item_id"];
[itemMapping addAttributeMappingsFromDictionary:#{
#"id" : #"item_id",
#"picture_id" : #"picture_id",
#"user_id" : #"user_id",
#"nickname" : #"nickname",
#"base64" : #"base64",
#"created_at" : #"createdAt"
}];
RKRelationshipMapping *itemURLRelation = [RKRelationshipMapping relationshipMappingFromKeyPath:#"itemurl" toKeyPath:#"itemurl" withMapping:itemURLMapping];
[itemMapping addPropertyMapping:itemURLRelation];
RKResponseDescriptor *itemDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:itemMapping
pathPattern:#"items"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[manager addResponseDescriptor:itemDescriptor];
RKObjectMapping *itemRequestMapping = [RKObjectMapping requestMapping];
[itemRequestMapping addAttributeMappingsFromArray:#[#"picture_id", #"user_id", #"nickname", #"base64", #"itemurl"]];
RKRequestDescriptor *itemRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:itemRequestMapping objectClass:[Item class] rootKeyPath:#"item" method:RKRequestMethodAny];
[manager addRequestDescriptor:itemRequestDescriptor];
I post a Picture instance in a ViewController and it works perfectly
- (void)uploadPicture:(UIImage *)chosenImage{
NSManagedObjectContext *moc = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
UIImage *resizedImage = [self scaleImage:chosenImage maxWidth:640 maxHeight:960];
NSString *imageEncoded = [self image2jpg2String:resizedImage];
Picture *picture = [Picture insertInManagedObjectContext:moc];
picture.user_id = userId;
picture.user_nickname = #"user_nickname";
picture.tag = #"ALPHA";
picture.base64 = imageEncoded;
[[RKObjectManager sharedManager] postObject:picture path:#"pictures" parameters:nil success:nil failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(#"Error: %#",error);}];
}
I try to do the same with an Item instance in another controller
- (void)uploadItem{
NSManagedObjectContext *mocFVC = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
NSNumber *userId = [NSNumber numberWithInt:1];
UIImage *itemImage = self.itemImage.image;
UIImage *resizedItem = [self scaleImage:itemImage maxWidth:640 maxHeight:960];
NSString *itemEncoded = [self image2png2String:resizedItem];
Item *item = [Item insertInManagedObjectContext:mocFVC];
item.user_id = userId;
item.nickname = #"user_nickname";
item.picture_id = pictureToDisplay.picture_id;
item.base64 = itemEncoded;
[[RKObjectManager sharedManager] postObject:item path:#"items" parameters:nil success:nil failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(#"Error: %#",error);}];
}
But unless I comment the item.base64, xcode always returns the following error
2013-08-28 22:51:41.116 MYPROJECT[4588:1603] E restkit.network:RKObjectRequestOperation.m:243 POST 'http://www.mywebsite/items' (422 Unprocessable Entity / 0 objects) [request=0.6791s mapping=0.0000s total=0.7111s]: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No mappable object representations were found at the key paths searched."
UserInfo=0x1e8af330 {DetailedErrors=(), NSLocalizedFailureReason=The mapping operation was unable to find any nested object representations at the key paths searched: error
The representation inputted to the mapper was found to contain nested object representations at the following key paths: itemurl
This likely indicates that you have misconfigured the key paths for your mappings., NSLocalizedDescription=No mappable object representations were found at the key paths searched., keyPath=null}
2013-08-28 22:51:41.119 MYPROJECT[4588:907] Error: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No mappable object representations were found at the key paths searched." UserInfo=0x1e8af330 {DetailedErrors=(), NSLocalizedFailureReason=The mapping operation was unable to find any nested object representations at the key paths searched: error
The representation inputted to the mapper was found to contain nested object representations at the following key paths: itemurl
This likely indicates that you have misconfigured the key paths for your mappings., NSLocalizedDescription=No mappable object representations were found at the key paths searched., keyPath=null}
I checked a lot of post on stackoverflow and read the restkit doc before posting, but don't understand why it doesn't work for my item since it's code and picture model are very closed to the one I use for my Item class. Am I missing something ? Any idea ? :)
#Wain the logs didn't show anything
Turns out the Restkit part was correct. The error was happening in my base64/upload function in the model.
def base64=(data)
# decode data and create stream on them
filename = "#{self.user_id}.png"
io = CarrierStringIO.new(filename, Base64.decode64(data))
# this will do the thing (photo is mounted carrierwave uploader)
self.path = io
end
The filename line works in a webbrowser but not using JSON. #weird
Had to change the path of the file to keep the user_id as data

How can I setup a relationship in RestKit when the only relationship info I have is the JSON structure?

I am trying to create a hierarchy of Node entities in Core Data based on a JSON I retrieve from a web service.
Here is a sample of my JSON structure
http://cl.ly/image/0r2x3E210m1U
I cannot figure out how to set up the relationships for the mapping.
Can someone please help me out? I am using the latest RestKit version.
You can't.
In JSON / RESTKIT you cant provide a recursive structure ob objects.
try just to fetch an object level at once and make a new query if you like to dive deeper.
Your 'node' class should have a 'nodes' property with a kind of lazy-loading if someone access this property.
If this fails:
RKEntityMapping *nodeMapping = [RKEntityMapping mappingForEntityForName:#"Node" inManagedObjectStore:managedObjectStore];
[locationIconMapping addAttributeMappingsFromDictionary:#{
#"name": #"name",
#"type": #"type",
}];
[nodeMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"nodes" toKeyPath:#"nodes" withMapping:nodeMapping]];
Then how about:
RKEntityMapping *nodeMapping1 = [RKEntityMapping mappingForEntityForName:#"Node" inManagedObjectStore:managedObjectStore];
[nodeMapping1 addAttributeMappingsFromDictionary:#{
#"name": #"name",
#"type": #"type",
}];
RKEntityMapping *nodeMapping2 = [RKEntityMapping mappingForEntityForName:#"Node" inManagedObjectStore:managedObjectStore];
[nodeMapping2 addAttributeMappingsFromDictionary:#{
#"name": #"name",
#"type": #"type",
}];
[nodeMapping1 addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"nodes" toKeyPath:#"nodes" withMapping:nodeMapping2]];
[nodeMapping2 addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"nodes" toKeyPath:#"nodes" withMapping:nodeMapping1]];

Why doesn't Restkit parse correctly?

Why doesn't Restkit parse correctly?
Here my delegate call:
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObject:(id)object {
NSString *s = [[NSString alloc] initWithData:objectLoader.response.body encoding:NSUTF8StringEncoding];
RKObjectMapping *rm = objectLoader.objectMapping;
NSLog(#"%#",s);
NSLog(#"%#",rm);
NSLog(#"%#", object);
}
and here the output
{"device_id": "4f75c887e45b583e4f000004"}
RKObjectMapping class => ETDevice: keyPath mappings => (
"RKObjectKeyPathMapping: device_token => secret",
"RKObjectKeyPathMapping: deivce_id => identifier"
)
(null)
any reason why it shouldn't work?
I don't think is a problem of the way I make the http request but anyway here is the code:
RKObjectManager *objectManager = [RKObjectManager sharedManager];
[objectManager sendObject:device delegate:self block:^(RKObjectLoader *loader) {
loader.serializationMapping = [[ETDevice objectMapper] inverseMapping];
loader.method = RKRequestMethodPOST;
loader.resourcePath = #"/devices/init";
loader.serializationMIMEType = #"application/json";
loader.objectMapping = [ETDevice objectMapper];
}];
btw I've also tried with:
{"device_id": "4f75c887e45b583e4f000004"}
{devices: {"device_id": "4f75c887e45b583e4f000004"}}
{devices: [{"device_id": "4f75c887e45b583e4f000004"}]}
please help, I'm timeboxing using restkit ;P
Ok I got completely crazy for this. I've debugged almost all the stack in Restkit.
The bug was just:
"deivce_id" instead of "device_id".
I've learned a lot about restKit at least