I’m using MapKit to display a satellite map in one of my apps.  I create custom annotations – and it all works great.  However I wanted to be able to play sounds when a user touches one of my MKAnnotation’s on my MapKit MKMapView so that the sound matches the display of the callout (and when it disappears too).

There is no delegate method or other built-in mechanism for detecting when your annotation is selected, however it does have a selected property.  So how to detect when the MKAnnotation is selected and then play my sounds?  The answer is key/value observing.

Setup an observer on our imageAnnontationView:

// At the top of the .m file put:
static NSString* const GMAP_ANNOTATION_SELECTED = @"gMapAnnontationSelected";
// Then later somewhere in your code, add the observer
[imageAnnotationView addObserver:self
		 forKeyPath:@"selected"
		options:NSKeyValueObservingOptionNew
		context:GMAP_ANNOTATION_SELECTED];

Then we get a callback whenever the selected property of our annotation changes:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context{

    NSString *action = (NSString*)context;

    if([action isEqualToString:GMAP_ANNOTATION_SELECTED]){
      BOOL annotationAppeared = [[change valueForKey:@"new"] boolValue];
     // do something
   }
}

The value of annotationAppeared will change based on the state of the annontations selected property.  GMAP_ANOTATION_SELECTED is a constant string I set at the top of my file.

I’ve updated my post to make the GMAP_ANOTATION_SELECTED constant more obvious.  Hopefully this helps people use the snippet above.