NSURLConnection works, but AFNetworking doesn't (on specific URL) - ios

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.

Related

How to use AFNetwowrking2.0 code for this Example url?

Hi I have one example url Which returns JSON Format. but when i use AFNetWorking2.0 to get the response from that URL, i am not getting correct Response. Here i am sending my code also.
- (void)testHTTPS {
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:YES];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager setSecurityPolicy:securityPolicy];
[manager GET:#"xxxxx"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSString* newStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
I am getting JSON Dic always nil. and if i print "newstr" i am getting html format response. can anyone please find correct way?
I have done as you said John but i am getting the below result
Error: Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x7ffb39c52ed0 {com.alamofire.serialization.response.error.response= { URL: xxxxx } { status code: 200, headers {
"Cache-Control" = "public, max-age=10800";
"Content-Encoding" = gzip;
"Content-Length" = 2922;
"Content-Type" = "text/html";
Date = "Wed, 29 Apr 2015 06:49:54 GMT";
Expires = "Wed, 29 Apr 2015 09:49:55 GMT";
"Last-Modified" = "Wed, 01 Apr 2015 03:19:39 GMT";
Server = "ECAcc (hhp/9ABE)";
Vary = "Accept-Encoding";
"X-Cache" = HIT;
} }, NSErrorFailingURLKey=xxxxx, com.alamofire.serialization.response.error.data=<0d0a3c21 444f4354 59504520 68746d6c 20505542 4c494320 222d2f2f 5733432f 2f445444 20584854 4d4c2031 2e302054 72616e73 6974696f 6e616c2f 2f454e22 20226874 74703a2f 2f777777 2e77332e 6f72672f 54522f78 68746d6c 312f4454 442f7868 746d6c31 2d747261 6e736974 696f6e61 6c2e6474 64223e0d 0a3c6874 6d6c2078 6d6c6e73 3d226874 74703a2f 2f777777 2e77332e 6f72672f 31393939 2f786874 6d6c223e 0d0a3c68 6561643e 0d0a3c6d 65746120 68747470 2d657175 69763d22 436f6e74 656e742d 54797065 2220636f 6e74656e >, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}
The problem is that you're using the AFHTTPResponseSerializer rather than AFNetworking's AFJSONResponseSerializer. Therefore, when the response comes in, it is parsing it as a HTTP response rather than a JSON response. This is easily fixed by assigning your manager.responseSerializer to AFJSONResponseSerializer instead:
manager.responseSerializer = [AFJSONResponseSerializer serializer];
You'll find that you won't need to create an NSDictionary from the response - upon success it should come through as an NSDictionary object already.
Check out the AFNetworking 2.0 migration guide. It's a very handy read and will make you aware of what to look out for in the future.

Request failed: unacceptable content-type: application/osm3s+xml

I'm trying to send request to OpenStreetMap api, and I'm still failing to do so. Please help me out what's incorrect.
My method:
NSString *url = #"http://api.openstreetmap.fr/xapi?node[name=London]";
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/osm3s+xml"];
[manager setResponseSerializer:[AFXMLParserResponseSerializer new]];
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, NSData *responseObject) {
NSLog(#"DATA: %#", responseObject);
[self stopProgress];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
self.textView.text = error.description;
[self stopProgress];
}];
Error:
Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: application/osm3s+xml" UserInfo=0x1702e1e80 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x17403d080> { URL: http://api.openstreetmap.fr/xapi?node%5Bname=London%5D } { status code: 200, headers {
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Length" = 7166;
"Content-Type" = "application/osm3s+xml";
Date = "Sun, 25 Jan 2015 21:18:54 GMT";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.2.22 (Debian)";
Vary = "Accept-Encoding";
} }, NSErrorFailingURLKey=http://api.openstreetmap.fr/xapi?node%5Bname=London%5D, com.alamofire.serialization.response.error.data=<3c3f786d 6c207665 7273696f 6e3d2231 2e302220 656e636f 64696e67 (... a lot of numbers ... )>, NSLocalizedDescription=Request failed: unacceptable content-type: application/osm3s+xml}
Your code:
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/osm3s+xml"];
Very clearly creates the header that OpenStreetMap is rejecting. Don't set that header: set it to a value like text/xml, which is documented as the right value.

Overpass-API iOS EXAMPLE

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?

AFNetworking getting json value. URL doesn't work

