restkit mapping nested array is empty (nested restkit request with json response) - ios

Am i doing something weired here ?
my categories get downloaded and mapped,
product also get downloaded and mapped as logging is saying,
but my products are empty under each category,
thnx!
{
"productsCategories" : [
{
"product" : [
{
"price" : 3.99,
"title" : "Product A"
},
{
"price" : 3.99,
"title" : "ProductB "
}
],
"categoryTitle" : “a category“
}
]
}
RKObjectMapping *productCategoryMapping = [RKObjectMapping mappingForClass:[ProductCategory class]];
[productCategoryMapping addAttributeMappingsFromDictionary:#{
#"categoryTitle": #"tit"
}];
RKObjectMapping* productMapping = [RKObjectMapping mappingForClass:[Product class] ];
[productMapping addAttributeMappingsFromDictionary:#{
#"title": #"tit",
#"price": #"prc"
}];
[productCategoryMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"product"
toKeyPath:#"product"
withMapping:productMapping]];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:productCategoryMapping method:RKRequestMethodPOST pathPattern:#"productByCategory" keyPath:#"productsCategories" statusCodes:[NSIndexSet indexSetWithIndex:200]];
NSURL *url=[NSURL URLWithString:#"http://www.example.com/REST/v2/"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:url];
[manager addResponseDescriptor:responseDescriptor];
NSMutableDictionary *mutableParameters = [NSMutableDictionary dictionary];
[mutableParameters setValue:#"1" forKey:#"id"];
[manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:productCategoryMapping method:RKRequestMethodPOST pathPattern:#"productByCategory" keyPath:#"productsCategories" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
[manager postObject:request path:#"productByCategory" parameters:mutableParameters success:^(RKObjectRequestOperation *operation, RKMappingResult *result){
self.productCategoryArr=result.array;
[self.tblDetails reloadData];
}failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(#"Operation failed with error: %#", error);
self.productCategoryArr=nil;
}];
the logging says objects are being mapped for each products but I only get
ProductCategory: 0x7bf53510
ProductCategory: 0x7be57f00
arrays and 0 objects in each

Assuming your ProductCategory class has
NSArray *Product
NSString * tit
Create a top level RKObjectMapping like,
RKObjectMapping * ProductCategoryResponseMapping = [RKObjectMapping mappingForClass: [ProductCategoryResponse class]];
[ProductCategoryResponseMapping addAttributeMappingsFromDictionary:#{
#"productsCategories": #"productsCategories"
}];
And create new class ProductCategoryResponse which should have
NSArray * productsCategories
Use ProductCategoryResponseMapping for Response descriptor.
Now your response will have array of productsCategories, each having array of Products and String tit.

Related

RESTKIT response only first KVC in mapping result dictionary or array

I'm receiving a dictionary from my restkit request as respond but only one of values are included. I am missing bunch of KV from my JSON.
JSON response from API:
{"categories" : [
{
"status" : 1,
"rest_id" : 1,
"id" : 1,
"title" : "01. BasicC",
"description" : "basic description"
},
{
"status" : 1,
"rest_id" : 1,
"id" : 26,
"title" : "01. Deli",
"description" : "deli description"
}
]}
IOS Function to request:
- (void)loadProduct{
_categoriesDic=[[NSDictionary alloc]init];
RKObjectMapping* productMapping = [RKObjectMapping mappingForClass:[ProductCategory class]];
[productMapping addAttributeMappingsFromDictionary:#{
#"id": #"id",
#"rest_id": #"rest_id",
#"title": #"title",
#"description": #"description",
#"status":#"status"
}];
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:productMapping method:RKRequestMethodPOST pathPattern:nil keyPath:#"categories" statusCodes:[NSIndexSet indexSetWithIndex:200]];
RKObjectManager *objectManager = [[RKObjectManager alloc] init];
[objectManager addResponseDescriptor:responseDescriptor];
NSString *jsonRequest = [NSString stringWithFormat:#"id=1"];
NSURL *url=[NSURL URLWithString:#"http://example.com/REST/v2/productCategories"];
NSData *json_data = [NSData dataWithBytes:[jsonRequest UTF8String] length:[jsonRequest length]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody: json_data];
RKObjectRequestOperation *objectRequestOperation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:#[ responseDescriptor ]];
[objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
RKLogInfo(#"Load collection of Categories: %#", mappingResult.dictionary);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(#"Operation failed with error: %#", error);
}];
[objectRequestOperation start];
}
response:
Load collection of Categories: {
categories = (
"basic description",
"deli description"
);
}
While your code does some slightly odd things (like create an empty immutable dictionary, and POST to an endpoint which should be using a GET) it does appear to work. It looks like you just aren't fully understanding the response, and that's because you are inadvertently overriding a built in method.
The log you show contains:
{
categories = (
"basic description",
"deli description"
);
}
is the description of a dictionary which contains 1 key (categories), which is an array of 2 objects. Now, those 2 objects have their description method called as well in order to generate the log contents. Unfortunately, you have a property called description so that is accessed instead of the superclass implementation., and hence you just get the descriptions.
Now, that doesn't mean the mapping hasn't worked, just that the log is misleading.
You should change the description on your destination object to another name, like overview and then your log will be meaningful (and you won't see similar issues in future).

RKMappingresult returning different result in 64-bit iphones with restkit

I have a strange problem with Restkit. I'm doing the following:
-(void)doLogin:(NSString *)email andPassword:(NSString *)password OnCompletion:(myCompletion) compblock{
Mapper *mapper = [Mapper new];
RKManagedObjectStore *store = [[OffitelDataModel sharedDataModel] objectStore];
NSLog(#"store is %#",store);
NSManagedObjectContext *context = store.mainQueueManagedObjectContext;
RKObjectManager *objectManager = [mapper mapLogin];
NSString *deviceToken = [[NSUserDefaults standardUserDefaults]objectForKey:#"deviceToken"];
NSString *urlString = [NSString stringWithFormat:#"company-user/login/%#?email=%#&pwd=%#&ios_id=%#",apikey,email,password,deviceToken];
NSURLRequest *request = [objectManager requestWithObject:nil method:RKRequestMethodGET path:urlString parameters:nil];
RKManagedObjectRequestOperation *operation = [objectManager managedObjectRequestOperationWithRequest:request managedObjectContext:context success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSError *error = nil;
BOOL success = [context save:&error];
if (!success) RKLogWarning(#"Failed saving managed object context: %#", error);
Data *data2 = [mappingResult.array objectAtIndex:0];
NSLog(#"MAPPING RESULT 0 = %#",[mappingResult.array objectAtIndex:0]);
NSLog(#"data status is %#",data2.webstatus);
int value = [data2.webstatus intValue];
if (value == 200){
Person *personObject = [mappingResult.array objectAtIndex:2];
NSString *name = [NSString stringWithFormat:#"%# %#",personObject.cu_first_name,personObject.cu_last_name];
NSDictionary *dictUser = [[NSDictionary alloc]initWithObjectsAndKeys:personObject.cu_id,#"personId",personObject.company.c_id,#"companyId",name,#"personName",personObject.cu_status_id,#"statusId", nil];
[[NSUserDefaults standardUserDefaults]setObject:dictUser forKey:#"user"];
[[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithBool:YES] forKey:#"loggedIn"];
[[NSUserDefaults standardUserDefaults] synchronize];
compblock(YES);
}else{
//show validation
NSLog(#"ERROR");
}
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"ERROR");
}];
[objectManager enqueueObjectRequestOperation:operation];
}
En this is my mapping
-(RKObjectManager *)mapLogin{
RKObjectMapping* dataMapping = [RKObjectMapping mappingForClass:[Data class]];
[dataMapping addAttributeMappingsFromDictionary:#{
#"status": #"webstatus",
#"message": #"message",
#"text": #"text"
}];
RKEntityMapping* personMapping = [RKEntityMapping mappingForEntityForName:#"Person" inManagedObjectStore:managedObjectStore];
personMapping.identificationAttributes = #[#"cu_id"] ;
[personMapping addAttributeMappingsFromDictionary:#{
#"cu_id": #"cu_id",
#"cu_status_id": #"cu_status_id",
#"cu_company_id": #"cu_company_id",
#"cu_function_id": #"cu_function_id",
#"cu_department_id": #"cu_department_id",
#"cu_email": #"cu_email",
#"cu_first_name": #"cu_first_name",
#"cu_last_name": #"cu_last_name",
#"cu_phone_intern": #"cu_phone_intern",
#"cu_mobile_phone": #"cu_mobile_phone",
#"cu_street": #"cu_street",
#"cu_number": #"cu_number",
#"cu_bus": #"cu_bus",
#"cu_postalcode": #"cu_postalcode",
#"cu_location": #"cu_location",
#"cu_country": #"cu_country",
#"cu_birthdate": #"cu_birthdate",
#"cu_picture": #"cu_picture",
#"cu_comment": #"cu_comment",
#"cu_ison_reminder_email": #"cu_ison_reminder_email",
#"cu_ison_reminder_app": #"cu_ison_reminder_app",
#"cu_ison_reminder_web": #"cu_ison_reminder_web",
#"cu_first_use": #"cu_first_use"
}];
RKEntityMapping* functionMapping = [RKEntityMapping mappingForEntityForName:#"Function" inManagedObjectStore:managedObjectStore];
functionMapping.identificationAttributes = #[#"cf_id"] ;
[functionMapping addAttributeMappingsFromDictionary:#{
#"cf_id": #"cf_id",
#"cf_name":#"cf_name"
}];
RKEntityMapping* departmentMapping = [RKEntityMapping mappingForEntityForName:#"Department" inManagedObjectStore:managedObjectStore];
departmentMapping.identificationAttributes = #[#"cd_id"] ;
[departmentMapping addAttributeMappingsFromDictionary:#{
#"cd_id": #"cd_id",
#"cd_name":#"cd_name"
}];
RKEntityMapping* companyMapping = [RKEntityMapping mappingForEntityForName:#"Company" inManagedObjectStore:managedObjectStore];
companyMapping.identificationAttributes = #[#"c_id"] ;
[companyMapping addAttributeMappingsFromDictionary:#{
#"c_id": #"c_id",
#"c_name":#"c_name",
#"c_phone":#"c_phone",
#"c_fax":#"c_fax",
#"c_website":#"c_website"
}];
RKEntityMapping* statusMapping = [RKEntityMapping mappingForEntityForName:#"Status" inManagedObjectStore:managedObjectStore];
statusMapping.identificationAttributes = #[#"cs_id"] ;
[statusMapping addAttributeMappingsFromDictionary:#{
#"cs_id": #"cs_id",
#"cs_company_id":#"cs_company_id",
#"cs_name":#"cs_name",
#"cs_default":#"cs_default",
#"cs_image":#"cs_image"
}];
RKRelationshipMapping* relationFunctionMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:#"function"toKeyPath:#"function"withMapping:functionMapping];
RKRelationshipMapping* relationDepartmentMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:#"department"toKeyPath:#"department"withMapping:departmentMapping];
RKRelationshipMapping* relationCompanyMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:#"company"toKeyPath:#"company"withMapping:companyMapping];
RKRelationshipMapping* relationStatusMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:#"statuses"toKeyPath:#"status"withMapping:statusMapping];
[personMapping addPropertyMapping:relationFunctionMapping];
[personMapping addPropertyMapping:relationDepartmentMapping];
[personMapping addPropertyMapping:relationCompanyMapping];
[companyMapping addPropertyMapping:relationStatusMapping];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:dataMapping
pathPattern:nil
keyPath:#"data" statusCodes:[NSIndexSet indexSetWithIndex:200]];
RKResponseDescriptor *responseDescriptor2 = [RKResponseDescriptor responseDescriptorWithMapping:personMapping
pathPattern:nil
keyPath:#"data.user"
statusCodes:[NSIndexSet indexSetWithIndex:200]];
RKResponseDescriptor *responseDescriptor3 = [RKResponseDescriptor responseDescriptorWithMapping:companyMapping
pathPattern:nil
keyPath:#"data.user.company"
statusCodes:[NSIndexSet indexSetWithIndex:200]];
NSArray *arrResponsDescriptor = [[NSArray alloc]initWithObjects:responseDescriptor,responseDescriptor2,responseDescriptor3, nil];
[objectManager addResponseDescriptorsFromArray:arrResponsDescriptor];
return objectManager;
}
The strange this is that on most phones it all works correct but only on 64-bit devices are going wrong.
When I look at this NSLog
NSLog(#"MAPPING RESULT 0 = %#",[mappingResult.array objectAtIndex:0]);
I see that in the not-64-bit devices it returns the Data class object. And thats oké. But in the 64-bit devices it returns the Company-object and that's not ok !
Can somebody help me with this ?
Kind regards
You have multiple response descriptors each with a nil path pattern, so they will always be applied to any response. RestKit does not guarantee the order in which they will be called. It also doesn't guarantee the order of the contents of mappingResult.array.
You should be using your key paths on the response descriptors to access the results of each descriptor. The mappingResult also offers you a dictionary (instead of array) where you can use the response descriptor key path to access the associated results. Use that to separate the Data results from the Company results.

Retrived null in POST JSON RestKit

I have used RestKit and made a mapping with a managed object. I then use the postObject method but I have a problem when retrieved the body as it maps to null.
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
// Serialize to JSON
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[RKObjectManager setSharedManager:objectManager];
RKEntityMapping *searchInfoMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Search class]) inManagedObjectStore: objectManager.managedObjectStore];
searchInfoMapping.identificationAttributes = #[ #"faresQueryType" ];
[searchInfoMapping addAttributeMappingsFromDictionary:#{
#"id" : #"ID",
#"type" : #"Type",
#"count" : #"Count",
#"route” : #"route”,
}];
RKObjectMapping *searchInfoRequestMapping =[RKObjectMapping requestMapping];
[searchInfoRequestMapping addAttributeMappingsFromDictionary:#{
#"id" : #"ID",
#"type" : #"Type",
#"count" : #"Count",
#"route” : #"route”,
}];
//Data mapping is a method that returns an RKObjectMapping for my model
RKResponseDescriptor * searchDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:searchInfoMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptorsFromArray:#[searchDescriptor,]];
//Inverse mapping, to perform a POST
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:searchInfoRequestMapping objectClass:[Search class] rootKeyPath:nil];
[objectManager addRequestDescriptor:requestDescriptor];
[appDelegate.objectManager postObject:nil path:#"routes" parameters:postParameters success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success case %#",mappingResult);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure in Flight Mapping %#",error);
[alert show];
}];
Edit
//JSON Result
{
"currency": {
"code": "USD",
"name": "U.S. Dollar",
"symbol": "US$",
"exchange_rate": 1
},
"routes": [
{
"id": "MS648-2022:MS985-2110",
"fares": [
{
"price": 745.32,
"description": "Economy",
"deeplink": "http://www.wego.com/flights/providers/2/deeplinks?search_id=CQtxCXQCRfmwhp72PAjopQ&trip_id=RUH:NYC:2013-12-20&fare_id=sky-tours.com:0&route=RUH-JFK",
"provider_code": "sky-tours.com",
"deeplink_params": {
"trip_id": "RUH:NYC:2013-12-20",
"route": "RUH-JFK",
"search_id": "CQtxCXQCRfmwhp72PAjopQ",
"fare_id": "sky-tours.com:0"
}
}
]
}
]
}
You need to supply the Search object instead of nil when you call postObject (currently you have postObject:nil). This tells RestKit which request mapping to use to send the request. As a result of not setting it the server will likely not have all of the required information (it's impossible to tell with the information provided).

RestKitObjectMapping Array off null objects

RestKitObjectMapping Array off null objects
I want to map CapitalImage object in Capital images object property.
//------------------------ The mapping I try to
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class]
forMIMEType:#"text/html"];
RKObjectMapping *CapitalImageMap = [RKObjectMapping mappingForClass:[CapitalImage class]];
[CapitalImageMap addAttributeMappingsFromDictionary:#{
#"src": #"src"
}];
RKObjectMapping *CapitalMap = [RKObjectMapping mappingForClass:[Capital class]];
[CapitalMap addAttributeMappingsFromDictionary:#{
#"name": #"name",
#"text": #"text"
}];
[CapitalMap addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"images" toKeyPath:#"images" withMapping:CapitalImageMap]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:CapitalMap
method:RKRequestMethodAny
pathPattern:nil
keyPath:nil
statusCodes:statusCodes];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.a10073.de4.dp10.ru/icapitals/capital.php"]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:#[responseDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
Capital *article = [result firstObject];
NSLog(#"Mapped the article: %# , %#", article.name,article.images.description);
} failure:^(RKObjectRequestOperation *operation, NSError *error) { NSLog(#"Failed with error: %#", [error localizedDescription]); }];
[operation start];
I get this result
2013-09-27 23:20:49.028 iCapitals v2[5099:c07] Mapped the article: London , (
(null),
(null),
(null),
)
LOGS - http://www.a10073.de4.dp10.ru/icapitals/consoleresult.txt
Please check the code and tell what i do wrong, Thanks!!!
Your mappings look correct. The log shows the mapping proceeding correctly. The issue appears to be with the CapitalImage class. Why is it giving a nil description? It could be that that is the only problem. So your log of the array is a list of nil, but the objects do exist.
Try logging the src of each objects. Are you seeing other issues? Did you implement the description method?

iOS RestKit issue: Invalid parameter not satisfying: responseDescriptors

I am trying to use RestKit to retrieve a listing of events and I keep getting this:
2013-05-20 10:52:56.708 EventApp[3380:c07] I restkit:RKLog.m:34 RestKit logging initialized...
2013-05-20 10:52:56.773 EventApp[3380:c07] *** Assertion failure in -[RKObjectRequestOperation initWithRequest:responseDescriptors:], /Users/mitchell/Desktop/eventapp/take2/EventApp/Pods/RestKit/Code/Network/RKObjectRequestOperation.m:158
2013-05-20 10:52:56.774 EventApp[3380:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: responseDescriptors'
I have been scratching my head for days on this one. As I have a fair amount of gaps in my iOS dev skills(about one project every year) it would greatly help if someone can just lead me in the right direction here using some laymen terms.
Please consider that I am looking to use enqueueObjectRequestOperation specifically for batching multiple requests. I have just pieced together bits of my code for translation here.
Here is what my datamodel looks like:
Here is the what the JSON file looks like:
[{
"id":1,
"farm_id":1,
"all_day": "NO",
"from": "2013-05-08T18:45:38Z",
"to": "2013-05-08T18:45:38Z",
"name": "event 1",
"desc": "some description",
"photo": "some.png",
"price": "price"
}]
Here is my code:
NSManagedObjectContext *context;
RKObjectManager *objectManager;
if (self.eventContext == nil) {
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"FarmApp" ofType:#"momd"]];
RKEntityMapping *entityMapping;
// NOTE: Due to an iOS 5 bug, the managed object model returned is immutable.
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
// Initialize the Core Data stack
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore __unused *eventPersistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(eventPersistentStore, #"Failed to add persistent store: %#", error);
[managedObjectStore createManagedObjectContexts];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];
// Configure the object manager
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:#"http://sandbox.bm.com"]];
[RKObjectManager setSharedManager:objectManager];
[objectManager setRequestSerializationMIMEType:#"application/json"];
[objectManager setAcceptHeaderWithMIMEType:#"text/plain"];
objectManager.managedObjectStore = managedObjectStore;
entityMapping = [RKEntityMapping mappingForEntityForName:#"Event" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:#{
#"id": #"eventID",
#"farm_id": #"farm",
#"all_day": #"allDay",
#"from": #"from",
#"to": #"to",
#"name": #"name",
#"desc": #"desc",
#"photo": #"photo",
#"price": #"price"
}];
RKResponseDescriptor *successDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:successDescriptor];
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:#"errors" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[objectManager addResponseDescriptor:errorDescriptor];
self.eventContext = managedObjectStore.mainQueueManagedObjectContext;
}
context = self.eventContext;
NSString* url = [NSString stringWithFormat:#"http://sandbox.bm.com/farmapp/%#.json", #"events"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:[objectManager responseDescriptors]];
[operation setCompletionBlockWithSuccess:nil failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Loaded this error: %#", [error localizedDescription]);
}];
NSArray *operations = [NSArray arrayWithObjects:operation, nil];
for (int i = 0; i < [operations count]; i++ ) {
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:[operations objectAtIndex:i]];
}
Can someone out there help me?
Here is the final solution
if (self.eventContext == nil) {
NSManagedObjectContext *context;
RKObjectManager *objectManager;
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"FarmApp" ofType:#"momd"]];
RKEntityMapping *entityMapping;
// NOTE: Due to an iOS 5 bug, the managed object model returned is immutable.
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
// Initialize the Core Data stack
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore __unused *eventPersistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(eventPersistentStore, #"Failed to add persistent store: %#", error);
[managedObjectStore createManagedObjectContexts];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:managedObjectStore];
// Configure the object manager
objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:#"http://sandbox.bm.com"]];
[RKObjectManager setSharedManager:objectManager];
[objectManager setRequestSerializationMIMEType:#"application/json"];
[objectManager setAcceptHeaderWithMIMEType:#"text/plain"];
objectManager.managedObjectStore = managedObjectStore;
entityMapping = [RKEntityMapping mappingForEntityForName:#"Event" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:#{
#"id": #"eventID",
//#"farm_id": #"farm",-->cannot create relationship this way
#"farm_id" : #"farmID",//farmID attribute needs to be added to Event's model
#"all_day": #"allDay",
#"from": #"from",
#"to": #"to",
#"name": #"name",
#"desc": #"desc",
#"photo": #"photo",
#"price": #"price"
}];
[entityMapping addConnectionForRelationship:#"farm" connectedBy:#"farmID"];
RKResponseDescriptor *successDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:#"events" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:successDescriptor];
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:entityMapping pathPattern:nil keyPath:#"errors" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
[objectManager addResponseDescriptor:errorDescriptor];
self.eventContext = managedObjectStore.mainQueueManagedObjectContext;
context = self.eventContext;
NSString* url = [NSString stringWithFormat:#"http://sandbox.bm.com/farmapp/%#.json", #"events"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
RKManagedObjectRequestOperation *operation = [objectManager managedObjectRequestOperationWithRequest:request managedObjectContext:managedObjectStore.mainQueueManagedObjectContext success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure");
}];
NSArray *operations = [NSArray arrayWithObjects:operation, nil];
for (int i = 0; i < [operations count]; i++ ) {
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:[operations objectAtIndex:i]];
}
}
As #JoelH. suggests in one of his comments, you need to use RKManagedObjectRequestOperation instead of RKObjectRequestOperation.
For example :
RKManagedObjectRequestOperation *operation = [objectmanager managedObjectRequestOperationWithRequest:request managedObjectContext:managedObjectStore.mainQueueManagedObjectContext success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure");
}];
Besides, I think the way you are mapping
#"farm_id": #"farm"
is not correct.
If you want to build the relationship between Event and Farm, you need to use one of these methods :
relationshipMappingFromKeyPath:toKeyPath:withMapping:
or addConnectionForRelationship:connectedBy:
If the Farm object already exists and you only want to map the new Event, I would go for addConnectionForRelationship:connectedBy:
For example :
RKEntityMapping* eventMapping = [RKEntityMapping mappingForEntityForName:#"Event" inManagedObjectStore:managedObjectStore];
[entityMapping addAttributeMappingsFromDictionary:#{
#"id": #"eventID",
//#"farm_id": #"farm",-->cannot create relationship this way
#"farm_id" : #"farmID",//farmID attribute needs to be added to Event's model
#"all_day": #"allDay",
#"from": #"from",
#"to": #"to",
#"name": #"name",
#"desc": #"desc",
#"photo": #"photo",
#"price": #"price"
}];
[eventMapping addConnectionForRelationship:#"farm" connectedBy:#"farmID"];
It would also require to add a farmID attribute in your Event model, as RestKit does not allow relationship connection without intermediary attributes yet.
The RestKit docs (Mapping Without KVC) seem to imply that if you don't have a KVC label on the top level(e.g. events:[]), a pathPattern: is required for the parser to know which mapping to use. Since both your keyPath: and pathPattern: are nil for your successDescriptor, I have two suggestions:
If changing the JSON structure is possible, change the top level to { events:[...] } and change keyPath:nil to keyPath:#"events" to reflect this change.
If it's not possible, change pathPattern:nil to pathPattern:#"/farmapp" Notice, I set pathPattern: to match your resource URL. This second suggestion might not work if you have other types of resources branching from that URL as well.
Also, I noticed that your errorDescriptor uses the same mapping(entityMapping) as your successDescriptor. I don't know if that's what you intended, but if your error response is supposed to be some different error object, I suggest changing that.
Hope this helps!

Resources