Request Mapping in RestKit - ios

https://github.com/RestKit/RestKit Only introduced mapping of JSON :
{
a : "a",
b : "b"
}
Mapping with Objective-C code:
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:#{#"entityId" : #"id"}];
But it do not show me how to mapping JSON Like:
{
entity: {
id: "xxxxxxxxx",
model : {
a : "a",
b : "b"
}
}
}
I did some attempt,
I create two model class like:
#interface Entity : NSObject
#property (strong, nonatomic) NSString *entityId;
#property (strong, nonatomic) NSObject *model;
#end
and
#interface Model : NSObject
#property (strong, nonatomic) NSString *a;
#property (strong, nonatomic) NSString *b;
#end
I make some RelationShipMapping Like ReponseMapping
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:#{#"entityId" : #"id"}];
RKObjectMapping *modelMapping = [RKObjectMapping requestMapping];
[modelMapping addAttributeMappingsFromDictionary:#{#"a" : #"b"}];
RKRelationshipMapping *modelToEntityMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:#"model" toKeyPath:#"model" withMapping:modelMapping];
[requestMapping addPropertyMapping:modelToEntityMapping];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Entity class] rootKeyPath:nil method:RKRequestMethodAny];
[objectManager addRequestDescriptor:requestDescriptor];
the following code I create the object
Entity *entity = [Entity new];
entity.entityId = #"/example/entityId";
Model *exampleModel = [ExampleModel new];
exampleModel.a = #"a";
exampleModel.b = #"b";
entity.model = exampleModel;
But I log the post JSON on my server:
{ id: '/example/entityId', 'model[a]': 'a', 'model[b]': 'b' }
So how to make a relationship when use requestMapping?

Related

How to parse this repsonse in restkit?

I am confused completely to parse this kind of response in restkit. I am using this link but i am not able to understand how to parse this response.Any help would be appreciated.
“groups”: {
"group1": [
{
"email": "blake#restkit.org",
"favorite_animal": "Monkey"
},
{
"email": "slake#restkit.org",
"favorite_animal": "Donkey"
}
],
"group2": [
{
"email": "sarah#restkit.org",
"favorite_animal": "Cat"
},
{
"email": "varah#restkit.org",
"favorite_animal": "Cow"
}
]
}
I am Using Below mapping.
#interface GroupResponse : NSObject
#property (nonatomic, strong) NSArray *Groups;
+ (RKObjectMapping *)mapping;
#end
#implementation GroupResponse
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class]];
[objectMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#“groups” toKeyPath:#“Groups” withMapping:[GroupData mapping]]];
return objectMapping;
}
#end
#interface GroupData : NSObject
#property (nonatomic, strong) NSString *groupName;
#property (nonatomic, strong) NSString *arrPersons;
+ (RKObjectMapping *)mapping;
#end
#implementation GroupData
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class]];
objectMapping.forceCollectionMapping = YES;
[objectMapping addAttributeMappingFromKeyOfRepresentationToAttribute:#"groupName"];
[objectMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#“(groupName)” toKeyPath:#"arrPersons" withMapping:[Person mapping]]];
return objectMapping;
}
#end
#interface Person : NSObject
#property (nonatomic, strong) NSString *email;
#property (nonatomic, strong) NSString *favAnimal;
+ (RKObjectMapping *) mapping;
#end
#implementation Person
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class]];
[objectMapping addAttributeMappingsFromDictionary:#{#"email" : #"email",
#"favorite_animal" : #"favAnimal"}];
return objectMapping;
}
#end
Everytime arrPersons is nil. How to do proper mapping in this case.
This attribute:
#property (nonatomic, strong) NSString *arrPersons;
should actually be a mutable array, not a string type:
#property (nonatomic, strong) NSMutableArray *arrPersons;
because the nested JSON array can't be converted into a string and your mapping indicates that it should be processed into an array of Person objects.

RestKit RKRelationshipMapping doesn't working