Im using AFNetworking to get JSON values from my iOS application i have tested my code to this link http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&alt=json then my code works fine. but when i use http://www.fr20.wearedesigners.net/WADMac/tourism/fetchGuideListAndroid.php this link to retrieve data im getting following Error please find below the code i used.please help me to retrieve data from my URL
-(void) retriveData
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:#"text/html" forHTTPHeaderField:#"Content-type"];
[manager GET:#"http://www.fr20.wearedesigners.net/WADMac/tourism/fetchGuideListAndroid.php" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
Error log
2014-07-19 18:36:01.107 WADTourisum[3000:60b] Reachability Flag Status: -R ------- networkStatusForFlags
2014-07-19 18:36:01.768 WADTourisum[3000:60b] Error: Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0xa05c4e0 {NSErrorFailingURLKey=http://www.fr20.wearedesigners.net/WADMac/tourism/fetchGuideListAndroid.php, com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x8d8ba40> { URL: http://www.fr20.wearedesigners.net/WADMac/tourism/fetchGuideListAndroid.php } { status code: 200, headers {
Connection = "Keep-Alive";
"Content-Type" = "text/html";
Date = "Sat, 19 Jul 2014 13:05:32 GMT";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.2.19 (Unix) mod_ssl/2.2.19 OpenSSL/0.9.8e-fips-rhel5 DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635";
"Transfer-Encoding" = Identity;
"X-Powered-By" = "PHP/5.2.17";
} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}
it happens
NSLocalizedDescription=Request failed: unacceptable content-type: text/html
format Content-Type" = "text/html doesn't have your AFNetworking.
Simply go to Serilization->AFURLResponseSerialization.m, line 215, and change it:
self.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/json", #"text/javascript",#"text/html", nil];
it will work you.
More recent versions may have the code on line 223.
Solution for Swift:
It will accept most of the content type.
let manager=AFHTTPRequestOperationManager()
manager.responseSerializer = AFJSONResponseSerializer(readingOptions: NSJSONReadingOptions.AllowFragments) as AFJSONResponseSerializer
manager.requestSerializer = AFJSONRequestSerializer() as AFJSONRequestSerializer
manager.responseSerializer.acceptableContentTypes = NSSet(objects:"application/json", "text/html", "text/plain", "text/json", "text/javascript", "audio/wav") as Set<NSObject>
The url you use (http://www.fr20.wearedesigners.net/WADMac/tourism/fetchGuideListAndroid.php ) returns a not accepted content-type header, instead of text/html it should return application/json.
As Otanaught says, the url you use (http://www.fr20.wearedesigners.net/WADMac/tourism/fetchGuideListAndroid.php ) returns a not accepted content-type header, instead of text/html it should return application/json.
If you have access to the PHP Web Service file, put this before any display code:
header('Content-type: application/json');
If u r using afnetwork 2.6.3 then
Simply go to Serilization -> AFURLResponseSerialization.m, line 224, and change it to:
self.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/json", #"text/javascript",#"text/html", nil];
it will work you.

Curl to AFNetworking?

I'm trying to use paypal Express checkout from a native iOS app (can't use paypal SDK because apple needs me to go through safari to make the payment). Problem is when i try to call the SetExpressCheckout API method. Here is the curl statement that they provide at the website:
curl -s --insecure https://api-3t.sandbox.paypal.com/nvp -d
"USER=callerID # User ID of the PayPal caller account
&PWD=callerPswd # Password of the caller account
&SIGNATURE=callerSig # Signature of the caller account
&METHOD=SetExpressCheckout
&VERSION=93
&PAYMENTREQUEST_0_PAYMENTACTION=SALE # type of payment
&PAYMENTREQUEST_0_AMT=19.95 # amount of transaction
&PAYMENTREQUEST_0_CURRENCYCODE=USD # currency of transaction
&RETURNURL=http://www.example.com/success.html # URL of your payment confirmation page
&CANCELURL=http://www.example.com/cancel.html" # URL redirect if customer cancels payment
I need to pass this to AFNetworking so i can do it inside the app, i've tried this but it's not working:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: kPaypalClientId,#"USER",
kPaypalPassword, #"PWD",
kPaypalSignature, #"SIGNATURE",
#"SetExpressCheckout", #"METHOD",
#"93", #"VERSION",
#"SALE",#"PAYMENTREQUEST_0_PAYMENTACTION",
#"19.95",#"PAYMENTREQUEST_0_AMT",
#"USD", #"PAYMENTREQUEST_0_CURRENCYCODE",
#"shareapp://bien",#"RETURNURL",
#"shareapp://cancel", #"CANCELURL", nil];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[manager POST:#"https://api-3t.sandbox.paypal.com/nvp" parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=%#",tokenValue]]];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
This is the error i'm getting:
Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/plain" UserInfo=0xba7de40 {NSErrorFailingURLKey=https://api-3t.sandbox.paypal.com/nvp, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xd06e720> { URL: https://api-3t.sandbox.paypal.com/nvp } { status code: 200, headers {
Connection = "keep-alive";
"Content-Length" = 230;
"Content-Type" = "text/plain; charset=utf-8";
DC = "origin1-api-3t.sandbox.paypal.com";
Date = "Tue, 15 Apr 2014 13:36:59 GMT";
Server = Apache;
"Set-Cookie" = "DC=origin1-api-3t.sandbox.paypal.com; secure";
} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/plain}
Thank you and sorry for my english!!
This line solved this for me:
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
You need to set the header: Content-Type: application/x-www-form-urlencoded when posting to the Paypal server.

Resources