I need to send query string in URL as well as JSON in body while making POST request.To send query string in url i override HTTPMethodsEncodingParametersInURI property as suggested in this thread on SO like
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:fullUrl]];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer.HTTPMethodsEncodingParametersInURI = [NSSet setWithArray:#[#"POST", #"GET", #"HEAD", #"PUT", #"DELETE"]];
[manager POST:fullUrl parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
but it seems doing this add my JSON data into URL as well, hence my request is not executed on server.But i need to send only 'command' parameter into url and some JSON data into request body.
my fullUrl string is looks like http://some_ip_address/config?command=some_command and param is NSDictionary object.
Note that there is a parameter in fullUrl i.e. command and i also send a NSDictionary object as param in
[manager POST:fullUrl parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
Edit2: I also tried with NSURLSession
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://my_server_ip/config?command=plugs"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:param options:0 error:&error];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
[postDataTask resume];
but get status code: 400 in NSURLResponse.
Edit3: someone suggested to subclass AFHTTPRequestSerializer class in this SO thread so i tried with
#implementation CustomAFHTTPRequestSerializer
-(id)init
{
self = [super init];
return self;
}
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
error:(NSError *__autoreleasing *)error
{
NSString* encodedUrl = [URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:encodedUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *error1;
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error1];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:[NSString stringWithFormat:#"%d", [postData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
return request;
}
#end
And assign it as requestSerializer of operationManager
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [[CustomAFHTTPRequestSerializer alloc] init];
But still get Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed: bad request (400)
Please help me guys, Any help would be highly appreciated.
Related
I tried Like this..
-(void)GetCartIdDetails{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *post = [NSString stringWithFormat:#"username=%#&pasword=%#",self.TextUsername.text,self.TextPassword.text];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://192.168.0.21/mahroosa/rest/V1/integration/customer/token"]];
[request setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//MultiThreading
if (postData){
dispatch_async(dispatch_get_main_queue(), ^{
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
//removing Double Qoutes From String
NSString *Replace =[requestReply stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSLog(#"requestReply: %#", Replace);
}] resume];
});
}
});
}
Using AFNetworking:
-(void)Gettok {
NSString* URLString = [NSString stringWithFormat:#"http://192.168.0.21/mahroosa/rest/V1/integration/customer/token"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
manager.requestSerializer = requestSerializer;
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[params setObject:self.TextUsername.text forKey:#"username"];
[params setObject:self.TextPassword.text forKey:#"password"];
[manager POST:URLString parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError * error;
NSArray *result = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
NSLog(#"--------------------respons : %#--------------------",result);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(#"----------------------Error ; %#------------------------------",error);
}];
}
The content type of the request body. Set this value "Content-Type:application/json"
In response i get decode error message.I already got the get JSON getrequest working in AFNetworking but this post request is giving me some problems. Thanks for help in advance.
In the first NSURLSession style you don't send json to the service. Try it like this:
-(void)GetCartIdDetails{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSDictionary *dict = #{#"username":self.TextUsername.text,
#"password":self.TextPassword.text};
NSData *postData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://192.168.0.21/mahroosa/rest/V1/integration/customer/token"]];
[request setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//MultiThreading
if (postData){
dispatch_async(dispatch_get_main_queue(), ^{
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
//removing Double Qoutes From String
NSString *Replace =[requestReply stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSLog(#"requestReply: %#", Replace);
}] resume];
});
}
});
}
Is there anyway to send a POST request with a JSON body using AFNetworking ~> 2.0?
I have tried using:
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager POST:<url> parameters: #{#"data":#"value"} success: <block> failure: <block>'
but it doesn't work. Any help is greatly appreciated.
Thanks
You can add your JSON body in NSMutableURLRequest not direct in parameters:. See my sample code :
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// Set post method
[request setHTTPMethod:#"POST"];
// Set header to accept JSON request
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Your params
NSDictionary *params = #{#"data":#"value"};
// Change your 'params' dictionary to JSON string to set it into HTTP
// body. Dictionary type will be not understanding by request.
NSString *jsonString = [self getJSONStringWithDictionary:params];
// And finally, add it to HTTP body and job done.
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:<block> failure:<block>];
Hope this will help you. Happy coding! :)
If someone looking for AFNetworking 3.0, here is code
NSError *writeError = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&writeError];
NSString* jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:120];
[request setHTTPMethod:#"POST"];
[request setValue: #"application/json; encoding=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setValue: #"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody: [jsonString dataUsingEncoding:NSUTF8StringEncoding]];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
NSLog(#"Reply JSON: %#", responseObject);
if ([responseObject isKindOfClass:[NSDictionary class]]) {
//blah blah
}
} else {
NSLog(#"Error: %#", error);
NSLog(#"Response: %#",response);
NSLog(#"Response Object: %#",responseObject);
}
}] resume];
i want to convert this code to AFNetworking but i have a error. i used
AFNetworking POST to REST webservice this code.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *latest_url = #"url_string";
[request setURL:[NSURL URLWithString:latest_url]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:useragent_string forHTTPHeaderField:#"User-Agent"];
[request setValue:host_string forHTTPHeaderField:#"Host"];
[request setValue:#"keep-alive" forHTTPHeaderField:#"Connection"];
[request setValue:#"keep-alive" forHTTPHeaderField:#"Proxy-Connection"];
[request setTimeoutInterval:30.0];
[request setHTTPBody:postData];
NSError *errorx = nil;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&errorx];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSData *jsonData = [json_string dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonerror;
NSData *get_data_from_request = [ourdelegate do_request:request_url post_array:request_post_array debug:istekdebug];
NSArray *statuses =[NSJSONSerialization JSONObjectWithData: jsonData options: NSJSONReadingMutableContainers error: &jsonerror];
How to convert this code to AFNetworking?
Since you are using post request, here's what you can do with AFHTTPSessionManager. You can also call AFHTTPSessionManager Get method with block invocation.
NSURL *baseURL = [NSURL URLWithString:BaseURLString];
NSDictionary *parameters = #{#"Host": host_string};
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:#"yourFile.php" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog("handle succes");
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog("handle error %#",[error localizedDescription]);
}];
Have fun :)
Since you aren't being specific with the error like rckoenes mentioned above.......
Why don't you just go get PAW from LuckyMarmot
It helps you formulate REST api calls and will translate the request into AFNetworking for you. Phenomenal tool for only $19.99. Worth every penny.
First calling for "post method" its working fine using AFHTTPRequestOperationManager. But second time i called get method for same AFHTTPRequestOperationManager got EXC_BAD_ACCESS. Please check my below source and help how to resolve.
FIRST CALLING "POST" METHOD- WORKING FINE
NSString *post =[[NSString alloc] initWithFormat:#"grant_type=client_credentials"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
NSMutableURLRequest *request = [[NSMutableURLRequest
alloc] init];
[request setURL:[NSURL URLWithString:#"https://example.com/oauth/token"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"enctype"];
[request setValue:#"xxxxxxxxxx"] forHTTPHeaderField:#"Authorization"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"enctype"];
[request setHTTPBody:postData];
[request setTimeoutInterval:120];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.securityPolicy.allowInvalidCertificates = YES;
[manager.requestSerializer setTimeoutInterval:120];
[post release];
AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] init];
operation2 = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSHTTPURLResponse *response = (NSHTTPURLResponse *)operation.response;
NSLog(#"Response: %#", operation.responseString);
NSLog(#"%ld", (long)response.statusCode);
NSData* data=[operation.responseString dataUsingEncoding:NSUTF8StringEncoding];
NSString *response1 = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding: NSUTF8StringEncoding];
[[NSNotificationCenter defaultCenter] postNotificationName:#"check_auth_token_init" object:[[ResponseHandler instance] parseToken:response1]];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", operation.responseString);
}];
[operation2 start];
SECOND CALLING "GET" METHOD- EXC_BAD_ACCESS
NSMutableURLRequest *request = [[NSMutableURLRequest
alloc] init];
[request setURL:[NSURL URLWithString:#"https://example.com/stu/groups/"]];
[request setHTTPMethod:#"GET"];
[request setValue:#"testing" forHTTPHeaderField:#"Authorization"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
//Here i tried to internalize "AFHTTPRequestOperationManager" but im getting EXC_BAD_ACCESS Please check attached screen shots
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] init];
manager.securityPolicy.allowInvalidCertificates = YES;
// Configure Request Operation Manager
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
// Send Request
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", operation.responseString);
}];
[operation start];
The warning "Method possibly missing a [super dealloc] call" suggests that you're compiling AFNetworking without ARC, which would explain why objects are being prematurely deallocated.
Please follow the installation instructions provided in the AFNetworking README to ensure that everything is configured correctly.
I am using AFHTTPRequestOperationManager (2.0 AFNetworking library) for a REST POST request. But the manager only have the call to set the parameters.
-((AFHTTPRequestOperation *)POST:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
I need to set HTTP request body with a string as well. How can I do it using the AFHTTPRequestOperationManager? Thanks.
I had the same problem and solved it by adding code as shown below:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL
cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[request setHTTPMethod:#"POST"];
[request setValue:#"Basic: someValue" forHTTPHeaderField:#"Authorization"];
[request setValue: #"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: [body dataUsingEncoding:NSUTF8StringEncoding]];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON responseObject: %# ",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
[op start];
for AFHTTPRequestOperationManager
[requestOperationManager.requestSerializer setValue:#"your Content Type" forHTTPHeaderField:#"Content-Type"];
[requestOperationManager.requestSerializer setValue:#"no-cache" forHTTPHeaderField:#"Cache-Control"];
// Fill parameters
NSDictionary *parameters = #{#"name" : #"John",
#"lastName" : #"McClane"};
// Customizing serialization. Be careful, not work without parametersDictionary
[requestOperationManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
NSString *argString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return argString;
}];
[requestOperationManager POST:urlString parameters:parameters timeoutInterval:kRequestTimeoutInterval success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (success)
success(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure)
failure(error);
}];
Check what that convenience method (POST:parameters:success:failure) is doing under the hood and do it yourself to get access to actual NSMutableRequest object.
I'm using AFHTTPSessionManager instead of AFHTTPRequestOperation but I imagine the mechanism is similar.
This is my solution:
Setup Session Manager (headers etc)
Manually create NSMutable request and add my HTTPBody, basically copying-pasting code inside that convenience method. Looks like this:
NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:#"POST" URLString:[[NSURL URLWithString:<url string>] absoluteString] parameters:parameters];
[request setHTTPBody:[self.POSTHttpBody dataUsingEncoding:NSUTF8StringEncoding]];
__block NSURLSessionDataTask *task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
if (error) {
// error handling
} else {
// success
}
}];
[task resume];
If you dig a little in sources of AFNetworking you will find that in case of POST method parameters are set into body of your HTTP request.
Each key,value dictionary pair is added to the body in form key1=value1&key2=value2. Pairs are separated by & sign.
Search for application/x-www-form-urlencoded in AFURLRequestSerialization.m.
In case of a string which is only a string, not key value pair then you might try to use AFQueryStringSerializationBlock http://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock: but this is only my guess.
You could create your own custom subclass of AFHTTPRequestSerializer, and set this as the requestSerializer for your AFHTTPRequestOperationManager.
In this custom requestSerializer, you could override
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(id)parameters
error:(NSError *__autoreleasing *)error;
Inside your implementation of this method, you'll have access to the NSURLRequest, so you could do something like this
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(id)parameters
error:(NSError *__autoreleasing *)error
{
NSURLRequest *serializedRequest = [super requestBySerializingRequest:request withParameters:parameters
error:error];
NSMutableURLRequest *mutableRequest = [serializedRequest mutableCopy];
// Set the appropriate content type
[mutableRequest setValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
// 'someString' could eg be passed through and parsed out of the 'parameters' value
NSData *httpBodyData = [someString dataUsingEncoding:NSUTF8StringEncoding];
[mutableRequest setHTTPBody:httpBodyData];
return mutableRequest;
}
You could take a look inside the implementation of AFJSONRequestSerializer for an example of setting custom HTTP body content.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:jsonObject success:^(AFHTTPRequestOperation *operation, id responseObject) {
//success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//fail
}];
This is the best and most concise way that I have found.
May be we can use the NSMutableURLRequest, here is the code :
NSURL *url = [NSURL URLWithString:yourURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
NSString *contentJSONString = [[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding];
[request setHTTPBody:[contentJSONString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];