Search code examples
objective-cios8mapkitmkmapitemmkplacemark

How to obtain a MKPlacemark Address for a callout


I'm trying to figure out how to get the street address for an MKPlacemark item. I print an item out in console and I can see the information's there, but I'm only getting the thoroughfare info without the street address number.

Here's my code:

- (void)performSearch {
    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc]init];
    request.naturalLanguageQuery = _searchText.text;
    request.region = _mapView.region;

    _matchingItems = [[NSMutableArray alloc]init];

    MKLocalSearch *search = [[MKLocalSearch alloc]initWithRequest:request];
    NSLog(@"MKLocalSearch array created");

    [search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
        if (response.mapItems.count == 0) {
            NSLog(@"No Matches Found");
        } else {
            for (MKMapItem *item in response.mapItems) {
                [_matchingItems addObject:item];
                MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
                annotation.coordinate = item.placemark.coordinate;

                // Pull out address info from MKMapItem
                MKPlacemark *placemark = item.placemark;
                NSLog(@"Placemark info: %@", item.placemark);
                // Address details
                NSDictionary *address = placemark.addressDictionary;
                NSString *titleString = @"";
                NSString *subtitleString = @"";
                NSString *name = @"";
                NSString *thoroughfare = @"";
                NSString *state = @"";
                NSString *city = @"";
                NSString *country = @"";

                name = [address objectForKey:@"Name"] ? [address objectForKey:@"Name"] : @"";
                thoroughfare = [address objectForKey:@"Thoroughfare"] ? [address objectForKey:@"Thoroughfare"] : @"";
                state = [address objectForKey:@"State"] ? [address objectForKey:@"State"] : @"";
                city = [address objectForKey:@"City"] ? [address objectForKey:@"City"] : @"";
                country = [address objectForKey:@"Country"] ? [address objectForKey:@"Country"] : @"";

                titleString = [NSString stringWithFormat:@"%@ %@", name, thoroughfare];
                subtitleString = [NSString stringWithFormat:@"%@ %@ %@ %@", thoroughfare, state, city, country];

                // Strings for annotation
                annotation.title = item.name;
                annotation.subtitle = subtitleString;

                [_mapView addAnnotation:annotation];
            }
        }
    }];
}

Solution

  • MKPlacemark is a subclass of CLPlacemark.

    CLPlacemark has convenient properties defined for each address element so you don't have to access the dictionary directly by key names. (If you must access the dictionary directly, try using the pre-defined ABPerson Address Property key name constants documented here.)

    Using the convenient property accessor, Street number should be in placemark.subThoroughfare.

    But note that not all address elements are guaranteed to be set depending on the accuracy of the coordinates given and the country.