1

Basically I need a way to put annotation on all the "Walmarts" that search request picks up. I am not using interface builder, I am just using code for this app.

MKMapView * map = [[MKMapView alloc] initWithFrame:
                   CGRectMake(0, 0, 320, 480)];
map.delegate = self;
[self.view addSubview:map];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.



MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = @"Walmart";
request.region = map.region;
Nirav Bhatt
  • 6,940
  • 5
  • 45
  • 89
moomoo
  • 77
  • 7
  • Your initialization also needs altering - follow what XCode comments say - all mapview initialization must happen after [super viewDidLoad]. – Nirav Bhatt Apr 15 '13 at 18:57
  • @moomoo - FYI, I've updated my answer for a refinement if working on slow network, whereby it cancels a prior search (if any still in progress) before initiating a new one. – Rob Apr 15 '13 at 21:10

2 Answers2

1

I'd suggest simply creating the mapview in viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];

    MKMapView * map = [[MKMapView alloc] initWithFrame:self.view.bounds];
    map.delegate = self;

    [self.view addSubview:map];
}

But when the user moves the map, look for Walmarts and add the annotations:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    // if on slow network, it's useful to keep track of the previous
    // search, and cancel it if it still exists

    [self.previousSearch cancel];

    // create new search request

    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
    request.naturalLanguageQuery = @"Walmart";
    request.region = mapView.region;

    // initiate new search

    MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
    [localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {

        NSMutableArray *annotations = [NSMutableArray array];

        [response.mapItems enumerateObjectsUsingBlock:^(MKMapItem *item, NSUInteger idx, BOOL *stop) {

            // if we already have an annotation for this MKMapItem,
            // just return because you don't have to add it again

            for (id<MKAnnotation>annotation in mapView.annotations)
            {
                if (annotation.coordinate.latitude == item.placemark.coordinate.latitude &&
                    annotation.coordinate.longitude == item.placemark.coordinate.longitude)
                {
                    return;
                }
            }

            // otherwise, add it to our list of new annotations
            // ideally, I'd suggest a custom annotation or MKPinAnnotation, but I want to keep this example simple

            [annotations addObject:item.placemark];
        }];

        [mapView addAnnotations:annotations];
    }];

    // update our "previous" search, so we can cancel it if necessary

    self.previousSearch = localSearch;
}

Clearly, this code sample assumes that you have a weak property for the previous search operation. (This is not, strictly speaking, necessary, but may give you better performance if browsing around on a map when you have a slow Internet connection.) Anyway, that property would be defined as follows:

@property (nonatomic, weak) MKLocalSearch *previousSearch;

There are other possible refinements (e.g. UIActivityIndicatorView or network activity indicator if search is in progress, perhaps remove annotations that are not within the map's current region, etc.), but hopefully you get the idea.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

Here is the approach:

MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[self.localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {

if(error)
{
        NSLog(@"localSearch startWithCompletionHandlerFailed!  Error: %@", error);
        return;
} 
else 
{
        for(MKMapItem *mapItem in response.mapItems)
        {
             MKPinAnnotation *annotation = [[MKPinAnnotation alloc] initWithCoordinate: mapItem.placemark.location.coordinate];
             [map addAnnotation:annotation];
             NSLog(@"Name for result: = %@", mapItem.name);
        }
}}];
Nirav Bhatt
  • 6,940
  • 5
  • 45
  • 89