Get the address of current user location

lavitanien picture lavitanien · Oct 21, 2011 · Viewed 11.2k times · Source

I follow some tutorial and mix my awful code. Now I can get my current location. And when I tap on a button it will trigger a pin which locates on my current location. If I tap on the pin, the message shows address of my current.

I have two question:

  1. Why I can not get a more precise address? Now I receive address with country, city and district, but without name of the road.

  2. How can I get the "text" of the address of current location? I want to display the address in a UILabel elsewhere but don't know how to do that.

Thank you very much!

here's the .h

#import <UIKit/UIKit.h>
#import "MapKit/MapKit.h"
#import "CoreLocation/CoreLocation.h"

@interface UserLocationAddressViewController : UIViewController     <MKMapViewDelegate,MKReverseGeocoderDelegate>
{
    MKMapView *userLocationAddMapView;
    CLLocationManager *locationManager;
}

@property (nonatomic, retain) MKMapView *userLocationAddMapView;

-(IBAction)getUserLocationAddress:(id)sender;

@end

And Here's .m

#import "UserLocationAddressViewController.h"

@implementation UserLocationAddressViewController

@synthesize userLocationAddMapView;

-(IBAction)getUserLocationAddress:(id)sender
{
    MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:locationManager.location.coordinate];
    geoCoder.delegate = self;
    [geoCoder start]; 
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(void)dealloc
{
    [userLocationAddMapView release];
    [super dealloc];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

self.userLocationAddMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    userLocationAddMapView.showsUserLocation = YES;
    userLocationAddMapView.delegate = self;
    self.userLocationAddMapView.mapType = MKMapTypeStandard;

    locationManager = [[CLLocationManager alloc] init];
    [locationManager startUpdatingLocation];
    CLLocationCoordinate2D coordinate = locationManager.location.coordinate;

    MKCoordinateRegion mapRegion;
    mapRegion.center = coordinate;
    MKCoordinateSpan mapSpan;
    mapSpan.latitudeDelta = 0.006;
    mapSpan.longitudeDelta = 0.006;
    mapRegion.span = mapSpan;
    [userLocationAddMapView setRegion:mapRegion animated:YES];
    self.userLocationAddMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.userLocationAddMapView];

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Get Add" style:UIBarButtonItemStylePlain target:self action:@selector(getUserLocationAddress:)] autorelease];  
}

-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
    NSLog(@"placemark %f %f", placemark.coordinate.latitude, placemark.coordinate.longitude);
    NSLog(@"addressDictionary %@", placemark.addressDictionary);
    [userLocationAddMapView addAnnotations:[NSArray arrayWithObjects:placemark, nil]];
    [geocoder release];
}

-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
    NSLog(@"reverseGeocoder fail");
    [geocoder release];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

Answer

bagwaa picture bagwaa · Oct 21, 2011

You shouldn't really use MKReverseGeocoder as it has been depreciated by apple in iOS5, you should really use CLGeocoder. The following example will return a whole tonne of information which is based in the NSArray *placemarks, you can then iterate through them and call the keys in the assoc array.

#import "MapPoint.h"

@implementation MapPoint
@synthesize coordinate, title, dateAdded, subtitle, city, reverseGeo;

-(id)initWithCoordinates:(CLLocationCoordinate2D)c 
                   title:(NSString *)t {

    self = [super init];
    if (self) {

        coordinate = c;
        [self setTitle: t];
        [self setCurrentCity: [[CLLocation alloc] initWithLatitude:c.latitude longitude:c.longitude]];

        [self setDateAdded: [[NSDate alloc] init]];

    }
    return self;

}

-(void)setCurrentCity: (CLLocation *)loc {

    if (!self.reverseGeo) {
        self.reverseGeo = [[CLGeocoder alloc] init];
    }

    [self.reverseGeo reverseGeocodeLocation: loc completionHandler: 
     ^(NSArray *placemarks, NSError *error) {

         for (CLPlacemark *placemark in placemarks) {

             NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
             [formatter setTimeStyle:NSDateFormatterNoStyle];
             [formatter setDateStyle:NSDateFormatterLongStyle];

             NSString *dateString = [formatter stringFromDate: [self dateAdded]];
             [self setSubtitle: [dateString stringByAppendingString: [placemark locality] ] ];             

         }
     }];
}

@end