Musisz tylko ustawić CLLocationManager
, który znajdzie Twoje aktualne współrzędne. Z aktualnymi współrzędnymi, których musisz użyć, MKReverseGeoCoder
aby znaleźć swoją lokalizację.
- (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);
}
Od iOS 5
MKReverseGeoCoder
jest przestarzały!Więc chcesz używać
CLGeocoder
zCLLocationManager
, bardzo prostym i działającym z blokiem.Przykład:
- (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]; } }]; }
Edycja: zamiast
for in
pętli możesz też:NSString *locString = placemarks.count ? [placemarks.firstObject locality] : @"Not Found";
źródło
To działa dobrze dla mnie:
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); }];
źródło
kCLErrorDomain error 8
, czy wiesz dlaczego?Jeśli ktoś próbuje przejść na CLGeocoder z MKReverseGeocoder, to napisałem wpis na blogu, który może być pomocny http://jonathanfield.me/jons-blog/clgeocoder-example.html
Zasadniczo przykładem może być to, że po utworzeniu obiektów locationManager i CLGeocoder wystarczy dodać ten kod do swojej metody viewDidLoad (), a następnie utworzyć kilka etykiet lub obszarów tekstowych, aby pokazać dane.
[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; }];
źródło
nil
i wiadomości wysyłane w celunil
uzyskanianil
, a także dostęp do właściwości za pomocą notacji kropkowej za pośrednictwemnil
. Biorąc to pod uwagę, zawsze należy sprawdzić, czyerror
nie jestnil
.Po skonfigurowaniu CLLocationManager otrzymasz aktualizację lokalizacji jako parę szerokość / długość geograficzna. Następnie można użyć CLGeocoder do konwersji współrzędnych na przyjazną dla użytkownika nazwę miejsca.
Oto przykładowy kod w 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() } } } } }
źródło
Jeśli ktoś potrzebuje tego w Swift 3 , tak to zrobiłem:
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!)" } } }
źródło
Musisz uzyskać aktualną lokalizację użytkownika, a następnie użyć MKReverseGeocoder do rozpoznania miasta.
Świetny przykład znajduje się w Przewodniku programowania aplikacji na iPhone'a , rozdział 8. Gdy masz już lokalizację, zainicjuj geokodera, ustaw delegata i odczytaj kraj z oznaczenia miejsca. Przeczytaj dokumentację MKReverseGeocodeDelegate i utwórz metody:
reverseGeocoder: didFailWithError:
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; geocoder.delegate = self; [geocoder start];
źródło
Możesz użyć tego kodu, aby uzyskać aktualne miasto: -
rozszerzenie YourController: CLLocationManagerDelegate {func locationManager (manager: CLLocationManager, didUpdateLocations lokalizacje: [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 } }
źródło
Oto moja mała klasa Swift, która pomaga mi w uzyskaniu odwróconych geokodowanych informacji o bieżącej lokalizacji. Nie zapomnij o
NSLocationWhenInUseUsageDescription
polu wInfo.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)") } }
źródło
// 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); }]; }
źródło
Przeczytaj dokumentację MKReverseGeocoder - nie bez powodu dokumentacja, przewodniki i przykładowe aplikacje są dostarczane przez Apple.
źródło