Adding custom header in httprequest restkit 0.20 ios - ios

I am trying to add a custom header to all the http request from the app but on server side I am not getting it.
I tried following methods:
1.setting header in NSMutableURLRequest:
[request addValue:headerString forHTTPHeaderField:#"deviceDetails"];
NSLog( #"%#",[request valueForHTTPHeaderField:#"deviceDetails"]);
Here I get null just after setting the header value. Not sure what is happening.
2.setting default header in RKObjectManager
[manager.HTTPClient setDefaultHeader:#"deviceDetails" value:headerString];
Here header seems to be set but on server there is no header field with key "deviceDetails"
Any help would be appreciated.
Code:
NSMutableURLRequest *request =[self _createPostRequestWithParams:[NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:nil] andPath:path];
[request setTimeoutInterval:20];
NSLog(#"%#",[request valueForHTTPHeaderField:#"deviceDetails"]);
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:BASE_URL]];
[manager setRequestSerializationMIMEType:#"application/json"];
[manager.HTTPClient setAuthorizationHeaderWithUsername:self.offlineService.user.username password:self.offlineService.user.password];
[manager addResponseDescriptor: [self _getResponseDescriptorWithKeyPath:keyPath andResponseClass:responseClass]];
[manager.HTTPClient setDefaultHeader:#"deviceDetails" value:#"String value" encoding:NSUTF8StringEncoding]];
RKObjectRequestOperation *operation = [self _createOperationForRequest:request successcallback:requestSuccessful failurecallback:requestFailure target:target manager:manager];
[operation start];
_createOperationForRequest:
- (RKObjectRequestOperation *)_createOperationForRequest:(NSMutableURLRequest *)request successcallback:(SEL)requestSuccessful failurecallback:(SEL)requestFailed target:(id)target manager:(RKObjectManager *)manager {
RKObjectRequestOperation *operation = [manager objectRequestOperationWithRequest:request
success:^(RKObjectRequestOperation *operation,RKMappingResult *result) {
}
failure:^(RKObjectRequestOperation *operation,NSError *error){
}];
return operation;
}
In above code both basic authentication and device details header are received on the server side.

Related

Restkit - enqueueObjectRequestOperation not being called after adding rootviewcontroller in appdelegate

I have been using Restkit to connect to my API server, and it works perfectly. Now my situation is that I added a checker in my appdelegate.m in didFinishLaunchingWithOptions. it checks if there is already adminID in the coredata. if there was a adminID stored, when the app is relaunched, it will set the rootviewcontroller into a uinavigation controller. but when the uiviewcontroller is called, the Restkit enqueueObjectRequestOperation is not called.
Here's my code:
in appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//adminID is fetch from custom Entity in core data
if(adminID==0){
AllKommunScreenViewController *adminController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"AllKommunScreenID"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:adminController];
self.window.rootViewController = navController;
}
return YES;
}
Here's my code in the Navigation controller's Rootview:
-(void)fetchData{
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[Auth class]];
[responseMapping addAttributeMappingsFromArray:#[#"status", #"sucess", #"data"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *userProfileDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:statusCodes];
NSString *apiPath = [NSString stringWithFormat:#"%#%#", baseURL,#"/api/kommun/all/stats/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:apiPath]];
request setValue:_sharedManager.userAccessToken forHTTPHeaderField:#"X-ACCESS-TOKEN"];
RKObjectRequestOperation *operation =[[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:#[userProfileDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {} failure:^(RKObjectRequestOperation *operation, NSError *error) {}];
[RKObjectManager sharedManager] enqueueObjectRequestOperation:operation];
}
i called the fetchData in viewWillAppear.
Then i add a breakpoint to the function, and it goes there, the problem is that the restkit is not calling the enqueueObjectRequestOperation.
Please help!!!
By the way, i make a custom core data entity to store the adminID
Why are you calling?
[RKObjectManager sharedManager] enqueueObjectRequestOperation:operation];
I think you should call
RKObjectRequestOperation *operation =[[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:#[userProfileDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
//print something
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
// print something
}];
[operation start];
If you want to add it to queue of Object Request Operations you should first init RKObjectManager and than call enqueueObjectRequestOperation:
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:baseUrl];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:apiPath]];
request setValue:_sharedManager.userAccessToken forHTTPHeaderField:#"X-ACCESS-TOKEN"];
RKObjectRequestOperation *operation =[[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:#[userProfileDescriptor]];
[manager enqueueObjectRequestOperation:operation];

IOS sending post method data can access in php as get method

I am very new to iOS. I am trying to send data through post method to PHP. In PHP it can't take data like $_POST['data'], but it takes $_GET['data']. My iOS code is as follows.
NSString *strURL = [NSString stringWithFormat:#"http://example.com/app_respond_to_job?emp_id=%#&job_code=%#&status=Worker-Accepted&comment=%#",SaveID2,txtJobcode1,alertTextField.text];
NSURL *apiURL = [NSURL URLWithString:strURL];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:apiURL];
[urlRequest setHTTPMethod:#"POST"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
_receivedData = [[NSMutableData alloc] init];
[connection start];
NSLog(#"URL---%#",strURL);
Can someone explain why is that, it will be very helpful.
Please Download this file https://www.dropbox.com/s/tggf5rru7l3n53m/AFNetworking.zip?dl=0
And import file in your project
Define in #import "AFHTTPRequestOperationManager.h"
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"Your Url"]];
NSDictionary *parameters = #{#"emp_id":SaveID2,#"job_code":txtJobcode1.text,#"status":alertTextField.text};
AFHTTPRequestOperation *op = [manager POST:#"rest.of.url" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[responseObject valueForKey: #"data"];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
because you send your data via query string in url
i think it will work if you try to pass data in your request's body:[urlRequest setHTTPBody:...]
POST parameters come from the request body, not from the URL string. You'll need to:
Call setHTTPBody on the request and provide the URL-encoded string (sans question mark, IIRC) as the body data
Call setValue:forHTTPHeaderField: to set the Content-Type to application/x-www-form-urlencoded
Either remove the call to [connection start] or use initWithRequest:delegate:startImmediately: so that you aren't starting the connection twice.
That last one is kind of important. You can get strange results if you try to start a connection twice. :-)

RESTKit 2.0: Pattern string must not be empty in order to perform pattern matching

I use the code below to login to the server:
//First Block Code
-(RKObjectManager *)getObjectManager
{
NSURL *baseURL = [NSURL URLWithString:#"http://api.domain.com"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:baseURL];
RKObjectManager *manager = [[RKObjectManager alloc]initWithHTTPClient:httpClient];
[manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[manager.HTTPClient setParameterEncoding:AFJSONParameterEncoding];
[RKMIMETypeSerialization registeredMIMETypes];
return [RKObjectManager sharedManager];
}
- (void)loginUserwithUsername:(NSString *)username andPassword:(NSString *)password requestByNewUser:(BOOL)newRegistration
{
[self getObjectManager];
RKObjectManager *objectManager = [RKObjectManager sharedManager];
[objectManager.HTTPClient setAuthorizationHeaderWithUsername:username password:password];
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKMapping *mapping = [RESTMappingProvider profileMapping];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:nil statusCodes:statusCodeSet];
NSMutableURLRequest *request = [objectManager.HTTPClient requestWithMethod:#"POST"
path:#"/login"
parameters:#{#"username": username,
#"password": password
}];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request
responseDescriptors:#[responseDescriptor]];
[objectManager.HTTPClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"mappingResults Error %#", error);
}
}];
[operation start];
}
AFTER I login, I try to make a Google Places API request and get an error:
//Second Block of Code
- (void)fetchPlaces:(NSString *)input;
{
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKMapping *mapping = [RESTMappingProvider googleAutoCompleteMapping];
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/json?input=%#&sensor=true&key=%#&location=0.000000,0.000000", input, self.key];
NSString *urlStringEncoded = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStringEncoded];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:#"predictions" statusCodes:statusCodeSet];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request
responseDescriptors:#[responseDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
self.responseObjects = mappingResult.array;
[operation start];
}
Error:
2014-04-02 14:11:17.865 App[1247:60b] *** Assertion failure in +[RKPathMatcher pathMatcherWithPattern:], /Users/App
Time/Pods/RestKit/Code/Support/RKPathMatcher.m:74
2014-04-02 14:11:17.868 App[1247:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Pattern string must not be empty in order to perform pattern matching.'
However, if I never Login (meaning that I skip the first code in this question) and go straight to call Google API, there is no crash API works great.
I think there is something that I'm doing to RESTKit (perhaps by creating an ObjectManager), by Logging-in that's causing Google's API call to cause a crash.
I tried to run Charles Web Debug Proxy, but the crash seems to happen even before making the API call.
*EDIT *
I found out what is causing the crash:
[[RKObjectManager sharedManager] cancelAllObjectRequestOperationsWithMethod:RKRequestMethodAny matchingPathPattern:nil];
This was an attempt to Cancel all previous requests.
I replaced it with:
[[RKObjectManager sharedManager] cancelAllObjectRequestOperationsWithMethod:RKRequestMethodAny matchingPathPattern:#"maps/api/place/autocomplete"];
and it seems to work.
Question: Does this code cancel any previous request to: https://maps.googleapis.com/maps/api/place/autocomplete/json ?
When you create responseDescriptor this is added to the RKObjectManager you use pathPattern:nil. This is not permitted. You must specify a path pattern as RestKit must lookup the appropriate response descriptor to apply to the received response.
Later, you again use pathPattern:nil, but this is directly with an RKObjectRequestOperation. In this case it is allowed (and thus works) because you have provided an explicit list and no lookup is required.

AFJSONParameterEncoding in AFNetworking 2.x.x

I am implementing following paypal REST API:
curl -v https://api.sandbox.paypal.com/v1/vault/credit-card \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {accessToken}' \
-d '{
"payer_id":"user12345",
"type":"visa",
"number":"4417119669820331",
"expire_month":"11",
"expire_year":"2018",
"first_name":"Joe",
"last_name":"Shopper"
}'
I have successfully implement this api in AFNetworking 1.3.3 with following Code. Where PPWebService is subclass of AFHTTPClient
[[PPWebService sharedClient] setParameterEncoding:AFJSONParameterEncoding];
[[PPWebService sharedClient] setDefaultHeader:#"Content-Type" value:#"application/json"];
[[PPWebService sharedClient] setDefaultHeader:#"Authorization" value:[NSString stringWithFormat:#"Bearer %#", accessToken]];
[[PPWebService sharedClient] postPath:#"vault/credit-card"
parameters:creditCard
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *response = [self JSONToObject:operation.responseString];
creditCardId = response[#"id"];
if(creditCardId)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Credit card" message:#"Saved !!" delegate:nil cancelButtonTitle:#"on" otherButtonTitles:nil];
[alert show];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Credit card" message:error.description delegate:nil cancelButtonTitle:#"on" otherButtonTitles:nil];
[alert show];
}];
I want to use AFNetworking 2.x.x in my project. But I am not able to do it with this new version.
I have subclass AFHTTPRequestOperationManager. I search internet and people suggest me to use AFJSONRequestSerializer. All other code is very similar. But than also I am getting bad request error.
So how can I send raw JSON string in with POST method in AFNetworking 2.x.x?
EDIT
Code for AFNetworking 2.X.X
Error Status : 404 Bad Request
Response :
{"name":"MALFORMED_REQUEST","message":"The request JSON is not well formed.","information_link":"https://developer.paypal.com/docs/api/#MALFORMED_REQUEST","debug_id":"ab3c1dd874a07"}
I am getting proper response by using Postman as shown in following screenshot.
So finally I got answer. I use subclass of AFHTTPSessionManager to implement API in my project. And use it with singleton object. So this is my singleton method.
+ (MASWebService *)APIClient
{
static MASWebService *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
NSURL *baseURL = [NSURL URLWithString:BaseURL];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_sharedClient = [[MASWebService alloc] initWithBaseURL:baseURL sessionConfiguration:config];
_sharedClient.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
_sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];
[_sharedClient.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
});
return _sharedClient;
}
The main key line is setting Request Serializer HTTP Header "Content-Type" to "application/json"
If you are not subclassing AFHTTPSessionManager and using AFHTTPRequestOperationManager for single request than also it will work because AFHTTPRequestOperationManager is also conform to AFURLRequestSerialization protocol as property of AFHTTPRequestSerializer. I have not done it but it should look like this.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[manager POST:#"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
I hope this will work. Inform me in comment if I am wrong somewhere.
Source : AFNetworking 2.0 POST request working example code snippet
So how can I send raw JSON string in with POST method in AFNetworking 2.x.x?
I had the same issue when trying to use SOAP+XML data with AFHTTPRequestOperationManager. Apparently the request serializer should be subclassed to make provision for your special serialisation needs, but this way seems easier:
NSError *error = nil;
NSData *envelopeData = [NSJSONSerialization dataWithJSONObject:params options:options error:nil];
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:#"POST"
URLString:path
parameters:nil
error:&error];
// In my case, I also needed the following:
// [request setValue:action forHTTPHeaderField:#"SOAPAction"];
[request setHTTPBody:envelopeData];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] init];
operation = [self HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
// parse response here
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
// parse response here
}];
It hijacks the request serialiser that is created by AFHTTPRequestOperationManager, inserts the parameter data into the HTTP body, and then passes this new request into the AFHTTPRequestOperation.

