90 votes

Comment récupérer le nom de la ville actuelle de l'utilisateur ?

Comment récupérer le nom de la ville actuelle de l'utilisateur ?

122voto

macayer Points 3104

À partir d'iOS 5 MKReverseGeoCoder est déprécié !

Vous voulez donc utiliser CLGeocoder avec CLLocationManager très simple et fonctionne avec le bloc.

Exemple :

- (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 : Au lieu d'un for in boucle que vous pouvez aussi faire :

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

107voto

tony.tc.leung Points 1757

Ce que vous devez faire est de mettre en place un CLLocationManager qui trouvera vos coordonnées actuelles. Avec les coordonnées actuelles, vous devez utiliser MKReverseGeoCoder pour trouver votre emplacement.

- (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);
}

9 votes

Une remarque : vous devez cacher le gestionnaire de localisation dans un ivar (et éventuellement l'arrêter à nouveau une fois que vous avez reçu une localisation), sinon il sera immédiatement libéré automatiquement et vous ne recevrez aucun rappel de délégué. De plus, le géocodeur inverse nécessite une connexion internet pour fonctionner.

0 votes

Pouvez-vous me dire comment imprimer la ville ou la localité actuelle dans le titre et le sous-titre d'une broche ?

1 votes

@Frade #import <AddressBook/AddressBook.h>

28voto

Gaurav aka sparsh Points 1169

Cela fonctionne bien pour moi :

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);

               }];

0 votes

Pourquoi renvoie-t-il un tableau ? étrange. Merci quand même.

0 votes

C'est génial, j'adore les blocs. Je mettrais une condition sur le tableau des points de repère pour m'assurer que l'objectatindex:0 existe réellement.

4 votes

Bonjour, je reçois une erreur kCLErrorDomain error 8 Vous savez pourquoi ?

17voto

Jonathan Field Points 223

Si quelqu'un essaie de passer de MKReverseGeocoder à CLGeocoder, j'ai écrit un article de blog qui pourrait vous être utile. http://jonathanfield.me/jons-blog/clgeocoder-example.html

Par exemple, après avoir créé les objets locationManager et CLGeocoder, ajoutez ce code à votre viewDidLoad(), puis créez des étiquettes ou des zones de texte pour afficher les données.

  [super viewDidLoad];
    locationManager.delegate = self;
    [locationManager startUpdatingLocation];

    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    [self.CLGeocoder reverseGeocodeLocation: locationManager.location completionHandler: 
     ^(NSArray *placemarks, NSError *error) {

         CLPlacemark *placemark = [placemarks objectAtIndex:0];

             isoCountryCode.text = placemark.ISOcountryCode;
             country.text = placemark.country;
             postalCode.text= placemark.postalCode;
             adminArea.text=placemark.administrativeArea;
             subAdminArea.text=placemark.subAdministrativeArea;
             locality.text=placemark.locality;
             subLocality.text=placemark.subLocality;
             thoroughfare.text=placemark.thoroughfare;
             subThoroughfare.text=placemark.subThoroughfare;
             //region.text=placemark.region;

     }];

0 votes

@macayer Oui, serait se bloque si elle est vide, mais ne sera jamais vide si je comprends bien. Il contiendra 1 ou plusieurs éléments ou sera nil et les messages envoyés à nil aboutir à nil ainsi que l'accès aux propriétés par la notation point via nil . Ceci étant dit, il faut toujours vérifier si error est non nil .

2voto

Marcin Zbijowski Points 471

Vous devez obtenir la position actuelle de l'utilisateur, puis utiliser MKReverseGeocoder pour reconnaître la ville.

Il y a un excellent exemple dans Guide de programmation des applications iPhone chapitre 8. Une fois l'emplacement obtenu, initialisez le géocodeur, définissez le délégué et lisez le pays à partir du repère. Lisez la documentation de MKReverseGeocodeDelegate et créez les méthodes :

  • reverseGeocoder:didFindPlacemark :
  • reverseGeocoder:didFailWithError :

    MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
    geocoder.delegate = self;
    [geocoder start];

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X