Bagaimana Anda mendapatkan kembali nama kota pengguna saat ini?
Bagaimana Anda mendapatkan kembali nama kota pengguna saat ini?
Jawaban:
Yang harus Anda lakukan adalah menyiapkan a CLLocationManager
yang akan menemukan koordinat Anda saat ini. Dengan koordinat saat ini yang perlu Anda gunakan MKReverseGeoCoder
untuk menemukan lokasi Anda.
- (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);
}
Sejak iOS 5 MKReverseGeoCoder
Tidak Berlaku Lagi!
Jadi Anda ingin menggunakan CLGeocoder
dengan CLLocationManager
sangat sederhana dan bekerja dengan blok.
Contoh:
- (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: Alih-alih for in
lingkaran Anda juga dapat melakukan:
NSString *locString = placemarks.count ? [placemarks.firstObject locality] : @"Not Found";
Ini berfungsi dengan baik untuk saya:
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
tahukah Anda mengapa?
Jika ada yang mencoba pindah ke CLGeocoder dari MKReverseGeocoder maka saya telah menulis posting blog yang mungkin bisa membantu http://jonathanfield.me/jons-blog/clgeocoder-example.html
Pada dasarnya contohnya adalah, setelah Anda membuat objek locationManager dan CLGeocoder cukup tambahkan kode ini ke viewDidLoad () Anda dan kemudian buat beberapa label atau area teks untuk menampilkan data.
[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
, dan pesan yang dikirim ke nil
hasil nil
, serta akses properti melalui notasi titik melalui nil
. Yang sedang berkata, seseorang harus selalu memeriksa apakah error
bukan- nil
.
Setelah Anda menyiapkan CLLocationManager, Anda akan mendapatkan pembaruan lokasi sebagai pasangan garis lintang / bujur. Kemudian Anda dapat menggunakan CLGeocoder untuk mengubah koordinat menjadi nama tempat yang ramah pengguna.
Berikut ini contoh kode di 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()
}
}
}
}
}
Jika ada yang membutuhkannya di Swift 3 , inilah cara saya melakukannya:
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!)"
}
}
}
Anda harus mendapatkan lokasi pengguna saat ini dan kemudian menggunakan MKReverseGeocoder untuk mengenali kota tersebut.
Ada contoh bagus di Panduan Pemrograman Aplikasi iPhone , bab 8. Setelah Anda mendapatkan lokasi inisialisasi geocoder, setel delegasi dan baca negara dari tanda letak. Baca dokumentasi untuk MKReverseGeocodeDelegate dan buat metode:
reverseGeocoder: didFailWithError:
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geocoder.delegate = self;
[geocoder start];
Anda dapat menggunakan kode ini untuk mendapatkan Kota Saat Ini: -
ekstensi YourController: CLLocationManagerDelegate {func locationManager (manager: CLLocationManager, didUpdateLocations locations: [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
}
}
Ini adalah kelas Swift kecil saya yang membantu saya mendapatkan informasi geocode terbalik tentang lokasi saat ini. Jangan lupa tentang NSLocationWhenInUseUsageDescription
field in 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);
}];
}
Baca dokumentasi untuk MKReverseGeocoder - dokumentasi, panduan & contoh aplikasi disediakan oleh Apple karena suatu alasan.