It seems that AFNetworking isn't working correctly for me. Specifically when I send apiKey request to server it gives me an unauthorized error. ASIHTTPRequest works fine for me however, so there seems to be something I am doing wrong in AFNetWorking. I know the problem is sending apiKey because if I comment it out AFNetWork works correctly. I still need to send the API key however. Any help will be appreciated.
AFNetWorking
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:apiKey forHTTPHeaderField:#"apiKey"];
NSMutableDictionary *userinfo = [[NSMutableDictionary alloc] init];
[manager POST:urlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[operation setUserInfo:userinfo];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[operation setUserInfo:userinfo];
}];
}
ASIHTTPRequest
NSString *urlStr = [NSString stringWithFormat:#"%#/%#", submitReportUrl, [self urlEncode:path]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setDelegate:self];
NSMutableDictionary *userinfo = [[NSMutableDictionary alloc] init];
[userinfo setObject:NSStringFromSelector(self.didFinishSelector) forKey:#"didFinishSelector"];
[userinfo setObject:NSStringFromSelector(self.didFailSelector) forKey:#"didFailSelector"];
[request setUserInfo:userinfo];
[request addRequestHeader:#"apiKey" value:apiKey];
[request setRequestMethod:method];
NSArray *keys = [params allKeys];
for ( NSString *key in keys )
[request addPostValue:[params objectForKey:key] forKey:key];
[self.operationQueue addOperation:request];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
I had the same problem working with the post. So research where was the problem. If you did not add the about line of the code. AFNetworking will automatically add in the header
Content-Type : "text/html"
either one
Cotent-Type : "text/plain"
By adding above code becomes
Content-Type : "application/json"
So the problem is solved. Since the server is expecting JSON.
Related
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. :-)
I have to make a post request using AFNetworking library with following request parameters
{
"method":"validate",
"name":{
"firstname":"john",
"lastname":"doe"
}
}
How to make this request using latest version of AFNetworking v3 library?
I used the following code and it doesn't work
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
[manager setRequestSerializer:[AFJSONRequestSerializer serializer]];
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
NSDictionary *parameters = #{\"method\":\"validate\",\"name\":{\"firstname\":\"john\",\"lastname\":\"doe\"}};
[manager POST:#"http://myUrl.." parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#",[responseObject description]);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#",[error localizedDescription]);
}];
Im getting the following error,
2016-02-13 11:04:54.085 SlideOutMenu[3698:50453] nulllllll
2016-02-13 11:04:55.794 SlideOutMenu[3698:50453] Failure Request failed: internal server error (500)
2016-02-13 11:04:55.795 SlideOutMenu[3698:50453] (null)
As you've already applied [manager setRequestSerializer:[AFJSONRequestSerializer serializer]] no need to convert dictionary to JSON again.
simply pass dictionary as a parameters, it will work.
NSDictionary *name = #{#"firstname": #"john", #"lastname": #"doe"};
NSMutableDictionary *parameters = [NSMutableDictionary new];
[parameters setObject:#"validate" forKey:#"method"];
[parameters setObject:name forKey:#"name"];
Also no need to initialise NSURLSessionConfiguration with defaultSessionConfiguration, AFNetworking will automatically initialise that. Simply use [AFHTTPSessionManager manager].
Your code is fine.Connect with your server guy.
code 500 is server side error.
check out this link for response code detail
http://www.restapitutorial.com/httpstatuscodes.html
So - I have identical AFNetworking code, that, when run on the simulator, returns results as expected, and gives me all the proper JSON back.
Soon as I run it on the device, I get a 401. Now, I understand this means 'unauthorized,' but how on earth does it run absolutely swimmingly on the simulator and then give me a 401 on the device?
The code is below and has only been changed to remove the address of our API which must remain private.
phoneNumber = phoneNumberField.text;
[[NSUserDefaults standardUserDefaults] setObject:phoneNumber forKey:#"phone_number"];
NSString *UDIDstring = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(#"UDID: %#",UDIDstring);
NSString *jsonRequest = [NSString stringWithFormat:#"{\"userId\":\"%#\",\"userType\":\"%#\",\"deviceId\":\"%#\",\"deviceType\":\"%#\"}",phoneNumberField.text,#"Number",UDIDstring,#"iPhone"];
NSLog(#"json: %#",jsonRequest);
NSDictionary *stuff = [[NSDictionary alloc] initWithObjectsAndKeys:
phoneNumberField.text, #"userId",
#"Number", #"userType",
UDIDstring,#"deviceId",
#"iPhone",#"deviceType",
nil];
NSLog(#"stuff: %#",stuff);
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:stuff options:0 error:&error];
NSString *urlString = #"(hidden for privacy reasons)"
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
NSString *userpass = [#"vclient:VastV1" base64EncodedString];
NSLog(#"userpass: %#",userpass);
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"Basic: %#",userpass] forHTTPHeaderField:#"Authorization"];
//[request setValue:#"*/*" forHTTPHeaderField:#"Accept"];
[request setValue: #"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
securityPolicy.allowInvalidCertificates = YES;
op.securityPolicy = securityPolicy;
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON responseObject: %# ",responseObject);
[infoLabel setText:#"You have been sent an activation code to the number you used. Please enter it above."];
[signupLabel setText:#"your code:"];
[mainButton setTitle:#"Activate" forState:UIControlStateNormal];
firstSignup=true;
[phoneNumberField setText:#""];
[phoneNumberField setPlaceholder:#"Enter activation code."];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
[op start];
One difference would be that you are reporting a different device ID. Maybe the API that you are using keeps track of device IDs that have been authorized. And your Mac has been authorized, but the iOS device hasn't.
You could try logging the device id on the Mac, and then change your code to use that ID as a hardcoded string, instead of using what the iPhone returns.
You can try this, I do it all the time
#import "AFNetworking.h"
NSDictionary *params = #{ #"key1": txtBox1.text, #"key2", txtbox2.text};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer *serializerRequest = [AFJSONRequestSerializer serializer];
AFJSONResponseSerializer *serializerResponse = [AFJSONResponseSerializer serializer];
[serializerRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"]];
serializerResponse.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
manager.requestSerializer = serializerRequest;
manager.responseSerializer = serializerResponse;
[manager.securityPolicy setAllowInvalidCertificates:YES];
[manager POST:#"url"
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// DO WHAT YOU WANT IF SUCCESSED
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// DO WHAT YOU WANT IF FAILED
}];
Are you using an authentication scheme that depends on the time? I've seen drift on the simulator that causes it to 401.
I have the following code below that uses a rather old library called ASIHTTPRequest. I am looking to upgrade the library, but need a little help to make sure I am doing it correctly and to get my feet wet. This is the code I need to convert to AFNetworking. Any tips or suggestions is appreciated.
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setDelegate:self];
NSMutableDictionary *userinfo = [[NSMutableDictionary alloc] init];
[userinfo setObject:NSStringFromSelector(self.didFinishSelector) forKey:#"didFinishSelector"];
[userinfo setObject:NSStringFromSelector(self.didFailSelector) forKey:#"didFailSelector"];
[request setUserInfo:userinfo];
[request setUserAgentString:USER_AGENT];
[request setTimeOutSeconds:60];
[request addRequestHeader:#"apiKey" value:apiKey];
[request setRequestMethod:method];
With AFNetworking the code should look like below
NSDictionary *parameters=#{"key":value};//The values you want to POST arrange in dictionary.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:apiKey forHTTPHeaderField:#"apiKey"];
[manager.requestSerializer setValue:USER_AGENT forHTTPHeaderField:#"User-Agent"];
[manager.requestSerializer setTimeoutInterval:60];
[manager POST:urlStr parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Result %#",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#",error.description);
}];
I hope it helps. Cheers.
How do I replicate this NSURLConnection code in AFNetworking 2.0?
NSString *post = #"key=xxx";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://test.com/"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[conn start];
Short answer: use the AFHTTPRequestSerializer provided by AFNetworking.
According to the document:
[[AFHTTPRequestSerializer serializer] requestWithMethod:#"POST" URLString:URLString parameters:parameters];
sends:
POST http://example.com/
Content-Type: application/x-www-form-urlencoded
foo=bar&baz[]=1&baz[]=2&baz[]=3
If you are using AFHTTPRequestOperationManager:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
// you can use different serializer for response.
manager.responseSerializer = [AFJSONResponseSerializer serializer];
It is given in the AFNetworking page github link
The code for sending post request is below, just import the AFNeworking folder in your project in xocde and add necessary frameworks getting started with afnetworking
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"key": #"xxx"};
[manager POST:#"http://test.com" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
In order to POST form-data with AFNetworking you must create this format out of your NSDictionary:
say you have to send these params :
{
key1 = val1;
key2 = val2;
key3 = val3;
}
create this format and encode data using UTF8Encoding :
key1=val1&key2=val2&key3=val3
You can use this formatting :
NSMutableString *str = [[NSMutableString alloc]init];
NSArray *allKeys = [dict allKeys];
for (NSString *key in allKeys) {
[str appendString:key];
[str appendString:#"="];
[str appendString:[dict valueForKey:key]];
[str appendString:#"&"];
}
[str deleteCharactersInRange:NSMakeRange([str length]-1, 1)];
NSData *requestBodyData = [str dataUsingEncoding:NSUTF8StringEncoding];
AFNetworking creates NSMutableRequest. In the HTTPBody of NSMutableRequest instance pass this requestBodyData.
Done.