Kullanıcının mevcut şehir adı nasıl alınır?


Yanıtlar:


107

Yapmanız gereken CLLocationManager, mevcut koordinatlarınızı bulacak bir a ayarlamaktır . Mevcut koordinatlarla MKReverseGeoCoderkonumunuzu bulmak için kullanmanız gerekir .

- (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
Bir not: Konum yöneticisini bir ivar'da saklamanız gerekir (ve belki bir konum aldıktan sonra onu tekrar durdurmanız gerekir), aksi takdirde anında otomatik olarak yayımlanır ve herhangi bir temsilci geri araması almazsınız. Ayrıca, ters coğrafi kodlayıcının çalışması için internet bağlantısı gerekir.
uliwitness

Pin üzerindeki Başlık ve Alt Yazıdaki Geçerli Şehir veya Konumun nasıl yazdırılacağını söyleyebilir misiniz ???
Raju

1
@Frade #import <AddressBook / AddressBook.h>
Jonathan

18
MKReverseGeoCoder, ios 5.0'dan beri kullanımdan kaldırıldı
adhg

Frade, keşke öğrendiklerini söyleyebilseydin ... ah
David

122

İOS 5 MKReverseGeoCoderitibariyle Kullanımdan Kaldırıldı!

Kullanmak istediğiniz Yani CLGeocoderile CLLocationManagerçok basit ve bloğun ile çalışır.

Misal:

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

Düzenleme: Bir for indöngü yerine şunları da yapabilirsiniz:

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

28

Bu benim için iyi çalışıyor:

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

               }];

Neden bir dizi döndürüyor? garip. Yine de teşekkürler.
Adam Waite

Bu kaygan, aşk blokları. Objectatindex: 0'ın gerçekten var olduğundan emin olmak için yer işaretleri dizisine bir koşul koyardım.
capikaw

4
Merhaba kCLErrorDomain error 8neden bir hata alıyorum biliyor musunuz?
maxisme

CLGeoCoder ne yapmam gerektiği açıklanmadı, bu yüzden neyi içe aktaracağım ve ne ekleyeceğim işe yarayabilir
iOS Developer

17

MKReverseGeocoder'dan CLGeocoder'a geçmeye çalışan biri varsa, o zaman yardımcı olabilecek bir blog yazısı yazdım http://jonathanfield.me/jons-blog/clgeocoder-example.html

Temel olarak bir örnek, locationManager ve CLGeocoder nesnelerini oluşturduktan sonra bu kodu viewDidLoad () öğenize ekleyin ve ardından verileri göstermek için bazı etiketler veya metin alanları yapın.

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



     }];

@macayer Evet, boş olsaydı çökebilirdi, ancak doğru anlarsam asla boş olmayacak. 1 veya daha fazla öğe içerecek veya olacak nilve nilsonuç için gönderilen mesajların nilyanı sıra noktalı gösterim yoluyla mülk erişimi nil. Varlık hep kontrol etmeleri gerektiğini söyledi errordışı olduğunu nil.
Victor Zamanian

4

CLLocationManager'ı kurduktan sonra, enlem / boylam çifti olarak konum güncellemesi alırsınız. Ardından, koordinatı kullanıcı dostu bir yer adına dönüştürmek için CLGeocoder'ı kullanabilirsiniz.

İşte Swift 4'teki örnek kod .

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

3

Swift 3'te buna ihtiyacı olan varsa , işte böyle yaptım:

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!)"
        }
    }
}

2

Kullanıcının mevcut konumunu almanız ve ardından şehri tanımak için MKReverseGeocoder'ı kullanmanız gerekir.

İPhone Uygulama Programlama Kılavuzu , bölüm 8'de harika bir örnek var. Konum bulduktan sonra coğrafi kodlayıcıyı başlatın, temsilciyi ayarlayın ve yer işaretinden ülkeyi okuyun. MKReverseGeocodeDelegate belgelerini okuyun ve yöntemler oluşturun:

  • reverseGeocoder: didFindPlacemark:
  • reverseGeocoder: didFailWithError:

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

1

Mevcut Şehri almak için bu kodu kullanabilirsiniz: -

extension YourController: CLLocationManagerDelegate {func locationManager (yönetici: CLLocationManager, didUpdateLocations konumları: [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
    }
}

1

İşte benim küçük Swift sınıfım şu anki konum hakkında ters coğrafi kodlamalı bilgi almamda bana yardımcı oluyor. NSLocationWhenInUseUsageDescriptionAlanı unutma 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)")
    }

}

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

                   }];
}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.