I want to allow the users to search for a street name and have the results displayed in a UITableView. For the moment the region is not important, it can be from any region.
I could not find any relevant example in my searches and I don't know if I should use CLLocation or MKLocalSearch.
Based on docs, I should use MKLocalSearch:
Although local search and geocoding are similar, they support different use cases. Use geocoding when you want to convert between map coordinates and a structured address, such as an Address Book address. Use local search when you want to find a set of locations that match the user’s input.
But I have tried both methods and it gives me only 1 result (even-though there is an NSArray returned.
This is the CLGeocoder approach:
CLGeocoder *geocoding = [[CLGeocoder alloc] init];
[geocoding geocodeAddressString:theTextField.text completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSLog(@"%i", [placemarks count]);
for(CLPlacemark *myStr in placemarks) {
NSLog(@"%@", myStr);
}
}
}];
And this is my MKLocalSearch try:
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = theTextField.text;
request.region = self.region;
localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error){
if (error != nil) {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Map Error",nil)
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK",nil) otherButtonTitles:nil] show];
return;
}
if ([response.mapItems count] == 0) {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"No Results",nil)
message:nil
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK",nil) otherButtonTitles:nil] show];
return;
}
self.streets = response;
[self.streetsTableView reloadData];
}];
MKLocalSearch seems to return more than 1 response in some cases, but these are related to places not street names searches.
Thanks in advance.
This is the closest I could get. This involves using google places API Web Service.
Note: You could probably use their Google Maps API, etc. I am sure there are other ways to get this information from the various Google APIs.
NSURL *googlePlacesURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%@&location=%f,%f&sensor=true&key=API_KEY", formattedSearchText, location.coordinate.latitude,
location.coordinate.longitude]];
The response is a JSON object. Convert it to a dictionary.
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:_googlePlacesResponse
options:NSJSONReadingMutableContainers error:&error];
if([[response objectForKey:@"status"] isEqualToString:@"OK"])
{
NSArray *predictions = [response objectForKey:@"predictions"];
for(NSDictionary *prediction in predictions)
{
NSArray *addressTypes = [prediction objectForKey:@"types"];
if([addressTypes containsObject:@"route"])
{
//This search result contains a street name.
//Now get the street name.
NSArray *terms = [prediction objectForKey:@"terms"];
NSDictionary *streetNameKeyValuePair = [terms objectAtIndex:0];
NSLog(@"%@",[streetNameKeyValuePair objectForKey@"value"]);
}
}
}
The possible types
seem to be
You could populate the table view with those predictions
that ONLY contain route
as an address type. This could work.