Showing nearby restaurants in MKMap View

12,575

In iOS 6.1, you can use MKLocalSearch, part of the standard iOS MapKit.framework:

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

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) {
        CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithPlacemark:item.placemark];

        annotation.title = item.name;
        annotation.subtitle = item.placemark.addressDictionary[(NSString *)kABPersonAddressStreetKey];
        annotation.phone = item.phoneNumber;

        [annotations addObject:annotation];
    }];

    [self.mapView addAnnotations:annotations];
}];

My custom annotation is just a MKPlacemark plus a title and subtitle:

@interface CustomAnnotation : MKPlacemark

@property (strong, nonatomic) NSString *title;
@property (strong, nonatomic) NSString *subtitle;
@property (strong, nonatomic) NSString *phone;

@end

If you want to see the disclosure indicator on your callout (so you can transition to another controller to view the details, you can:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (![annotation isKindOfClass:[CustomAnnotation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                       reuseIdentifier:@"CustomAnnotationView"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    return annotationView;
}

If you want to open your other view when the user clicks on the callout accessory:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    if (![view.annotation isKindOfClass:[CustomAnnotation class]])
        return;
    CustomAnnotation *annotation = (CustomAnnotation *)view.annotation;

    ABRecordRef person = ABPersonCreate();
    ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFStringRef) annotation.title, NULL);

    if (annotation.phone)
    {
        ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
        ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFStringRef) annotation.phone, kABPersonPhoneMainLabel, NULL);
        ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
        CFRelease(phoneNumberMultiValue);
    }

    ABMutableMultiValueRef address = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
    ABMultiValueAddValueAndLabel(address, (__bridge CFDictionaryRef) annotation.addressDictionary, kABWorkLabel, NULL);
    ABRecordSetValue(person, kABPersonAddressProperty, address, NULL);
    ABUnknownPersonViewController *personView = [[ABUnknownPersonViewController alloc] init];

    personView.unknownPersonViewDelegate = self;
    personView.displayedPerson = person;
    personView.allowsAddingToAddressBook = YES;

    [self.navigationController pushViewController:personView animated:YES];

    CFRelease(address);
    CFRelease(person);
}

- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person
{

}

For more information (e.g. customizing the annotation views, determining device location, etc.), refer to the Location Awareness Programming Guide.

See https://github.com/robertmryan/MKMapView-custom-annotations for a simple example.

Share:
12,575
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    In my iphone app,I have to show near by restaurants in Map View,Currently I am using Google map url in a web view.

    But how can I show nearby restaurants with in 5000 meters of current location with native MKMap view(I found out my current location-lat&long)

    I would like to learn how to implement as in the below screen shot(by clicking the annotations going to its detail too)

    Any helps ?? thanks in advance

    enter image description here

  • Paras Joshi
    Paras Joshi about 11 years
    you most wel-come :) just create MyAnnotation class or something which you want to display with other parameters..
  • Admin
    Admin about 11 years
    but...What is ASIFormDataRequest??
  • Paras Joshi
    Paras Joshi about 11 years
    oh i use ASIHTTPRequest for send request and get data from api .. just add ASIHTTPRequest and add .h file in your current class's .m file , its a class which used for send request to server and get data back...
  • Admin
    Admin about 11 years
    Thanks it worked...:) I can pass the title to the detail page as below,how to pass the subtitle ? Please see this question stackoverflow.com/questions/14954240/…
  • Rob
    Rob about 11 years
    @NithinMK You'd pass it in the same way you'd pass the title. Personally, I think it's just easier to pass the annotation itself, that way the detail page can just access all of the properties of the annotation. If you're still having problems, post a new question with your code to create the annotation as well as your code to launch the details page and we can help you further. Feel free to add a link to the new question here so that I can see it when you post it.