Ever since upgrading my IOS code to use AFNetworking version 2.0 instead of 1.x, I cannot do an HTTP Post any more with JSON parameters.
I suspect it is because my HTTP request header is not "application/json" but I have tried to do that and it still does not work.
This is my test code for trying to POST by JSON:
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
email, #"email",
password, #"password",
nil];
[[OTApiClient sharedInstance] POST:#"login" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"result: %#", responseObject);
Boolean response = [[responseObject valueForKey:#"success"] boolValue];
if(response == TRUE) {
//ok, success
NSLog(#"success");
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Success!" message:#"Successfully logged in" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
} else {
NSLog(#"Not successful");
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"The email or password is incorrect." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %# , for operation: %#", error, operation);
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"There is a problem connecting to the server, please try again soon." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
}];
});
and I keep getting this error :
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0xca80730 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.} , for operation: <AFHTTPRequestOperation: 0xca6bee0, state: isFinished, cancelled: NO request: <NSMutableURLRequest: 0xca76040> { URL: http://1.2.3.4:9000/api/login }, response: <NSHTTPURLResponse: 0xc963d60> { URL: http://1.2.3.4:9000/error404 } { status code: 404, headers {
"Content-Length" = 1809;
"Content-Type" = "text/html; charset=utf-8";
} }>
I am very sure that the server is up and accessible because all other GET calls work properly.
I have checked the updated documentation for AFNetworking 2.0 and it seems like what I have is the right way to do a JSON POST
Please let me know if I missed anything
Thanks
IS
Actually, I finally got it to work.
Basically, for my requestSerializer of the AFHTTPRequestOperationManager, I was using AFHTTPRequestSerializer and then trying to set the Content-Type to "application/json"
But once I switched to using AFJSONRequestSerializer instead, it works fine now
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
operationManagerInstance.requestSerializer = requestSerializer;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
[serializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[serializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
manager.requestSerializer = serializer;
now it will work.
I encountered the same problem using AFNetworking API through Swift, trying to send a post request and finally got it work as well thanks to user1805458's post.
Basically, for my requestSerializer of the AFHTTPRequestOperationManager, I was also using AFHTTPRequestSerializer and then trying to set the Content-Type to "Application/JSON" and it did not work.
But once I switched to using AFJSONRequestSerializer instead, it works fine now:
let manager = AFHTTPRequestOperationManager()
manager.requestSerializer = AFJSONRequestSerializer(writingOptions: nil)
// Contrary to user1805458's solution, I did not need to use these two instructions below using Swift.
// manager.requestSerializer.setValue("Application/JSON", forHTTPHeaderField:"Content-Type")
// manager.requestSerializer.setValue("Application/JSON", forHTTPHeaderField:"Accept")
I hope it will help you to fix this error in case where you use Swift, AFNetworking and try to send a post request containing a JSON body.
Related
I use the below code to upload image to server.
NSString *url = [NSString stringWithFormat:#"http://192.250.1.52:xxx/api/user/profileUploadUser?userid=27&emailid=tom#gnts.in"];
NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc]init];
[jsonDict setObject:ImageToUpload forKey:#"file"];
////////ImageToUpload = /var/mobile/Containers/Data/Application/89112E0B-C1D6-4408-8586-6C5B4A431713/Documents/61.png
[manager POST:url parameters:jsonDict
success:^(AFHTTPRequestOperation *operation, id responseObject)
{ //////success code }
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Image upload" message:#"failure" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
NSLog(#"error message %#",error);
// handle failure
}];
It always enter into the failure block and
shows the error message.
error message : Error Domain=NSURLErrorDomain Code=-1001 "The request
timed out."
UserInfo={NSErrorFailingURLStringKey=http://192.250.1.52:xxxx/api/user/profileUploadUser?userid=27&emailid=tom#gnts.in, _kCFStreamErrorCodeKey=-21022}}}
Check your internet speed might be slow,
[manager.requestSerializer setTimeoutInterval:30];//Set request timeout interval time & interact with backend developer for same.
One more thing you can manage one retry counter in singleton & give second request if fails & if again fails then show toast message internet speed is slow.
You are trying to a POST operation whereas what you want is a file upload.
Try out AFNetworking multipart file upload.
I am trying to check if my POST request is working properly using AFNetworking in Objective c. Request is working fine in Android and Postman. Here is my URL:
#define API_BASE #"54.191.xx.xxx/XXXXXXXX/index.php/checkout"
Here are my params:
NSDictionary *paramters = #{#"quantity":#"21", #"price":#"10"};
This is my code to make the request:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
[manager POST:API_BASE parameters:paramters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#",responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:error.localizedDescription delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}];
This code never enters the success block and I am getting an error saying 'Unsupported URL'. Any help would be appreciated.
Change API_BASE value to include http://:
#define API_BASE #"http://54.191.26.206/EntropikSDKBackend/index.php/checkout
54.191.xx.xxx/XXXXXXXX/index.php/checkout is not a valid URL. You need to specify the scheme. Likely http:// or https://.
Note: http and https are the schemes. :// is just part of the URL syntax.
You will need to add http:// to your API_BASE, like so:
#define API_BASE #"http://54.191.26.206/EntropikSDKBackend/index.php/checkout
You will most likely also need to add an ATS exception to your info.plist to allow unencryped traffic to the host 54.191.26.206
You are missing the network reference path. Any URL you are providing should also need the network reference path for communication and to decide which scheme/protocol need to be used.
I tried lots but getting this error while calling this api for getting match schedule using this
- (IBAction)getButtonPressed:(id)sender
{
NSString *string = [NSString stringWithFormat:#"https://api.sportsdatallc.org/nba-Trial(t)1/ru/games/2014/reg/schedule.json?api_key=qgdmf6egtuf5guy9pdvk5ydf"];
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSLog(#"url is %#",url);
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// 3
NSLog(#"%#",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
// 5
[operation start];
}
getting this error
Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: server error (596)" UserInfo=0x7994db10 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x799335b0> { URL: https://api.sportsdatallc.org/nba-Trial(t)1/ru/games/2014/reg/schedule.json?api_key=qgdmf6egtuf5guy9pdvk5ydf } { status code: 596, headers {
Connection = "keep-alive";
"Content-Length" = 30;
"Content-Type" = "text/xml";
Date = "Fri, 20 Mar 2015 08:55:01 GMT";
Server = "Mashery Proxy";
"X-Mashery-Error-Code" = "ERR_596_SERVICE_NOT_FOUND";
} }, NSErrorFailingURLKey=https://api.sportsdatallc.org/nba- Trial(t)1/ru/games/2014/reg/schedule.json?api_key=qgdmf6egtuf5guy9pdvk5ydf, NSLocalizedDescription=Request failed: server error (596), com.alamofire.serialization.response.error.data=<3c68313e 35393620 53657276 69636520 4e6f7420 466f756e 643c2f68 313e>, NSUnderlyingError=0x7994eb90 "Request failed: unacceptable content-type: text/xml"}
I am using this website api:
http://developer.sportsdatallc.com/docs/NBA_API
Details of using this api:
Daily Schedule
Schema
Syntax:
http(s)://api.sportsdatallc.org/nba-[access_level][version]/schema/schedule-v2.0.xsd?api_key=[your_api_key]
Schema Example:
Feed
Syntax:
http(s)://api.sportsdatallc.org/nba-[access_level][version]/[locale]/games/[year]/[month]/[day]/schedule.xml?api_key=[your_api_key]
Parameter Format Notes
[access_level] = Production (p), Trial (t)
[version] = whole number (sequential, starting with the number 1)
[year] = Year in 4 digit format (YYYY)
[month] = Month in 2 digit format (MM)
[day] = Day of the month in 2 digit format (DD)
[format] = xml, json
Optional Parameters
[locale] = ru (russian), zh (simplified chinese)
In -[AFHTTPRequestOperationManager initWithBaseURL:], you will find that the responseSerializer property is set to an instance of AFJSONResponseSerializer. .
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:myURL];
To get the functionality you want(delivering a parsed XML model back to your callback as the responseObject), simply set the responseSerializer property to an instance of AFXMLResponseSerializer
manager.responseSerializer = [AFXMLResponseSerializer new];
Sample Code:
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:myURL];
manager.responseSerializer = [AFXMLResponseSerializer new];
[manager GET:#"http://www.example.com/feed" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Data: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
i wanted to get data from server encoded in json to display it, so i use afnetworking library but i get error here is my code
NSURL * url =[NSURL URLWithString:#"http://software-sultan.com/alaa/image_test.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// 3
array = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
NSLog(#"%#",error);
}];
// 5
[operation start];
here is the error
Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x7f920964bff0 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7f920965cc20> { URL: http://software-sultan.com/alaa/image_test.php } { status code: 200, headers {
Connection = "keep-alive";
"Content-Length" = 126781;
"Content-Type" = "text/html";
Date = "Thu, 29 Jan 2015 19:00:55 GMT";
"Keep-Alive" = "timeout=30";
Server = "Apache/2";
"X-Powered-By" = "PHP/5.3.13";
} }, NSErrorFailingURLKey=http://software-sultan.
It looks like you are trying to parse a JSON response with AFJSONResponseSerializer, but the webserver sends text/html as content type. JSON responses are generally served with the Content-Type: application/json header.
Also, if the response was successfully parsed as JSON, the responseObject given as the second parameter of your completion block would already be a valid NSArray containing your data. So there wouldn't need to create it again using NSJSONSerialization.
I have a Django Rest Api with a iOS app and right now I'm testing AFNetworking to change the HTTP Request my app is doing but i came with this dilema that i dont know how to handle, first is that on REST Standards when i get an error i should return a 404_BAD_REQUEST as a status if either sends or something wrong happens and this is OK. The issue comes when AFNetworking sees this 404. I still want to see the JSON that it returns.
curl -X POST http://domain.com:8000/user-login/ -d "nick=superUser&pass_field=superPassword"
i get 202 Status HTTP:
{
"nick": "eddwinpaz", "rate": 30, "name": "Eddwin Paz", "avatar": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn2/t1.0-1/p160x160/10270540_10154074250190063_1762683854515424400_n.jpg", "id": 9}eddwinpazs-MacBook-Pro:~ eddwinpaz$
}
When i get 404 BAD REQUEST i get:
{"message": "Invalid Username or Password"}
I want to grab that message json tag if i get a 404 Error
I've the following code. and put it on the message on the Alert
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"nick": #"eddwinpaz",#"pass_field":#"eddwinpaz1"};
AFHTTPRequestOperation *operation = [manager POST:#"http://domain.com/user-login/"];
[operation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndex:404]];
[manager POST:#"http://domain.com/user-login/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Login Failed"
message:#"E-mail or password are wrong, Please Try Again"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[hud hide:YES];
}];
Per default the error code 404 is handled as an error code. You could add it as one of the accepted error codes via
AFHTTPRequestOperation *operation = [manager POST:#"http://doma...
[operation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndex:404]];
Then success: is called on an 404 response and you can handle it there.
The answer by #miho did not work for me. addAcceptableStatusCodes does not exist in AFNetworking 2.5.0 from what I can tell. I had to do the following.
NSMutableIndexSet *acceptedCodes = [[NSMutableIndexSet alloc]
initWithIndexSet:operation.responseSerializer.acceptableStatusCodes];
[acceptedCodes addIndex:304];
operation.responseSerializer.acceptableStatusCodes = [acceptedCodes copy];