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.
Related
I am having an issue where I am not able to connect to the API. This happens only with iOS8. It works fine with iOS7.
- (void)performSearch:(NSString*)type : (NSString*)keyword{
url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", API, keyword]];
request = [NSURLRequest requestWithURL:url];
operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
credential = [NSURLCredential credentialWithUser:USERNAME password:PASSWORD persistence:NSURLCredentialPersistenceForSession];
[operation setCredential:credential];
[[NSOperationQueue mainQueue] addOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *error = nil;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
if (error) {
NSLog(#"Error serializing %#", error);
return;
}
[self parseJSON:JSON :keyword];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error : %#", error);
}];
[operation start];
}
The Error message I am getting.
Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unauthorized (401)" UserInfo=0x7ff0650052f0 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7ff062c5e4d0> { URL: https://distribution.virk.dk/cvr-permanent-prod-20150622/_search?q=anders } { status code: 401, headers {
Connection = "keep-alive";
"Content-Length" = 194;
"Content-Type" = "text/html";
Date = "Tue, 18 Aug 2015 09:36:09 GMT";
Server = "nginx/1.6.2";
"Www-Authenticate" = "Basic realm=\"Beskyttet adgang\"";
} }, NSErrorFailingURLKey=https://distribution.virk.dk/cvr-permanent-prod-20150622/_search?q=anders, com.alamofire.serialization.response.error.data=<3c68746d 6c3e0d0a 3c686561 643e3c74 69746c65 3e343031 20417574 686f7269 7a617469 6f6e2052 65717569 7265643c 2f746974 6c653e3c 2f686561 643e0d0a 3c626f64 79206267 636f6c6f 723d2277 68697465 223e0d0a 3c63656e 7465723e 3c68313e 34303120 41757468 6f72697a 6174696f 6e205265 71756972 65643c2f 68313e3c 2f63656e 7465723e 0d0a3c68 723e3c63 656e7465 723e6e67 696e782f 312e362e 323c2f63 656e7465 723e0d0a 3c2f626f 64793e0d 0a3c2f68 746d6c3e 0d0a>, NSLocalizedDescription=Request failed: unauthorized (401)}
Status code is 401, which means that your account or password is incorrect. I suggest that you should log out the params, and find out whether they are null or anything else
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 do not know how to add parameters to the post request to Overpass-API. To create request I am using AFNetworking.
1) at the beginning, i build query in overpass-turbo.eu than i export it to XML, so i get this
<osm-script>
<query type="node">
<has-kv k="amenity" v="drinking_water"/>
<bbox-query e="12.51119613647461" n="41.89248629819397" s="41.88659196260802" w="12.488558292388916"/>
</query>
<print/>
</osm-script>
and put that in NSString
NSString *myString = #"<osm-script><query type=\"node\"><has-kv k=\"amenity\" v=\"drinking_water\"/><bbox-query e=\"12.51119613647461\" n=\"41.89248629819397\" s=\"41.88659196260802\" w=\"12.488558292388916\"/></query><print/></osm-script>";
2) than i try build params
AFNetworking - How can I PUT and POST raw data without using a key value pair?
So i create the NSData category method base64DataFromString is available here.
And create my request
NSString *urlString = #"http://overpass-api.de/api/interpreter";
NSURL *myUrl = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myUrl];
// Generate an NSData from your NSString (see below for link to more info)
NSData *postBody = [NSData base64DataFromString:myString];
// Add Content-Length header if your server needs it
unsigned long long postLength = postBody.length;
NSString *contentLength = [NSString stringWithFormat:#"%llu", postLength];
[request addValue:contentLength forHTTPHeaderField:#"Content-Length"];
// This should all look familiar...
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postBody];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response data: %#", responseObject);
self.textView.text = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
self.textView.text = [NSString stringWithFormat:#"%#",error];
}];
[manager.operationQueue addOperation:operation];
3) But now i get error
Error: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo=0x1700fc680 {NSUnderlyingError=0x170247290 "Request failed: unacceptable content-type: text/html", com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x170230860> { URL: http://overpass-api.de/api/interpreter } { status code: 400, headers {
Connection = close;
"Content-Encoding" = gzip;
"Content-Length" = 491;
"Content-Type" = "text/html; charset=utf-8";
Date = "Sat, 13 Dec 2014 13:25:37 GMT";
Server = "Apache/2.2.22 (Ubuntu)";
Vary = "Accept-Encoding";
} }, NSErrorFailingURLKey=http://overpass-api.de/api/interpreter, com.alamofire.serialization.response.error.data=<...
What im doing wrong?
This what you need to achieve is to create request with xml as the body. In your example AFNetworking will convert parameters into some body, but that body won't be an xml. You should store your xml as string and send it as raw body data: AFNetworking - How can I PUT and POST raw data without using a key value pair?
I set up a simple web server on an AWS EC2 instance and wrote a small test.php file that goes like this:
<?php
$dict = array("key" => "value", "test" => "Hello world");
echo json_encode($dict);
?>
In my browser I can go to http://'myInstanceIP'/test.php and I will get the encoded JSON response. I tried doing this in iOS and for some reason I can only get a successful response via NSURLConnection and not through AFNetworking. It's weird because the AFN code works if I input some other URL that will give me a JSON response, just not on my URL.
I call it in viewDidAppear just for testing:
- (void)viewDidAppear:(BOOL)animated
{
NSString *urlString = #"http://54.183.178.170/test.php";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", (NSDictionary *)responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed");
}];
[operation start];
}
I can't tell if it's the fault of my web server or AFN (since it works on NSURLConnection).
UPDATE:
Here's the failure code I'm getting from AFNetworking:
2014-09-02 11:50:11.538 testingAWS[26751:60b] Failed, error: Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x8c4ce00 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x8d80fa0> { URL: http://54.183.178.170/test.php } { status code: 200, headers {
Connection = "Keep-Alive";
"Content-Length" = 34;
"Content-Type" = "text/html";
Date = "Tue, 02 Sep 2014 18:50:09 GMT";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.4.7 (Ubuntu)";
"X-Powered-By" = "PHP/5.5.9-1ubuntu4.3";
} }, NSErrorFailingURLKey=http://54.183.178.170/test.php, NSLocalizedDescription=Request failed: unacceptable content-type: text/html, com.alamofire.serialization.response.error.data=<7b226b65 79223a22 76616522 2c227465 7374223a 2248656c 6c6f2077 6f726c64 227d>}
We can see here:
Code=-1016 "Request failed: unacceptable content-type: text/html"
That your problem should be happening because of this line:
operation.responseSerializer = [AFJSONResponseSerializer serializer];
For some reason your server must be returning a non-JSON response, and you are using a JSONResponseSerializer. So if you fix the server return type the correct format you'll probably be fine.
Or, you could just change the serializer type like this:
operation.responseSerializer = [AFHTTPResponseSerializer serializer];
if it's just for a testing purpose.
So it turns out I need to add the following line to my PHP, right before json_encode():
header('Content-type: application/json');
Then it works with AFNetworking as it should.
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.