Overpass-API iOS EXAMPLE - ios

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?

Related

how to handle space in sending json parameters to server in ios?

I am sending data to the server it is going successful but response coming with %20 at the space in data what I have sent to server here is the code I am using
NSString *str = [NSString stringWithFormat:#"http://www.me911.com/new/miphone3/android_edithealth.php?profile_id=%#&health_condition=%#&health_insurance_provider=%#&primary_physician_name=%#&primary_physician_phone=%#&last_physical=%ld&blood_type=%#&organ_donor=%#",profileId,txthospital.text,textinsurence.text,txtprimary.text,txtphone.text,dateInMillis,questionNo,textorgan.text];
str = [str stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSLog(#"Healthinfo URL: %#",str);
NSMutableURLRequest *dataRqst = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[dataRqst setHTTPMethod:#"POST"];
NSString *stringBoundary = #"0xKhTmLbOuNdArY---This_Is_ThE_BoUnDaRyy---pqo";
NSString *headerBoundary = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",stringBoundary];
[dataRqst addValue:headerBoundary forHTTPHeaderField:#"Content-Type"];
NSMutableData *postBody = [NSMutableData data];
[dataRqst setHTTPBody:postBody];
NSHTTPURLResponse *dataresponse =[[NSHTTPURLResponse alloc] init];
NSError* error = [[NSError alloc] init] ;
//synchronous filling of data from HTTP POST response
NSData *responseData = [NSURLConnection sendSynchronousRequest:dataRqst returningResponse:&dataresponse error:&error];
//convert data into string
NSString *responseString = [[NSString alloc] initWithBytes:[responseData bytes] length:[responseData length] encoding:NSUTF8StringEncoding];
NSLog(#"responseString %# ",responseString);
if (responseString == NULL)
{
NSDictionary *infoDic = [[NSDictionary alloc] initWithObjectsAndKeys:#"There was a small problem",
#"title",
#"The network doesn't seem to be responding, please try again.",
#"message",
#"OK",
#"cancel",
#"1",
#"tag",nil,
#"delegate", nil];
[CommonFunctions performSelectorOnMainThread:#selector(showAlertWithInfo:) withObject:infoDic waitUntilDone:NO];
}
else
{
NSDictionary *jsonResponse = [responseString JSONValue];
if ([jsonResponse objectForKey:#"error"]){
NSLog(#"response %#",jsonResponse);
}
else{
}
NSMutableArray *dataresponse=[jsonResponse valueForKey:#"success"];
if ([jsonResponse objectForKey:#"success"])
{
NSLog(#"Array response %#",dataresponse);
}
}
And this is web service
:http://anaadit.net/miphone3/android_edithealth.php?profile_id=287&health_condition=palo%20Alto%20Veterans%20Hospital%20&health_insurance_provider=Blue%20Cross&primary_physician_name=Dr.Akki&primary_physician_phone=6504935000&last_physical=-57600&blood_type=7&organ_donor=No
Here I am sending data in textfield in like guru prasad but response getting like this guru%20prasad.
So please correct me where am I going wrong .
thanks in advance
Your code has a number of issues.
In order to create a URL with query params, I recommend to use the utility class NSURLComponents (see Apple documentation: NSURLComponents).
Composing a POST request whose content type is "multipart/formdata" is quite error prone. If you absolutely have to compose such a request I very strongly recommend to use a Network Library, for example AFNetworking.
On the other hand, using a POST request whose Content-Type is application/json is very easy to setup, especially with NSURLSession and friends.
You can find specific solutions for any of the suggested approaches mentioned above on SO, too.
Its seems there is some problem in parsing data, the space are replaced with %20...It seems you are using NSURL Connection for making API Calls.
Use AFNetworking for making API Calls, the response data will automatically come in JSON format and you can initialize Dictionary from same.
Please find below link for AFNetworking:
https://github.com/AFNetworking/AFNetworking
Please use "AFNetworking" and the code will be:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"profile_id": #"287", #"health_condition": #"palo Alto Veterans Hospital", #"health_insurance_provider": #"Blue Cross",
#"primary_physician_name":#"Dr.Akki",
#"primary_physician_phone":#"6504935000",
#"last_physical":#"-57600",
#"blood_type":#"7",
#"organ_donor":#"No"};
[manager POST:#"http://anaadit.net/miphone3/android_edithealth.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Please try the above code. I think this will help you.

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.

AFnetworking keep returning response Code=-1011 "Request failed: client error (422)

I'm try to use AFNetworking to create a POST request. However I always return an error says:
Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: client error (422)" UserInfo=0x7ff1fa76a5c0 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7ff1fa76ce40> { URL: https://isisfriends.zendesk.com/requests/mobile_api/create.json } { status code: 422, headers {
"Cache-Control" = "no-cache";
Connection = "keep-alive";
"Content-Length" = 33;
"Content-Type" = "application/json; charset=UTF-8";
Date = "Mon, 20 Oct 2014 14:56:54 GMT";
P3P = "CP=\"NOI DSP COR NID ADMa OPTa OUR NOR\"";
Server = nginx;
"Set-Cookie" = "_zendesk_shared_session=eyJpZCI6IjUxYjdmOGFjMzZjMzE1MjRjNDE0OTFiMjRmYmYzNjhhIiwibG9jYWxlX2lkIjoxfQ%3D%3D--229c90ddd7cf33dc5886aba445fd51cccaf69ea7; path=/; secure; HttpOnly, _zendesk_session=BAh7CkkiD3Nlc3Npb25faWQGOgZFVEkiJWVhZTRmZTQ5ZDQ1NmZjOTgzZDBlMzgyMWQ5YjMwMjNlBjsAVEkiDGFjY291bnQGOwBGaQMdNgdJIgpyb3V0ZQY7AEZpAuq9SSIOaXNfbW9iaWxlBjsAVFRJIhN3YXJkZW4ubWVzc2FnZQY7AFR7AA%3D%3D--c8bf5a2774eb5fdaa8ff7ec2da6adef3f76b15c3; path=/; secure; HttpOnly";
Status = "422 Unprocessable Entity";
Vary = Accept;
"X-Frame-Options" = SAMEORIGIN;
"X-Rack-Cache" = "invalidate, pass";
"X-Request-Id" = b71fc58dc1cf122d395b77968aff9014;
"X-Runtime" = "0.088859";
"X-UA-Compatible" = "IE=Edge,chrome=1";
"X-XSS-Protection" = "1; mode=block";
"X-Zendesk-Origin-Server" = "app13.pod2.sac1.zdsys.com";
"X-Zendesk-Request-Id" = 10c9143fd5ac87ab66d3;
} }, NSErrorFailingURLKey=https://isisfriends.zendesk.com/requests/mobile_api/create.json, com.alamofire.serialization.response.error.data=<7b226572 726f7222 3a22496e 76616c69 6420656d 61696c20 61646472 65737322 7d>, NSLocalizedDescription=Request failed: client error (422)}
Here is my code:
NSString * question = [_textFieldQuestion text];
NSString * detail = [_textFieldDetails text];
NSString * email = [_textFieldEmail text];
if(question.length > 0 && detail.length > 0 && email.length > 0)
{
NSString *url = #"https://isisfriends.zendesk.com/requests/mobile_api/create.json";
NSDictionary *parameters = #{#"subject":question, #"description":detail, #"email":email};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer *reqSerializer = [AFJSONRequestSerializer serializer];
[reqSerializer setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[reqSerializer setValue:#"1.0" forHTTPHeaderField:#"X-Zendesk-Mobile-API"];
manager.requestSerializer = reqSerializer;
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSLog(parameters.descriptionInStringsFileFormat);
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"===== JSON: ======= %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"============== Error: ============\n%#", [error description]);
}];
} else {
}
I'm petty sure the parameters I provided (subject, description, email)is corrent, becuase if I put the parameters directly in the url like below, it works fine.
https://isisfriends.zendesk.com/requests/mobile_api/create.json?subject=testing&email=testing#asd.com&description=testing
422 client error is for failed authentication. Check if you need any authentication or if you think You have permission, Look for the logged Failure error serialised in the console to check what server has to say about your call.
Use this simplified code:
NSString *myUrlString= YOUR LINK;
NSMutableDictionary* postRequestDictionary = [[NSMutableDictionary alloc] init];
postRequestDictionary[#"YOUR PARAMATER"]= YOUR PARAMETER VALUE;
// ... ADD ANY MORE PARAMETER IF YOU WANT HERE ...
NSLog(#"body = %#",postRequestDictionary);
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc]init];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"HEADER VALUE" forHTTPHeaderField:#"HEADER"];
// ... ADD ANYMORE HEADER IF YOU WANT ...
[manager POST:myUrlString parameters:postRequestDictionary success:^(AFHTTPRequestOperation *requestOperation,id JSON){
NSLog(#"%#",JSON);
} failure:^(AFHTTPRequestOperation *requestFailureOperation , NSError *error){
NSLog(#"%#",error);
NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: errorData options:kNilOptions error:nil];
NSLog(#"Failure error serialised - %#",serializedData);
}];
Hope this helps. 😊👍

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

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.

Resources