Что вам нужно сделать, так это настроить, CLLocationManager
который будет определять ваши текущие координаты. С текущими координатами вам нужно использовать, MKReverseGeoCoder
чтобы найти свое местоположение.
- (void)viewDidLoad
{
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geoCoder.delegate = self;
[geoCoder start];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"locationManager:%@ didFailWithError:%@", manager, error);
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
MKPlacemark * myPlacemark = placemark;
NSString *city = [myPlacemark.addressDictionary objectForKey:(NSString*) kABPersonAddressCityKey];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
NSLog(@"reverseGeocoder:%@ didFailWithError:%@", geocoder, error);
}
Начиная с iOS 5
MKReverseGeoCoder
не рекомендуется!Таким образом , вы хотите использовать
CLGeocoder
сCLLocationManager
очень простой и работает с блоком.Пример:
- (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]; } }]; }
Изменить: вместо
for in
цикла вы также можете:NSString *locString = placemarks.count ? [placemarks.firstObject locality] : @"Not Found";
источник
Это отлично работает для меня:
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); }];
источник
kCLErrorDomain error 8
, знаете почему?Если кто-то пытается перейти на CLGeocoder с MKReverseGeocoder, я написал сообщение в блоге, которое может помочь http://jonathanfield.me/jons-blog/clgeocoder-example.html
В основном примером может быть, после того как вы создали объекты locationManager и CLGeocoder, просто добавьте этот код в свой viewDidLoad (), а затем создайте несколько меток или текстовых областей для отображения данных.
[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; }];
источник
nil
, и сообщения, отправленные вnil
результатеnil
, а также доступ к свойствам через точечную нотацию черезnil
. При этом всегда следует проверять, неerror
является ли онnil
.После настройки CLLocationManager вы получите обновление местоположения в виде пары широта / долгота. Затем вы можете использовать CLGeocoder для преобразования координат в удобное для пользователя название места.
Вот пример кода в 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() } } } } }
источник
Если кому-то это нужно в Swift 3 , вот как я это сделал:
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!)" } } }
источник
Вы должны получить текущее местоположение пользователя, а затем использовать MKReverseGeocoder для распознавания города.
В Руководстве по программированию приложений для iPhone , глава 8, есть отличный пример. После того, как вы получили местоположение, инициализируйте геокодер, установите делегата и прочтите страну по метке. Прочтите документацию для MKReverseGeocodeDelegate и создайте методы:
reverseGeocoder: didFailWithError:
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; geocoder.delegate = self; [geocoder start];
источник
Вы можете использовать этот код для получения текущего города: -
extension YourController: CLLocationManagerDelegate {func locationManager (manager: CLLocationManager, didUpdateLocations местоположения: [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 } }
источник
Вот мой небольшой класс Swift, который помогает мне получать обратную геокодированную информацию о текущем местоположении. Не забывайте про
NSLocationWhenInUseUsageDescription
полеInfo.plist
.class CurrentPlacemarkUpdater: NSObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() private let geocoder = CLGeocoder() private(set) var latestPlacemark: CLPlacemark? var onLatestPlacemarkUpdate: (() -> ())? var shouldStopOnUpdate: Bool = true func start() { locationManager.requestWhenInUseAuthorization() locationManager.desiredAccuracy = kCLLocationAccuracyKilometer locationManager.delegate = self locationManager.startUpdatingLocation() } func stop() { locationManager.stopUpdatingLocation() } fileprivate func updatePlacemark(for location: CLLocation) { geocoder.reverseGeocodeLocation(location) { [weak self] placemarks, error in if let placemark = placemarks?.first { self?.latestPlacemark = placemark self?.onLatestPlacemarkUpdate?() if self?.shouldStopOnUpdate ?? false { self?.stop() } } } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.last { updatePlacemark(for: location) } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("CurrentPlacemarkUpdater: \(error)") } }
источник
// 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); }]; }
источник
Прочтите документацию по MKReverseGeocoder - документация, руководства и примеры приложений не зря предоставляются Apple.
источник