Parsing of google apis - ios

I'm new to ios and working on parsing and got the url shown below:-
#"https://maps.googleapis.com/maps/api/place/textsearch/xml?query=%#&sensor=true&key=%#",typedtext,kGOOGLE_API_KEY
But i am not able to parse it.
I am having no idea about this, how is should be done.
So please kindly help me out.

If that link returns a json, you can put the response in a NSData and than with JSONObjectWothData:options:error: parse it.
EX.
NSString *urlStr = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false
"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString:urlPercoso]];
json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
});
Where json is a NSDictionary
then you receive a structure like that:
{
"results" : [
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Amphitheatre Pkwy",
"short_name" : "Amphitheatre Pkwy",
"types" : [ "route" ]
},
{
"long_name" : "Mountain View",
"short_name" : "Mountain View",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Santa Clara",
"short_name" : "Santa Clara",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "California",
"short_name" : "CA",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "94043",
"short_name" : "94043",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
"geometry" : {
"location" : {
"lat" : 37.42291810,
"lng" : -122.08542120
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 37.42426708029149,
"lng" : -122.0840722197085
},
"southwest" : {
"lat" : 37.42156911970850,
"lng" : -122.0867701802915
}
}
},
"types" : [ "street_address" ]
}
],
"status" : "OK"
}
so like data you can take al the info because now is just a dictionary, array, string and number value so then your can do that alone for more info look this link

Please follow this its working code for xml parsing
https://github.com/71squared/TBXML

Related

AFNetworking get json from Google Geocode API is incomplete

