How to retrieve user's current city name?

Solution 1:

As of iOS 5 MKReverseGeoCoder is Deprecated!

So you want to use CLGeocoder with CLLocationManager, very simple and works with block.

Example:

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
   [self.locationManager stopUpdatingLocation];

   CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
    [geoCoder reverseGeocodeLocation:newLocation
                   completionHandler:^(NSArray *placemarks, NSError *error) {
                       for (CLPlacemark *placemark in placemarks) {
                           .... = [placemark locality];
                       }
                   }];
}

Edit: Instead of a for in loop you can also do:

NSString *locString = placemarks.count ? [placemarks.firstObject locality] : @"Not Found";

Solution 2:

What you have to do is setup a CLLocationManager that will find your current coordinates. With the current coordinates you need to use MKReverseGeoCoder to find your location.

- (void)viewDidLoad 
{  
    // this creates the CCLocationManager that will find your current location
    CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    [locationManager startUpdatingLocation];
}

// this delegate is called when the app successfully finds your current location
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{
    // this creates a MKReverseGeocoder to find a placemark using the found coordinates
    MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
    geoCoder.delegate = self;
    [geoCoder start];
}

// this delegate method is called if an error occurs in locating your current location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{
 NSLog(@"locationManager:%@ didFailWithError:%@", manager, error);
}

// this delegate is called when the reverseGeocoder finds a placemark
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
    MKPlacemark * myPlacemark = placemark;
    // with the placemark you can now retrieve the city name
    NSString *city = [myPlacemark.addressDictionary objectForKey:(NSString*) kABPersonAddressCityKey];
}

// this delegate is called when the reversegeocoder fails to find a placemark
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
    NSLog(@"reverseGeocoder:%@ didFailWithError:%@", geocoder, error);
}

Solution 3:

This is working fine for me :

CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
[geocoder reverseGeocodeLocation:self.locationManager.location
               completionHandler:^(NSArray *placemarks, NSError *error) {
                   NSLog(@"reverseGeocodeLocation:completionHandler: Completion Handler called!");

                   if (error){
                       NSLog(@"Geocode failed with error: %@", error);
                       return;

                   }


                   CLPlacemark *placemark = [placemarks objectAtIndex:0];

                   NSLog(@"placemark.ISOcountryCode %@",placemark.ISOcountryCode);
                   NSLog(@"placemark.country %@",placemark.country);
                   NSLog(@"placemark.postalCode %@",placemark.postalCode);
                   NSLog(@"placemark.administrativeArea %@",placemark.administrativeArea);
                   NSLog(@"placemark.locality %@",placemark.locality);
                   NSLog(@"placemark.subLocality %@",placemark.subLocality);
                   NSLog(@"placemark.subThoroughfare %@",placemark.subThoroughfare);

               }];