Here is my JSON
{
"pages": 8,
"salads": [
{
"id": "392",
"img": "http://salatiki.com.ua/images/mini/20120114_285.jpg",
"ingredCount": 5,
"ingredients": "картофель, свекла, салат, яйцо, сливки",
"name": "Шведский картофельный",
"rating": 4
},
.......
]
}
I got "pages", but my "salads" is nil (see log).
My NSManagedObjects
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#class SSaladsBody;
#interface SSaladPage : NSManagedObject
#property (nonatomic, retain) NSNumber * sPages;
#property (nonatomic, retain) SSaladsBody *salads;
#end
for key "salads"
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface SSaladsBody : NSManagedObject
#property (nonatomic, retain) NSNumber * sId;
#property (nonatomic, retain) NSString * sImage;
#property (nonatomic, retain) NSString * sName;
#property (nonatomic, retain) NSNumber * sRating;
#property (nonatomic, retain) NSString * sIngredients;
#property (nonatomic, retain) NSNumber * sIngredientsCount;
#end
in my add delegate
RKEntityMapping *saladPageMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([SSaladPage class]) inManagedObjectStore:managedObjectStore];
[saladPageMapping addAttributeMappingsFromDictionary:#{ #"pages" : #"sPages", }];
saladPageMapping.identificationAttributes = #[#"sPages"];
RKEntityMapping *saladsBodyMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([SSaladsBody class]) inManagedObjectStore:managedObjectStore];
[saladsBodyMapping addAttributeMappingsFromDictionary:#{ #"id" : #"sId",
#"img" : #"sImage",
#"name" : #"sName",
#"rating" : #"sRating",
#"ingredients" : #"sIngredients",
#"ingredCount" : #"sIngredientsCount" }];
saladsBodyMapping.identificationAttributes = #[#"sId"];
[saladPageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"salads"
toKeyPath:#"salads"
withMapping:saladsBodyMapping]];
RKResponseDescriptor *saladPageDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:saladPageMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[manager addResponseDescriptorsFromArray: #[saladPageDescriptor]];
[[RKObjectManager sharedManager] getObjectsAtPath:#"api/get.php?getByCat=1&page=1" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Mapping salads OK! %#", mappingResult.array);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#",error);
}];
and log
2014-11-04 23:57:49.641 Salatiki[10213:f03] I restkit.network:RKObjectRequestOperation.m:250 GET 'http://salatiki.com.ua/api/get.php?getByCat=1&page=1' (200 OK / 1 objects) [request=0.0989s mapping=0.0117s total=0.1613s]
2014-11-04 23:57:49.641 Salatiki[10213:607] Mapping salads OK! (
"<SSaladPage: 0x7b03b970> (entity: SSaladPage; id: 0x7b267d90 <x-coredata://8CC2FD2A-9D05-4863-99AA-30B318EEC57C/SSaladPage/p42> ; data: {\n sPages = 8;\n salads = nil;\n})"
)
what i'm doing wrong? I try to add one more responseDeskriptor, for "salads" it work's but he put array in to main {}; not to "salads" = []; Thank you.
The property
#property (nonatomic, retain) SSaladsBody *salads;
should actually be a relationship, so it should be NSSet, not SSaladsBody.
Other than that, things look ok. If you still have issues you should turn on trace logging and see what processing is done around the relationship contents.

POST JSON to Server from CoreData Information

I'm somewhat new to iOS development so I'm trying to figure out posting a JSON string to a webserver and getting back some information. In the first page I ask for the user to give me their first name and last name. I then generate an ID for them and pass them to the second page. When the second page loads I want to send a JSON string to the server to tell it the users first name, last name among other things. The request would be like follows:
{
"user":{
"first_name":"Joe",
"last_name":"User",
"device_descriptor":"iPhone",
"idfa":"12345678",
"btmacid":"01:23:45:67:89:ab"
}
}
The create response successful would come back as follows:
{
"id": "8",
"first_name: "Joe",
"last_name": "User",
"device_descriptor": "iPhone",
"created_at": "2014-10-07T05:25:36.119Z",
"updated_at": "2014-10-07T05:25:36.119Z",
"idfa": "12345678",
"btmacid": "01:23:45:67:89:ab"
}
The code I have thus far is as follows:
#import "WelcomeViewController.h"
#import "CoreDataStack.h"
#import "UserInformation.h"
#import <CoreData/CoreData.h>
#import <RestKit/RestKit.h>
#interface WelcomeViewController ()
#property (nonatomic,strong) NSFetchedResultsController *fetchResultsController;
#property (strong, nonatomic) IBOutlet UILabel *welcomeTextLabel;
#end
#implementation WelcomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.fetchResultsController performFetch:nil];
UserInformation *entry = [[self.fetchResultsController fetchedObjects] objectAtIndex:0];
_welcomeTextLabel.text = [NSString stringWithFormat: #"Welcome " #"%#!", entry.firstName];
[self postUserInformation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSFetchRequest *)entryFetchRequest{
NSFetchRequest *fetchReqeust = [NSFetchRequest fetchRequestWithEntityName:#"UserInformation"];
fetchReqeust.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"createdAt" ascending:NO]];
return fetchReqeust;
}
- (NSFetchedResultsController *)fetchResultsController {
if (_fetchResultsController != nil) {
return _fetchResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryFetchRequest];
_fetchResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
return _fetchResultsController;
}
- (void) postUserInformation {
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
[self.fetchResultsController performFetch:nil];
UserInformation *entry = [[self.fetchResultsController fetchedObjects] objectAtIndex:0];
RKObjectManager *manager = [RKObjectManager sharedManager];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[UserInformation class]];
NSDictionary *userInformation = #{
#"id" : #"userID",
#"first_name" : #"firstName",
#"last_name" : #"lastName",
#"device_descriptor" : #"deviceHardwareID",
#"created_at" : #"created_at",
#"updated_at" : #"updated_at",
#"idfa" : #"deviceAdvertisementID",
#"btmacid" : #"btmac_Id"
};
[responseMapping addAttributeMappingsFromDictionary:userInformation];
manager.requestSerializationMIMEType = RKMIMETypeJSON;
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:#"/users" keyPath:nil statusCodes:statusCodes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:userInformation];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[userInformation class] rootKeyPath:nil method:RKRequestMethodAny];
[manager addResponseDescriptor:responseDescriptor];
[manager addRequestDescriptor:requestDescriptor];
// NSDictionary *params = #{
// #"id" : entry.userID,
// #"first_name" : entry.firstName,
// #"last_name" : entry.lastName,
// #"device_descriptor" : entry.deviceHardwareID,
// #"created_at" : entry.createdAt,
// #"updated_at" : entry.updatedAt,
// #"idfa" : entry.deviceAdvertisementID,
// #"btmacid" : entry.btmacID
// };
[manager postObject:userInformation path:#"http://serverendpoint.com/users" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
}];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Any help you all could provide would be greatly appreciated.
You shouldn't create the request mapping with
[requestMapping addAttributeMappingsFromDictionary:userInformation];
Because the inputs and outputs are the wrong way around. Instead, use the inverseMapping from your response mapping.