Is it a bug of AFNetworking or googleapi? I only get partial json result. And if I try it on Chrome, it works fine.
NSString *urlstring = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?components=postal_code:\"%#\"", zipcodefield.text];
urlstring = [urlstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager.responseSerializer setAcceptableContentTypes:[NSSet setWithArray:#[#"application/json"]]];
[manager GET:urlstring parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSDictionary *zipfile = (NSDictionary *)responseObject;
NSLog(#"%#", zipfile);
} failure:^(NSURLSessionTask *operation, NSError *error) {
//some code
}];
returns json with only part of the result the I got with Chrome:
{
results = (
{
"address_components" = (
{
"long_name" = "N2L 3W6";
"short_name" = "N2L 3W6";
types = (
"postal_code"
);
},
{
"long_name" = Waterloo;
"short_name" = Waterloo;
types = (
locality,
political
);
},
{
"long_name" = "Waterloo Regional Municipality";
"short_name" = "Waterloo Regional Municipality";
types = (
"administrative_area_level_2",
political
);
},
{
with Chrome, it returns a different full result:
{
"results" : [
{
"address_components" : [
{
"long_name" : "N2L 3W6",
"short_name" : "N2L 3W6",
"types" : [ "postal_code" ]
},
{
"long_name" : "Waterloo",
"short_name" : "Waterloo",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Waterloo Regional Municipality",
"short_name" : "Waterloo Regional Municipality",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Ontario",
"short_name" : "ON",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "Canada",
"short_name" : "CA",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Waterloo, ON N2L 3W6, Canada",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 43.4774664,
"lng" : -80.53395789999999
},
"southwest" : {
"lat" : 43.47248219999999,
"lng" : -80.538017
}
},
"location" : {
"lat" : 43.473585,
"lng" : -80.5351634
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 43.4774664,
"lng" : -80.53395789999999
},
"southwest" : {
"lat" : 43.47248219999999,
"lng" : -80.538017
}
}
},
"place_id" : "ChIJXV6ZhAf0K4gRYW7aCuG25xQ",
"types" : [ "postal_code" ]
}
],
"status" : "OK"
}
This may just be the NSLog limitation when printing the data. You can check out this question were its indicated that there may be practical limitations on printing logs. The best approach for this is to print it by "chunks". The result is a JSONArray to in which you can just print logs thru a loop on the objects (or just print the necessary information).

Google places api should return only address

I use this url to get addresses with Get request: https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Nov&key=MyKet&types=address
But sometimes I get only streets without houses, sometimes I get even cities (if input=Minsk in Russian: https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%D0%9C%D0%98%D0%9D%D0%A1%D0%9A&key=MyKey&types=address)
But I want to get only streets with houses, because I'm writing taxi application and I need there only full address, it's not enough if user selected only street.
So if I get from Google Proletarsk street 25, Bern, Switzerland - it's ok, but if I get from Google Proletarsk street, Bern, Switzerland - it's not ok.
And when I get the responce from Google for streets and addresses it always return the same type
types = (
route,
geocode
);
So I can't even differ if the return value is a street or if it's a full address.
Can you give me any advice?
Based on the use case you describe, it sounds like you used the wrong API.
You should be using the Geocoding API if you have the address and would love Google Maps parse it for you and return extra information. You can determine if the result has a street_number so that you can tell if the result contains a full address. For example:
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA
would give you a result like this:
{
"results" : [
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Amphitheatre Parkway",
"short_name" : "Amphitheatre Pkwy",
"types" : [ "route" ]
},
{
"long_name" : "Mountain View",
"short_name" : "Mountain View",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Santa Clara County",
"short_name" : "Santa Clara County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "California",
"short_name" : "CA",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "94043",
"short_name" : "94043",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
"geometry" : {
"location" : {
"lat" : 37.4223455,
"lng" : -122.0841893
},
"location_type" : "ROOFTOP",
"viewp.....
Which give you a street_number and so you can tell it is a full address.

Http request on iOS. Not getting full string

I have this code to call the webservice to retrieve the coordinates given the address:
NSLog(#"\ndata:%#", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
if (error != nil) {
NSLog(#"\nerror:%#", error);
}
When I make 2 or 3 call, some of them I get the error != nil because the string is not full.
For example, if I've called "Ads" (http://maps.google.com/maps/api/geocode/json?address=ads) for the 3rd time or random time, I get this string:
{
"results" : [
{
"address_components" : [
{
"long_name" : "Addison Airport",
"short_name" : "Addison Airport",
"types" : [ "establishment" ]
},
{
"long_name" : "220",
"short_name" : "220",
"types" : [ "subpremise" ]
},
{
"long_name" : "16051",
"short_name" : "16051",
"types" : [ "street_number" ]
},
{
"long_name" : "Addison Road",
"short_name" : "Addison Rd",
"types" : [ "route" ]
},
{
"long_name" : "Addison",
"short_name" : "Addison",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Dallas County",
"short_name" : "Dallas County",
so my parser doesn't work.
I repeat, this is on random times, I have to execute the code several times to reproduce it.
What am I doing wrong?
Thank you in advance.
I think you forgot to collect all data-snippets of the whole response and past them together in one NSData object. This is just a part of the complete response. Maybe this post can help you.

Google places api Administrative_Area_level strange wrong format?

I'm using google places api to retrive information about some cities that users can select with an autocomplete UItableview.
My first Request give me a list of cities and locality,starting from the search string:
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=salo&types=(cities)&key=APIKEY
From the results list i take the place_id of "Salò" a city in Italy. With this id the second request:
https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJdf_ajleOgUcRGniBFh7H884&key=APIKEY
And this is the resulting json:
{
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "Salò",
"short_name" : "Salò",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Salo'",
"short_name" : "Salo'",
"types" : [ "administrative_area_level_3", "political" ]
},
{
"long_name" : "Brescia",
"short_name" : "BS",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Lombardia",
"short_name" : "Lombardia",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "Italia",
"short_name" : "IT",
"types" : [ "country", "political" ]
}
],
"adr_address" : "\u003cspan class=\"locality\"\u003eSalò\u003c/span\u003e \u003cspan class=\"region\"\u003eBS\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eItalia\u003c/span\u003e",
"formatted_address" : "Salò BS, Italia",
"geometry" : {
"location" : {
"lat" : 45.60839199999999,
"lng" : 10.5104769
},
"viewport" : {
"northeast" : {
"lat" : 45.6146863,
"lng" : 10.5464998
},
"southwest" : {
"lat" : 45.59572439999999,
"lng" : 10.4992233
}
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
"id" : "f505830b9f7b6886f119df1b07bec0a6785940c7",
"name" : "Salò",
"place_id" : "ChIJdf_ajleOgUcRGniBFh7H884",
"reference" : "CnRtAAAAP9oklxjP8yqebLXhyFK0PM7l_w8zD8eBdNszf67rPHlckKnrhhs66eXZTYHfBiEizetRM8m7e8qxM6otVCX0QvxQ4jXgSv4VcH7NY2ZbYysboNplu8vaFs_BhITJ1MQJ-TunE9L-r1nBavhMLQRKNBIQqsKl1vt_pyqE_7Ow1aXp-hoU9jreecvh94V2ZpHT1JB-DxfoZEI",
"scope" : "GOOGLE",
"types" : [ "locality", "political" ],
"url" : "https://maps.google.com/maps/place?q=Sal%C3%B2+BS,+Italia&ftid=0x47818e578edaff75:0xcef3c71e1681781a",
"vicinity" : "Salò"
},
"status" : "OK"
}
From this json i need to extract the value from administrative_area_level_3 but i see something strange in accent, why the locality long_name value is "Salò" while the administrative_area_level_3 long_name value is "Salo'" ? What's the sense of this behaviour? In this way the administrative_area_level_3 results in the uilabel of my app as "Salo\'" even with utf8 encode/decode process...

Can Ruby Geocoder return just the street name on reverse_geocode calls?

The geocoder gem will automatically reverse geocode on save if the line after_validation :reverse_geocode is included in the model. This results in a long string of text being saved as the address, though - the format is something like "Street Name, City Name, County Name, State Name, Zip Code, Country Name".
I'm only interested in the street name for this particular project, so I'm wondering if there's a way to modify the after_validation call to only save that information.
If I do the reverse geocoding manually, I can access the road value in the result:
place = Place.first
result = Geocoder.search("#{place.latitude},#{place.longitude}")
street = result[0].data['address']['road']
I could set up my own custom after_validation that does just this, but I'd rather not duplicate functionality if geocoder already provides this.
Alternatively, if there's an entirely different way that I can convert latitude/longitude to street name I'd be interested in hearing about it. It would be OK if this option included the address number or address range as well.
You can customize the reverse_geocode method by providing a block which takes the object to be geocoded and an array of Geocoder::Result objects.
reverse_geocoded_by :latitude, :longitude do |obj,results|
if geo = results.first
obj.street = geo.address
end
end
after_validation :reverse_geocode
Every Geocoder::Result object, result, provides the following data:
result.latitude - float
result.longitude - float
result.coordinates - array of the above two
result.address - string
result.city - string
result.state - string
result.state_code - string
result.postal_code - string
result.country - string
result.country_code - string
More information can be found in the geocode docs. You might even be able to find more fields that you can pull off of the Geocoder::Result object.
You can access all the attributes from the selected geocoding service that you are using by using the :data method.
query = "45.679, -45.567"
result = Geocoder.search(query).first
if (result)
all_attributes = result.data
end
This will return a JSON response of all the available keys and values for your particular coordinates. If you are using Google to reverse geocode then you would get a response similar to this:
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Amphitheatre Pkwy",
"short_name" : "Amphitheatre Pkwy",
"types" : [ "route" ]
},
{
"long_name" : "Mountain View",
"short_name" : "Mountain View",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Santa Clara County",
"short_name" : "Santa Clara County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "California",
"short_name" : "CA",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "94043",
"short_name" : "94043",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
"geometry" : {
"location" : {
"lat" : 37.4224764,
"lng" : -122.0842499
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 37.4238253802915,
"lng" : -122.0829009197085
},
"southwest" : {
"lat" : 37.4211274197085,
"lng" : -122.0855988802915
}
}
},
"place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
"types" : [ "street_address" ]
}
So just drill down through the JSON to get what you desire:
result.data["address_components"].each do |component|
if component["types"].include?("route")
street = component["long_name"]
end
end
Please note the formatting will be different for each geocoding service that you use: Here is another example using Yandex:
street = result.data["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"]

Resources