Error with RestKit POST Request

I am trying to send JSON data in POST request to server using RestKit but I am getting error
Expected content type {(
"application/x-www-form-urlencoded",
"application/json"
)}, got text/plain
The code I have written is:
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",BASE_SERVICE_URL,TASK_SERVICE_URL]];
RKObjectMapping *mapping=[RKObjectMapping mappingForClass:[LoginData class]];
[mapping addAttributeMappingsFromDictionary:#{#"s":#"status",
#"message":#"message"}];
RKResponseDescriptor *descriptor=[RKResponseDescriptor responseDescriptorWithMapping:mapping method:RKRequestMethodPOST pathPattern:nil keyPath:#"" statusCodes:0];
NSMutableURLRequest *request=[[NSMutableURLRequest alloc]initWithURL:url];
[request setHTTPMethod:#"POST"];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSDictionary *dict=#{#"task":#"storeProfile",
#"fdate":#"01.01.2013",
#"tdate":#"19.08.2013",
#"keyword":#"taxi && cab",
#"AlertHours":#"120",
#"AlertDay":#"0",
#"AlertTimeStart":#"12:00",
#"AlertTimeEnd":#"18:00",
#"topic":#[
#{#"tname":#"Politics"},
#{#"tname":#"Economy"}
],
#"publication":#[
#{#"pname":#"Vijay Times Online"},
#{#"pname":#"Leisure Opportunities"}
]
};
NSError *error=nil;
NSData *jsonData=[NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
return;
}
[request setHTTPBody:jsonData];
operation=[[RKObjectRequestOperation alloc]initWithRequest:request responseDescriptors:#[descriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
LoginData *data=[mappingResult.dictionary objectForKey:#""];
NSLog(#"%#",data.message);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"ERROR:%#",error.localizedDescription);
}];
[operation start];
Could somebody please help me to figure out what exactly the problem is??
I have tried setting content type as follow also:
[request addValue:#"application/application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
Try this
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:BASE_URL]];
[objectManager setRequestSerializationMIMEType:RKMIMETypeJSON];
You have to register the class RKNSJSONSerialization . Please include the below code in your method.
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:#"text/plain"];

Resources