¿Cómo recuperar el nombre actual de la ciudad del usuario?

¿Cómo recuperas el nombre actual de la ciudad del usuario?

Lo que tienes que hacer es configurar un CLLocationManager que encuentre tus coordenadas actuales. Con las coordenadas actuales, necesita usar MKReverseGeoCoder para encontrar su ubicación.

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

A partir de iOS 5 MKReverseGeoCoder está en MKReverseGeoCoder !

Entonces, quiere usar CLGeocoder con CLLocationManager , muy simple y funciona con bloque.

Ejemplo:

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

Editar: en lugar de un bucle for in , también puedes hacer:

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

Esto está funcionando bien para mí:

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

Si alguien está intentando pasar a CLGeocoder desde MKReverseGeocoder, he escrito una publicación en el blog que podría ser de ayuda http://jonathanfield.me/jons-blog/clgeocoder-example.html

Básicamente, un ejemplo sería, después de haber creado los objetos de locationManager y CLGeocoder, simplemente agregue este código a su viewDidLoad () y luego haga algunas tags o áreas de texto para mostrar los datos.

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

Si alguien lo necesita en Swift 3 , así es como lo hice:

 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.first! let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 500, 500) self.location = location self.locationManager?.stopUpdatingLocation() // Drop a pin at user's Current Location let myAnnotation: MKPointAnnotation = CustomPointAnnotation() myAnnotation.coordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude) myAnnotation.title = "Localização" self.mapViewMK.addAnnotation(myAnnotation) self.mapViewMK.setRegion(coordinateRegion, animated: true) self.locationManager?.stopUpdatingLocation() self.locationManager = nil // Get user's current location name let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(self.location!) { (placemarksArray, error) in if (placemarksArray?.count)! > 0 { let placemark = placemarksArray?.first let number = placemark!.subThoroughfare let bairro = placemark!.subLocality let street = placemark!.thoroughfare self.addressLabel.text = "\(street!), \(number!) - \(bairro!)" } } } 

Debes obtener la ubicación actual del usuario y luego usar MKReverseGeocoder para reconocer la ciudad.

Hay un gran ejemplo en la Guía de progtwigción de aplicaciones para iPhone , capítulo 8. Una vez que tenga la ubicación inicialice el geocodificador, configure el delegado y lea el país desde la marca de posición. Lea la documentación de MKReverseGeocodeDelegate y cree métodos:

  • reverseGeocoder: didFindPlacemark:
  • reverseGeocoder: didFailWithError:

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

Puede usar este código para obtener la Ciudad actual: –

extensión YourController: CLLocationManagerDelegate {func locationManager (manager: CLLocationManager, didUpdateLocations ubicaciones: [CLLocation]) {

  CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in if (error != nil) { manager.stopUpdatingLocation() return } else { if placemarks!.count > 0 { let placeMarksArrray: NSArray = placemarks! let pm = placeMarksArrray[0] as! CLPlacemark self.displayLocationInfo(pm) manager.stopUpdatingLocation() } else { print("Problem with the data received from geocoder") } } }) } func displayLocationInfo(placemark: CLPlacemark!) { if (placemark != nil) { //stop updating location to save battery life locationLocation.stopUpdatingLocation() var tempString : String = "" if(placemark.locality != nil){ tempString = tempString + placemark.locality! + " " print(placemark.locality) } if(placemark.postalCode != nil){ tempString = tempString + placemark.postalCode! + " " print(placemark.postalCode) } if(placemark.administrativeArea != nil){ tempString = tempString + placemark.administrativeArea! + " " print(placemark.administrativeArea) } if(placemark.country != nil){ tempString = tempString + placemark.country! + " " } let dictForaddress = placemark.addressDictionary as! NSDictionary if let city = dictForaddress["City"] { print(city) } strLocation = tempString } } 
 // place the function code below in desire location in program. // [self getCurrentLocation]; -(void)getCurrentLocation { 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.locality %@",placemark.locality ); 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); }]; } 

Después de configurar CLLocationManager, obtendría la actualización de la ubicación como un par de latitud / longitud. Entonces podrías usar CLGeocoder para convertir las coordenadas a un nombre de lugar fácil de usar.

Aquí está el código de muestra en Swift 4 .

 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let lastLocation = locations.last { let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(lastLocation) { [weak self] (placemarks, error) in if error == nil { if let firstLocation = placemarks?[0], let cityName = firstLocation.locality { // get the city name self?.locationManager.stopUpdatingLocation() } } } } } 

Lea la documentación de MKReverseGeocoder : la documentación, las guías y las aplicaciones de muestra son proporcionadas por Apple por algún motivo.