How to obtain a MKPlacemark Address for a callout

4.4k Views Asked by At

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];
            }
        }
    }];
}
2

There are 2 best solutions below

0
AudioBubble On BEST ANSWER

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.

0
SphynxTech On

You can find the address like this:

        geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
        var placemark:CLPlacemark!

        if error == nil && placemarks!.count > 0 {
            placemark = placemarks![0] as CLPlacemark


            var addressString : String = ""
            if placemark.ISOcountryCode == "TW" /*Address Format in Chinese*/ {
                if placemark.country != nil {
                    addressString = placemark.country!
                }
                if placemark.subAdministrativeArea != nil {
                    addressString = addressString + placemark.subAdministrativeArea! + ", "
                }
                if placemark.postalCode != nil {
                    addressString = addressString + placemark.postalCode! + " "
                }
                if placemark.locality != nil {
                    addressString = addressString + placemark.locality!
                }
                if placemark.thoroughfare != nil {
                    addressString = addressString + placemark.thoroughfare!
                }
                if placemark.subThoroughfare != nil {
                    addressString = addressString + placemark.subThoroughfare!
                }
            } else {
                if placemark.subThoroughfare != nil {
                    addressString = placemark.subThoroughfare! + " "
                }
                if placemark.thoroughfare != nil {
                    addressString = addressString + placemark.thoroughfare! + ", "
                }
                if placemark.postalCode != nil {
                    addressString = addressString + placemark.postalCode! + " "
                }
                if placemark.locality != nil {
                    addressString = addressString + placemark.locality! + ", "
                }
                if placemark.administrativeArea != nil {
                    addressString = addressString + placemark.administrativeArea! + " "
                }
                if placemark.country != nil {
                    addressString = addressString + placemark.country!
                }

                print (placemark.postalCode)

                let new_placemark: MKPlacemark = MKPlacemark (placemark: placemark)

            print(placemark.description)    

            }


        }
    })