Is it possible to use MKLocalSearch to find all nearby businesses? - ios

In order to avoid the API limits of foursquare or one of the other local search providers, I would like to use MKLocalSearch from iOS 6.1. The following code:
MKLocalSearchRequest *localSearchRequest = [[MKLocalSearchRequest alloc] init];
MKCoordinateRegion localSearchRegion = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake([theLocationChange.latitude floatValue], [theLocationChange.longitude floatValue]), 500.0f, 500.0f);
localSearchRequest.naturalLanguageQuery = #"restaurants";
localSearchRequest.region = localSearchRegion;
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:localSearchRequest];
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error)
{
if (error)
{
NSLog([error localizedDescription]);
}
for (MKMapItem* mapItem in response.mapItems)
{
NSLog(#"mapitem name is: %#",mapItem.name);
}
}];
will correctly fetch and display restaurants near the specified location. If I change localSearchRequest.naturalLanguageQuery to "hotels", it will fetch and display hotels. The same applies for "hospitals", "bars", etc. If, however, I try an empty string, or " ", "*", or "?" for localSearchRequest.naturalLanguageQuery, it returns no results.
If I use the foursquare API and send it a location, I can easily get back a list of venues that includes local businesses of all types. Is there a way to use MKLocalSearch to return all venues or local businesses?

Apple documentation says that localSearchRequest.naturalLanguageQuery to be considered as natural Language query which means, you can type in anything and get the related results to your query. But Apples Maps database may not be returning the values as you expect.

Related

MKLocalSearch not working like Apple Maps search?

I have created a MapKit and trying to play around with MKLocalSearch. One thing I noticed in comparison to Apple Maps, is that mklocalsearch is restricted to 10 results. So how does Apple Maps display 15 suggestions under the search bar?
Okay, on to an example. Im trying to find "Barcelona." In Apple Maps it will be suggested after writing just "barc" and it will stay on the suggestion list throughout typing barcelona.
Now in my own Map view, I actually have to type in the full Barcelona to get the suggestion: Spain, Barcelona. On my way I get other suggestions, but nothing like Spain, Barcelona and not like Apple maps.
Any insight on how to get it working and to why Apple Maps work differently (spec. the 15 results vs 10 with mklocalseach)
Here is the code called on textField Changes:
- (IBAction)searchFieldChanged:(UITextField *)sender {
if(self.locationTextfield.text.length>0)
self.tableView.hidden = NO;
else
self.tableView.hidden = YES;
NSString *query = self.locationTextfield.text;
// Create and initialize a search request object.
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = query;
request.region = self.mapsView.region;//we dont want region-specific search results!
//request.region = MKCoordinateRegionMakeWithDistance(self.mapsView.userLocation.location.coordinate,40000000, 15000000);
// Create and initialize a search object.
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
// Start the search and display the results as annotations on the map.
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error)
{
[placeMarks removeAllObjects];
NSLog(#"p-count: %lu", response.mapItems.count);
for (MKMapItem *item in response.mapItems) {
[placeMarks addObject:item.placemark];
self.tempPlacemark = item.placemark;
NSLog(#"placemark: %#", item.placemark);//.location.coordinate.latitude);
}
//if(placemarks.count==0)
// appDelegate.staticPlacemark = nil;
//[self.mapsView removeAnnotations:[self.mapsView annotations]];
//[self.mapsView showAnnotations:placemarks animated:NO];
[self.tableView reloadData];
}];
}
What you do is a MKLocalSearch using a MKLocalSearchRequest. What Apple in its macOS and iOS map apps does is using the newer MKLocalSearchCompleter class to obtain autocompletion suggestions. These suggestions are used for realtime search and displayed in a UITableView. When the user selects one entry that suggestion is used to initialize a MKLocalSearchRequest to obtain detailled information about this location.

MKLocalSearch returning results outside of region

I'm using Apple Maps to get a list of addresses in the local area. However, it seems to be returning results from all over the world, rather than the map region I am specifying.
I am using the following code, and have checked the region to make sure it is 'broadly' the whole of London (see attachment) for mapView with the same parameters. However in my results I sometimes have locations in Germany, USA or South America.
Anyone can see what I'm doing wrong?
MKLocalSearchRequest* request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchTerm;
CLLocationCoordinate2D cornerCoordinate = CLLocationCoordinate2DMake(51.5007282, -0.1246263);
request.region = MKCoordinateRegionMakeWithDistance(cornerCoordinate, 50000, 50000);
MKLocalSearch* search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
//results come in here
}];
Map region:
According to the documentation:
Specifying a region does not guarantee that the results will all be
inside the region. It is merely a hint to the search engine.
It's bummer, but there's unfortunately no way to limit the results just to the provided region.
You may consider use a Google Places API for that: https://developers.google.com/places/webservice/autocomplete
Try this solution. Here I think issue is because of the region you specified.
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchTerm;
MKCoordinateSpan span = MKCoordinateSpanMake(.1, .1);
CLLocationCoordinate2D cornerCoordinate = CLLocationCoordinate2DMake(51.5007282, -0.1246263);
request.region = MKCoordinateRegionMake(cornerCoordinate, span);
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
}];

