I want send object through post protocol to server. I use for it RestKit framework.
so, example:
PData *item = [[PData alloc] init];
item.uri = #"http://google.com";
item.status = #"0";
item.updated = [NSDate date];
item.created = [NSDate date];
item.user_id = #"3";
RKObjectManager *sharedManager = RKObjectManager sharedManager;
[sharedManager postObject:item
path:nil
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self printPData:mappingResult];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"\n\n\n == \nERROE = %#",error);
}];
How can I push json (which consist data of item) in some key ("data")?
(this data on server I can take from $_POST["data"])
How can I do request like this?
{
"data": {
"created": "2014-03-05 14:49:30",
"status": "0",
"updated": "2014-03-05 14:49:30",
"uri": "http:\/\/google.com",
"user_id": "3"
}
}
now, I have had only this:
{
"status": "0",
"updated": "2014-03-05 14:52:17",
"user_id": "3",
"uri": "http:\/\/google.com",
"created": "2014-03-05 14:52:17"
}
It sounds like you haven't specified a key path in your request descriptor. At the moment, somewhere in your code, you'll have something like this:
RKRequestDescriptor *descriptor =
[RKRequestDescriptor requestDescriptorWithMapping:mapping
objectClass:[PData class]
rootKeyPath:nil
method:RKRequestMethodAny];
You need to change it to:
RKRequestDescriptor *descriptor =
[RKRequestDescriptor requestDescriptorWithMapping:mapping
objectClass:[PData class]
rootKeyPath:#"data"
method:RKRequestMethodAny];
That way RestKit will know that PData objects ought to be mapped to the data key path.
Related
I would like to use RestKit but I don't see how to write the pathPattern and the keyPath, where the json returns :
{
"photos": {
"page": 1,
"pages": 39594,
"perpage": 10,
"total": "395933",
"photo": [
{
"id": "16766829152",
"owner": "32546988#N00",
"secret": "5b38b40c57",
"server": "8744",
"farm": 9,
"title": "City box lights",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
}
]
}
}
The error :
Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No mappable object representations were found at the key paths searched
This is what I have now :
#define kBaseRESTURL #"https://api.flickr.com/services/rest/?method="
#define kSearchMethod #"flickr.photos.search"
-(void)configureRestKit{
NSString *url = [NSString stringWithFormat:#"%#%#", kBaseRESTURL, kSearchMethod];
NSURL *baseURL = [NSURL URLWithString:url];
AFHTTPClient* client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
RKObjectManager *manager = [[RKObjectManager alloc] initWithHTTPClient:client];
RKObjectMapping* photoMapping = [RKObjectMapping mappingForClass:[Photo class]];
[photoMapping addAttributeMappingsFromArray:#[#"title"]];
RKResponseDescriptor *responseDesc = [RKResponseDescriptor responseDescriptorWithMapping:photoMapping method:RKRequestMethodGET pathPattern:#"" keyPath:#"photos.photo" statusCodes:[NSIndexSet indexSetWithIndex:200]];
[manager addResponseDescriptor:responseDesc];
}
-(void)loadCities : (void(^)(NSArray*))completion {
[self configureRestKit];
NSDictionary *queryParams = #{#"api_key" : apiKey,
#"tags" : #"cities",
#"per_page" : #"10",
#"format" : #"json",
#"nojsoncallback" : #"1"
};
[[RKObjectManager sharedManager] getObjectsAtPath:#"" parameters:queryParams success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"ok");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#" ");
NSLog(#"error : %#", error);
}];
}
Thanks
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.
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).
I'm sending out a request to get an object with an nested array of data. However, RestKit is only saving the last item in the nested array of data.
For example, here's the JSON response the server is delivering
{
"nutrition_day": {
"id": "5342e9e13138610012420100",
"start_on": "2014-04-07",
"meal_goals": [
{
"id": "5342e9e13138610012410100",
"name": "Breakfast",
"food_entries": [
{
"id": "535429513663320008210000",
"consumed_on": "2014-04-20",
"food_id": 33801,
"serving_id": 29457,
}
]
},
{
"id": "5342e9e13138610012430100",
"name": "Morning Snack",
"food_entries": []
}
]
}
}
However, using the code below, when I attempt to access nutrition_data.meal_goals, I am left with only the last item in the array "Morning Snack" and am not getting "Breakfast"
Mapping:
+ (void)mapping
{
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
RKEntityMapping *responseMapping = [RKEntityMapping mappingForEntityForName:#"NutritionDay" inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
[requestMapping addAttributeMappingsFromArray:#[#"date"]];
[responseMapping addAttributeMappingsFromArray:#[#"start_on", #"protein_target"]];
[responseMapping setIdentificationAttributes:#[#"start_on"]];
[responseMapping addRelationshipMappingWithSourceKeyPath:#"meal_goals" mapping:[MealGoal responseMapping]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:[NutritionDay class]
rootKeyPath:#"nutrition_day"
method:RKRequestMethodGET];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping
method:RKRequestMethodAny
pathPattern:#"nutrition/days/:date"
keyPath:#"nutrition_day"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[RKObjectManager sharedManager] addRequestDescriptor:requestDescriptor];
[[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor];
}
Request:
[[RKObjectManager sharedManager] getObjectsAtPath:#"nutrition/days/2014-12-12" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NutritionDay *nut = ((NutritionDay *)mappingResult.firstObject);
NSLog(#"%lu", (long)nut.meal_goals.count); // this always returns 1 when it should be 2
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"fail");
}];
Is there something I need to do so that RestKit recognizes the entire array of the relationship and saves it?
I would suggest that you should include the id in your mapping and use that as the identification attribute.
meal_goals should be a to-many relationship (with inverse).
Your log should be:
NSLog(#"%lu", (long)nut.meal_goals.count);
Other than those things, the code you show looks correct. Log the entire mapping result to verify the contents.
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).