RestKit RKObjectMapping error, update from 0.10 to 0.20

I'm updating RestKit from 0.10 to 0.20 and getting some errors I'm trying to figure out.
I'm getting errors on the Spring.m file for the MappingForClass:usingBlock, no #interface for mapKeyPathsToAttributes, and no #interface for hasMany:withMapping.
Can't seem to figure this out myself.
Spring.h
#interface Spring : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSNumber *id;
#property (nonatomic, strong) NSArray *leafs;
+ (RKObjectMapping *)mapping;
#end
Spring.m
#implementation Spring
// Creating RestKit object mapping variable, THIS IS WHERE ERRORS OCCUR
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapKeyPathsToAttributes:
#"name", #"name",
#"id", #"id",
nil];
[mapping hasMany:#"leafs" withMapping:[Leaf mapping]];
}];
return objectMapping;
}
#end
I'm using https://github.com/RestKit/RestKit/wiki/Upgrading-from-v0.10.x-to-v0.20.0 to help me try to figure this out.
Answer: Needed to use RKRequestDescriptor

RestKit Entity mapping

Hi can someone teach me how to do nested Restkit Entity Mapping? i keep get error message while debug, below are my error message and code
[__NSSetM insertObject:atIndex:]: unrecognized selector sent to instance 0x95269d0
Json data
Family =(
{
id = "1";
parentName = "Mr John";
Child =(
{
parentID = "1";
childName = "James";
age = "18";
},
{
parentID = "1";
childName = "ruby";
age = "19";
},
{
parentID = "1";
childName = "ella";
age = "20";
}
);
}
);
My AppDelegate.m
RKEntityMapping *familyMapping = [RKEntityMapping mappingForEntityForName:#"Family" inManagedObjectStore:managedObjectStore];
debtorMapping.identificationAttributes = #[ #"id" ];
[familyMapping addAttributeMappingsFromDictionary:#{
#"id": #"accNo",
#"parentName": #"companyName"
}];
RKEntityMapping *childMapping = [RKEntityMapping mappingForEntityForName:#"Child" inManagedObjectStore:managedObjectStore];
childMapping.identificationAttributes = #[ #"parentID"];
[childMapping addAttributeMappingsFromDictionary:#{
#"parentID": #"parentID",
#"childName": #"childName",
#"age": #"age"
}];
[familyMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"Child" toKeyPath:#"Child" withMapping:childMapping]];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:familyMapping
pathPattern:nil
keyPath:#"Family"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
Family NSManagedObject
#class Child;
#interface Family : NSManagedObject
#property (nonatomic, retain) NSString * id;
#property (nonatomic, retain) NSString * parentName;
#property (nonatomic, retain) NSSet *child;
#end
#interface Family (CoreDataGeneratedAccessors)
- (void)addChildObject:(Child *)value;
- (void)removeChildObject:(Child *)value;
- (void)addChild:(NSSet *)values;
- (void)removeChild:(NSSet *)values;
#end
Child NSManageObject
#class Family;
#interface Child : NSManagedObject
#property (nonatomic, retain) NSString * parentID;
#property (nonatomic, retain) NSString * childName;
#property (nonatomic, retain) NSString * age;
#property (nonatomic, retain) Family *family;
#end
i found out my mistake already.
[familyMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"Child" toKeyPath:#"child" withMapping:childMapping]];
the toKeyPath string should assign with small letter. "follow core data relationship string".

Resources