CLLocation, geocoder and region search

I have problem with narrowing the Geocoder result. Here is my code:
CLLocationCoordinate2D centerLocation = CLLocationCoordinate2DMake(53, 10);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter: centerLocation radius:100 identifier:#"de"];
[self.geocoder geocodeAddressString:[NSString stringWithFormat:#"%#%#",textField.text,string] inRegion:region
completionHandler:^(NSArray* placemarks, NSError* error){
//filling the tableView code
}];
From apple docs:
"Specifying a region lets you prioritize the returned set of results
to locations that are close to some specific geographical area"
But if i start tapping the nearest street name i get results from all over the world but not the street i want. I need to put entire street name in the field to get in in placemarks array. How can I get nearest-first result from geocoder?
EDIT:
I don't know if address is a street, postcode, city name or place name. The bahavior is similar to Map app where there is only one textfield to search in all places.
"if i start tapping the nearest street name"
It looks like to me you’re doing a search based on user-entered query. You should use MKLocalSearch from Map Kit to perform searches for locations that a user can describe by name, address or type. Geocoding is used to convert map coordinates to a structured address or vice versa.
To quote the documentation:
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.
For example:
MKLocalSearchRequest *request = [MKLocalSearchRequest new];
request.naturalLanguageQuery = #"saint";
request.region = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(48.850354, 2.337341), 500, 500);
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
for (MKMapItem *item in response.mapItems) {
NSLog(#"item.placemark.name = %#", item.placemark.name);
}
}];
And I would get the following results which are correct based on the region i specified:
item.placemark.name = Eglise Saint Sulpice
item.placemark.name = J'Go Saint Germain
item.placemark.name = Terrazza Saint Germain
item.placemark.name = Hôtel Odéon Saint Germain
item.placemark.name = Le Bon Saint Pourcain
item.placemark.name = Hotel Le Relais Saint Germain
item.placemark.name = Piscine Saint Germain
item.placemark.name = Bistrot de la Grille Saint Germain
item.placemark.name = Esprit Saint Germain
item.placemark.name = Hôtel Relais Saint Sulpice
Then, you're free to do anything you want with the results you get.

google search places autocomplete specific to country in ios

I am working on Google Places AutoComplete Service where i need to filter the places specific to country and found this.
It is working good untill when i pass a parameter components=country:se to filter the autocomplete field its response is REQUEST_DENIED
NSMutableString *url = [NSMutableString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%#&components=country:se&sensor=%#&key=%#",
[input stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
SPBooleanStringForBool(sensor), key];
I need the autocomplete to give suggestion specific to country.
Thanks
This works fine for me.
You can set this by adding the bounds for the region by adding its extreme top left and bottom right location points of the the Geographical area.
like for USA i used.
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:CLLocationCoordinate2DMake(52.00, 148.00)
coordinate:CLLocationCoordinate2DMake(18.00, -71.00)];
GMSPlacesClient * placesClient = [[GMSPlacesClient alloc] init];
[placesClient autocompleteQuery:fieldValue bounds:bounds filter:nil
callback:^(NSArray *results, NSError *error)
{
if (error != nil)
{
NSLog(#"Autocomplete error %#", [error localizedDescription]);
return;
}
else
{
[self.autoComplete removeAllObjects];
[self.AddressPlaceID removeAllObjects];
for (GMSAutocompletePrediction* result in results)
{
CustomAddress * parseAddress = [[CustomAddress alloc] init];
NSString * adString = [parseAddress removeCountryFromAddress:result.attributedFullText.string];
[self.autoComplete addObject:adString];
[self.AddressPlaceID addObject:result.placeID];
}
[self.autoCompleteTable reloadData];
}
}];
But you can still get the other location results . It will prefer first the geographical bounds you define in the GMCoordinateBounds
Why do not use the iOS SDK to obtain country specific results? Follow this answer.

Map Location names in drop down list

My App Has to integrate search location names using text box. Is Map kit has any method to implement this kind of a functionality ? This below image displays what i exactly need
No , there is not any method of MapKit to implement this type of property..
For That You have to implement Your own Code, i.e. use of UISearchbarCantroller or Simple UISearchbar.
For Search results you can use Google Place Autocomplete api.
You can Use this GooglePlacesAutocomplete Example.
In
iOS >= 6.1 provides MKLocalSearch, MKLocalSearchRequest to search for natural language points of interest. Sample
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.region = regionToSearchIn;
request.naturalLanguageQuery = #"restaurants"; // or business name
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
// do something with the results / error
}];

Resources