Facing difficulty in parsing google location response - ios

Using iOS 8.0.
I am using Google API for getting the location.and I want to reduce the coding using NSPredicate and KeyPath.
I am using below link for getting the google response,
iPhone - Get City name from Latitude and Longtiude
Using answer of user #'Constantin Saulenco'.
If I would a Sql developer I would write a query like,
1. (select address_components from MAIN_TABLE where types like 'postal_code') from this I will get NAME_TABLE rows.
2.select long_name from NAME_TABLE where types like 'locality'
For that I am using below code,After watching the #ztan's answer I have changed the coding like this
Edit: Answer
NSArray *addressArray = json[#"results"];
NSPredicate *predicateForTypes=[NSPredicate predicateWithFormat:#"(types CONTAINS 'postal_code')"];
addressArray=([addressArray filteredArrayUsingPredicate:predicateForTypes][0])[#"address_components"];
NSPredicate *predicateForCity=[NSPredicate predicateWithFormat:#"(types CONTAINS 'locality')"];
NSString *cityName=([addressArray filteredArrayUsingPredicate:predicateForCity][0])[#"long_name"];
I have below JSON...
{
"address_components" = (
{
"long_name" = 221;
"short_name" = 221;
types = (
"street_number"
);
},
{
"long_name" = "Juniper Drive";
"short_name" = "Juniper Dr";
types = (
route
);
},
{
"long_name" = "North Kingstown";
"short_name" = "North Kingstown";
types = (
locality,
political
);
},
{
"long_name" = "Washington County";
"short_name" = "Washington County";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = "Rhode Island";
"short_name" = RI;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = "United States";
"short_name" = US;
types = (
country,
political
);
},
{
"long_name" = 02852;
"short_name" = 02852;
types = (
"postal_code"
);
},
{
"long_name" = 4308;
"short_name" = 4308;
types = (
"postal_code_suffix"
);
}
);
"formatted_address" = "221 Juniper Drive, North Kingstown, RI 02852, USA";
geometry = {
location = {
lat = "41.577761";
lng = "-71.468383";
};
"location_type" = ROOFTOP;
viewport = {
northeast = {
lat = "41.5791099802915";
lng = "-71.46703401970849";
};
southwest = {
lat = "41.5764120197085";
lng = "-71.4697319802915";
};
};
};
"place_id" = ChIJ563yzFex5YkRujoi28Fvzvo;
types = (
"street_address"
);
},
{
"address_components" = (
{
"long_name" = "North Kingstown";
"short_name" = "North Kingstown";
types = (
locality,
political
);
},
{
"long_name" = "Washington County";
"short_name" = "Washington County";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = "Rhode Island";
"short_name" = RI;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = "United States";
"short_name" = US;
types = (
country,
political
);
}
);
"formatted_address" = "North Kingstown, RI, USA";
geometry = {
bounds = {
northeast = {
lat = "41.6549521";
lng = "-71.4023083";
};
southwest = {
lat = "41.497126";
lng = "-71.52244109999999";
};
};
location = {
lat = "41.5568315";
lng = "-71.4536835";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "41.6549521";
lng = "-71.4023083";
};
southwest = {
lat = "41.497126";
lng = "-71.52244109999999";
};
};
};
"place_id" = "ChIJgWUP-V-x5YkRO7Zie7NXWsI";
types = (
locality,
political
);
},2nd JSON Object, 3rd JSON Object ,......,....
My question is How to Reduce the coding ? Using NSPRedicates and KeyPath ..
This is how can we brake the problems......I have mentioned this in #ztan's answer, please have a look, It would be beneficial.
please see my second comment.......:)

You can do the following:
NSArray *addressArray = resultDict[#"results"];
NSPredicate *predicateFromTypes=[NSPredicate predicateWithFormat:#"(types CONTAINS 'postal_code') AND (types CONTAINS 'locality')"];
NSLog(#"\n%#", [addressArray[0][#"address_components"] filteredArrayUsingPredicate:predicateFromTypes][0][#"long_name"]);

try this
NSArray *filtered = [YOURARRAY filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"(types == %#)", #"locality "]];

Related

I want the value for key open_now in array

Opening :- (
"Not Available",
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
{
"open_now" = 1;
"weekday_text" = (
);
},
"Not Available",
{
"open_now" = 1;
"weekday_text" = (
);
},
"Not Available"
)
This is an output of my NSArray. It contains some strings as Not Available and it contains some NSDictionary starting with { "open_now" = 1; "weekday_text" = ( ); } .I wanted the value of only open_now. I don't know how to get value of open_now in my new NSArray. Please anyone help me.
Yes, use the NSArray -valueForKey: method.
NSArray *extracted = [sourceArray valueForKey:#"a key"];
You can use valueForKeyPath method of NSArray to get value of particular key.
NSArray *aryValue = [YOUR_ARRAY valueForKeyPath:#"open_now"];

Filter NSMutableDiction with Key

I need to filter this NSMutableDictionary on key value based where item_type= bad
i tried but not working
NSPredicate *pred=[NSPredicate predicateWithFormat:#"(item_type == %#)", #"Good"];
NSArray *resultArray = [[dummyDictionary allValues] filteredArrayUsingPredicate:pred];
NSLog(#"resultArray:%#",resultArray);
{
“Cat1” = (
{
"image_item" = “a”;
"item_type" = “Good”;
}
);
Cat2 = (
{
"image_item" = “b”;
"item_type" = Good;
},
{
"image_item" = “c”;
"item_type" = Bad;
},
);
Cat3 = (
{
"image_item" = “d”;
"item_type" = Good;
},
{
"image_item" = “e”;
"item_type" = Bad;
},
);
}
And need such output NSMutableDictionary
{
“Cat1” = (
);
Cat2 = (
{
"image_item" = “c”;
"item_type" = Bad;
},
);
Cat3 = (
{
"image_item" = “e”;
"item_type" = Bad;
},
);
}
NOTE: dummyDictionary is value i get from .plist

NSDictionary Not Getting First Item JSON

Maybe somebody can help. I am trying to get the location name for the google maps location and latitude in the URL below. As you can see from the JSON that it is first opening the results then the address_components. I am trying to get the first long_name and short_name in the JSON but instead the code I have below is only giving me the last long_name and short_name in the JSON.
Maybe someone has some type of idea, I have tried everything at this stage and nothing seems to solve the issue.
Thanks,
CurtisB
-(void)getPlaceName
{
NSString *urlString = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",53.348623,-6.243089];
NSURL *url = [NSURL URLWithString:urlString];
//Next we need a NSURLSession instance
NSURLSession *session = [NSURLSession sharedSession];
//All tasks (there are three, see documentation) are created from an NSURLSession instance
//We want a DataTask
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//This "block" (of code) will be executed when the call is complete
//Serialize the JSON to Foundation objects
NSDictionary *geocodeDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//Parse through the JSON to get to where we want, address_components array
NSArray *resultsArray = geocodeDictionary[#"results"];
NSDictionary *resultsDictionary = resultsArray[1];
NSArray *addressComponents = resultsDictionary[#"address_components"];
//Declare variables to hold desired results
NSString *longName;
NSString *shortName;
//The address_components array contains many dictionaries,
//we loop through each dictionary and check the types array
for (NSDictionary *addressComponentDictionary in addressComponents) {
longName = addressComponentDictionary[#"long_name"];
shortName = addressComponentDictionary[#"short_name"];
}
//Test log to see we are correct
NSLog(#"Long name for GetAddress is: %#", longName);
NSLog(#"Short Name is: %#", shortName);
}];
[dataTask resume];
}
JSON LOG:
[8948:3198407] {
results = (
{
"address_components" = (
{
"long_name" = "National College of Ireland";
"short_name" = "National College of Ireland";
types = (
premise
);
},
{
"long_name" = "Mayor Street Lower";
"short_name" = "Mayor Street Lower";
types = (
route
);
},
{
"long_name" = "International Financial Services Centre";
"short_name" = "International Financial Services Centre";
types = (
"sublocality_level_1",
sublocality,
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
locality,
political
);
},
{
"long_name" = "Dublin 1";
"short_name" = "Dublin 1";
types = (
"postal_town"
);
},
{
"long_name" = "Dublin City";
"short_name" = "Dublin City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "National College of Ireland, Mayor Street Lower, International Financial Services Centre, Dublin 1, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.34914449999999";
lng = "-6.2420244";
};
southwest = {
lat = "53.3484171";
lng = "-6.2435218";
};
};
location = {
lat = "53.3487808";
lng = "-6.242773100000001";
};
"location_type" = ROOFTOP;
viewport = {
northeast = {
lat = "53.3501297802915";
lng = "-6.241424119708499";
};
southwest = {
lat = "53.3474318197085";
lng = "-6.244122080291502";
};
};
};
"place_id" = "ChIJ7fLaG40OZ0gRJsCRPZA1_iA";
types = (
premise
);
},
{
"address_components" = (
{
"long_name" = "Excise Walk";
"short_name" = "Excise Walk";
types = (
route
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
locality,
political
);
},
{
"long_name" = "Dublin City";
"short_name" = "Dublin City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "Excise Walk, Dublin, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.3492304";
lng = "-6.2434942";
};
southwest = {
lat = "53.3484317";
lng = "-6.243662899999999";
};
};
location = {
lat = "53.34883110000001";
lng = "-6.243578599999999";
};
"location_type" = "GEOMETRIC_CENTER";
viewport = {
northeast = {
lat = "53.3501800302915";
lng = "-6.242229569708497";
};
southwest = {
lat = "53.3474820697085";
lng = "-6.244927530291502";
};
};
};
"place_id" = "ChIJG_rIHI0OZ0gRHTz7pFf9r7o";
types = (
route
);
},
{
"address_components" = (
{
"long_name" = "North Dock";
"short_name" = "North Dock";
types = (
neighborhood,
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
locality,
political
);
},
{
"long_name" = "Dublin City";
"short_name" = "Dublin City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "North Dock, Dublin, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.3608191";
lng = "-6.1894282";
};
southwest = {
lat = "53.34522";
lng = "-6.2549399";
};
};
location = {
lat = "53.3497493";
lng = "-6.2306567";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "53.3608191";
lng = "-6.1894282";
};
southwest = {
lat = "53.34522";
lng = "-6.2549399";
};
};
};
"place_id" = "ChIJr9h9M_oOZ0gRrycKzPZj46A";
types = (
neighborhood,
political
);
},
{
"address_components" = (
{
"long_name" = "Dublin Northside";
"short_name" = "Dublin Northside";
types = (
neighborhood,
political
);
},
{
"long_name" = Ashtown;
"short_name" = Ashtown;
types = (
"sublocality_level_1",
sublocality,
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
locality,
political
);
},
{
"long_name" = "Dublin City";
"short_name" = "Dublin City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "Dublin Northside, Ashtown, Dublin, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.4088667";
lng = "-6.0358715";
};
southwest = {
lat = "53.34558130000001";
lng = "-6.381769299999999";
};
};
location = {
lat = "53.3815507";
lng = "-6.1922052";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "53.4088667";
lng = "-6.0358715";
};
southwest = {
lat = "53.34558130000001";
lng = "-6.381769299999999";
};
};
};
"place_id" = ChIJvUSkJbcPZ0gRyXXPH9MSQwk;
types = (
neighborhood,
political
);
},
{
"address_components" = (
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
locality,
political
);
},
{
"long_name" = "Dublin City";
"short_name" = "Dublin City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "Dublin, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.42521010000001";
lng = "-6.0439235";
};
southwest = {
lat = "53.22343009999999";
lng = "-6.4474846";
};
};
location = {
lat = "53.3498053";
lng = "-6.2603097";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "53.42521010000001";
lng = "-6.0439235";
};
southwest = {
lat = "53.22343009999999";
lng = "-6.4474846";
};
};
};
"place_id" = ChIJL6wn6oAOZ0gRoHExl6nHAAo;
types = (
locality,
political
);
},
{
"address_components" = (
{
"long_name" = "Dublin City";
"short_name" = "Dublin City";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "Dublin City, Co. Dublin, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.4111566";
lng = "-6.1131916";
};
southwest = {
lat = "53.2988569";
lng = "-6.3870807";
};
};
location = {
lat = "53.3603142";
lng = "-6.315054200000001";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "53.4111566";
lng = "-6.1131916";
};
southwest = {
lat = "53.2988569";
lng = "-6.3870807";
};
};
};
"place_id" = ChIJv2RI7foRZ0gRwAKA8azHAAM;
types = (
"administrative_area_level_2",
political
);
},
{
"address_components" = (
{
"long_name" = Dublin;
"short_name" = Dublin;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = "Co. Dublin, Ireland";
geometry = {
bounds = {
northeast = {
lat = "53.6347257";
lng = "-5.9962748";
};
southwest = {
lat = "53.1781971";
lng = "-6.5468798";
};
};
location = {
lat = "53.3824769";
lng = "-6.3133674";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "53.6347257";
lng = "-5.9962748";
};
southwest = {
lat = "53.1781971";
lng = "-6.5468798";
};
};
};
"place_id" = ChIJv2RI7foRZ0gRwAKA8azHABg;
types = (
"administrative_area_level_1",
political
);
},
{
"address_components" = (
{
"long_name" = Ireland;
"short_name" = IE;
types = (
country,
political
);
}
);
"formatted_address" = Ireland;
geometry = {
bounds = {
northeast = {
lat = "55.4351345";
lng = "-5.994700099999999";
};
southwest = {
lat = "51.4199312";
lng = "-10.66958";
};
};
location = {
lat = "53.41291";
lng = "-8.24389";
};
"location_type" = APPROXIMATE;
viewport = {
northeast = {
lat = "55.4351345";
lng = "-5.99471";
};
southwest = {
lat = "51.4199312";
lng = "-10.6694501";
};
};
};
"place_id" = "ChIJ-ydAXOS6WUgRCPTbzjQSfM8";
types = (
country,
political
);
}
);
status = OK; }
Your for loop is going over all of the address_components and assigning their values to your longName and shortName variables, thus when the loop finishes only the last retrieved values in the array will be stored. If you only want the first set then you probably want to do something like this:
if ( addressComponents.count > 0 ) {
NSDictionary *componentDict = addressComponents[0];
longName = componentDict[#"long_name"];
shortName = componentDict[#"short_name"];
}
//The address_components array contains many dictionaries,
//we loop through each dictionary and check the types array
for (NSDictionary *addressComponentDictionary in addressComponents) {
longName = addressComponentDictionary[#"long_name"];
shortName = addressComponentDictionary[#"short_name"];
}
as Larme said your problem is here, instead of longName and shortName.
Create 2 arrays:
NSMutableArray *longNameArray = [[NSMutableArray alloc] init]
NSMutableArray *shortNameArray = [[NSMutableArray alloc] init]
for (NSDictionary *addressComponentDictionary in addressComponents) {
[longNameArray addObject:addressComponentDictionary[#"long_name"]];
[shortNameArray addObject:addressComponentDictionary[#"short_name"]];
}
This will give you the full list of elements found in the request.
Update - Get only the first element
If you need only the first element, get the first item from array
//This check will ensure that the array is not empty
if (addressComponents.count > 0) {
NSDictionary *addressComponentDictionary = addressComponents[0];
longName = addressComponentDictionary[#"long_name"];
shortName = addressComponentDictionary[#"short_name"];
}

How to get Google Place Details value in iOs

I'm now got stuck that I cannot retrieve how to fetch value from below json of Google Place Detail API.
I want to get all data from "types" node.
{
"address_components" = (
{
"long_name" = "Bridge Street";
"short_name" = "Bridge St";
types = (
route
);
},
{
"long_name" = London;
"short_name" = London;
types = (
locality,
political
);
},
{
"long_name" = London;
"short_name" = London;
types = (
"postal_town"
);
},
{
"long_name" = "Greater London";
"short_name" = "Greater London";
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = "United Kingdom";
"short_name" = GB;
types = (
country,
political
);
},
{
"long_name" = "SW1A 2LW";
"short_name" = "SW1A 2LW";
types = (
"postal_code"
);
}
);
vicinity = London;
}
Why not integrate Google places API itself rather than parsing yourself.
It's simple and easy to retrieve places
here is the link
https://developers.google.com/places/ios-api/
You can use google places api. Use place id and use below code to get place details value.
-(id)getAddressFromPlaceId:(NSString*)placeId
{
NSString *placeRequest;
if ([AppDelegate getInstance].isDetailsLimitReached)
{
placeRequest = [[NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/details/json?placeid=%#&key=%#&language=en",placeId,[Utility getInstance].arrGooglkey[tempc]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
else
{
placeRequest = [[NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/details/json?placeid=%#&language=en",placeId] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:placeRequest]cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:20.0];
NSError *error;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
if (error)
{
return nil;
}
else
{
NSDictionary *resData = [NSJSONSerialization JSONObjectWithData:response options:0 error:&error];
if (error)
{
return nil;
}
else
{
if ([resData[#"status"] isEqualToString:#"OK"] || [[resData objectForKey:#"status"] isEqualToString:#"ZERO_RESULTS"]) {
return [resData[#"result"] mutableCopy];
}
else
{
if ([AppDelegate getInstance].isDetailsLimitReached)
{
return nil;
}
[AppDelegate getInstance].isDetailsLimitReached = TRUE;
return [self getAddressFromPlaceId:placeId];
}
}
}
return nil;
}

JSON that contains an array to NSString

How do I extract each address from the NSDictionary I instantiated (below), so I can assign to various NSString objects?
I have the following JSON:
{
"Address":[
{
"$":{
"ID":"0"
},
"Address2":[
"10 Smith RD"
],
"City":[
"Mapleville"
],
"State":[
"NJ"
],
"Zip5":[
"90210"
],
"Zip4":[
"764"
]
},
{
"$":{
"ID":"1"
},
"Address2":[
"32 Hog CT"
],
"City":[
"New York City"
],
"State":[
"NY"
],
"Zip5":[
"90210"
],
"Zip4":[
"1390"
]
}
]
}
cData (below) came from the JSON above.
I did the following to convert to a NSDictionary:
NSDictionary* dictionary2 = [NSJSONSerialization JSONObjectWithData:cData options:NSJSONReadingAllowFragments error:nil];
once I did a:
NSLog(#"%#", dictionary2);
output from NSLog:
{
Address = (
{
"$" = {
ID = 0;
};
Address2 = (
"10 Smith RD"
);
City = (
"Mapleville"
);
State = (
NJ
);
Zip4 = (
7642
);
Zip5 = (
90210
);
},
{
"$" = {
ID = 1;
};
Address2 = (
"32 Hog CT"
);
City = (
"New York City"
);
State = (
NY
);
Zip4 = (
1390
);
Zip5 = (
90210
);
}
);
}
Just follow the structure.
NSDictionary* dictionary2 = [NSJSONSerialization ...
NSArray *addresses = dictionary2[#"Address"];
for (NSDictionary *addressData in addresses) {
NSString *address2 = addressData[#"Address2"];
NSString *city = addressData[#"City"];
// and the rest as needed
}

Resources