Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find city name and country from latitude and longitude in Swift

I'm working on application in Swift3 and I have letter problem i can't find the answer for it.

How can I know city name and country short names base on latitude and longitude?

import UIKit import CoreLocation  class ViewController: UIViewController, CLLocationManagerDelegate{     let locationManager = CLLocationManager()     var latitude: Double = 0     var longitude: Double = 0     override func viewDidLoad() {         super.viewDidLoad()         // For use when the app is open & in the background         locationManager.requestAlwaysAuthorization()         // For use when the app is open         //locationManager.requestWhenInUseAuthorization()         locationManager.delegate = self         locationManager.startUpdatingLocation()         if CLLocationManager.locationServicesEnabled() {             locationManager.delegate = self             locationManager.desiredAccuracy = kCLLocationAccuracyBest             locationManager.startUpdatingLocation()         }     }     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {         if let location = locations.first {             print(location.coordinate)             latitude = location.coordinate.latitude             longitude = location.coordinate.longitude         }     }     func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {         if (status == CLAuthorizationStatus.denied){             showLocationDisabledpopUp()         }     }     func showLocationDisabledpopUp() {         let alertController = UIAlertController(title: "Background Location Access  Disabled", message: "We need your location", preferredStyle: .alert)         let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)         alertController.addAction(cancelAction)         let openAction = UIAlertAction(title: "Open Setting", style: .default) { (action) in             if let url = URL(string: UIApplicationOpenSettingsURLString){                 UIApplication.shared.open(url, options: [:], completionHandler: nil)             }         }         alertController.addAction(openAction)         self.present(alertController, animated: true, completion: nil)     } } 
like image 836
joshua Avatar asked May 17 '17 17:05

joshua


People also ask

What is lat long number?

Latitude and longitude are a pair of numbers (coordinates) used to describe a position on the plane of a geographic coordinate system. The numbers are in decimal degrees format and range from -90 to 90 for latitude and -180 to 180 for longitude. For example, Washington DC has a latitude 38.8951 and longitude -77.0364 .


1 Answers

You can use CLGeocoder reverseGeocodeLocation method to fetch a CLPlacemark and get its country and locality properties info. Note that it is an asynchronous method so you will need to add a completion handler to your method when fetching that info:

import UIKit import MapKit import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true  extension CLLocation {     func fetchCityAndCountry(completion: @escaping (_ city: String?, _ country:  String?, _ error: Error?) -> ()) {         CLGeocoder().reverseGeocodeLocation(self) { completion($0?.first?.locality, $0?.first?.country, $1) }     } } 

Usage

let location = CLLocation(latitude: -22.963451, longitude: -43.198242) location.fetchCityAndCountry { city, country, error in     guard let city = city, let country = country, error == nil else { return }     print(city + ", " + country)  // Rio de Janeiro, Brazil } 

edit/update:

iOS 11 or later CLPlacemark has a postalAddress property. You can import Contacts framework and use CNPostalAddressFormatter's string(from:) method to get a localized formatted address. You can also extend CLPlacemark and add some computed properties to better describe some of its properties:

import MapKit import Contacts  extension CLPlacemark {     /// street name, eg. Infinite Loop     var streetName: String? { thoroughfare }     /// // eg. 1     var streetNumber: String? { subThoroughfare }     /// city, eg. Cupertino     var city: String? { locality }     /// neighborhood, common name, eg. Mission District     var neighborhood: String? { subLocality }     /// state, eg. CA     var state: String? { administrativeArea }     /// county, eg. Santa Clara     var county: String? { subAdministrativeArea }     /// zip code, eg. 95014     var zipCode: String? { postalCode }     /// postal address formatted     @available(iOS 11.0, *)     var postalAddressFormatted: String? {         guard let postalAddress = postalAddress else { return nil }         return CNPostalAddressFormatter().string(from: postalAddress)     } } 

extension CLLocation {     func placemark(completion: @escaping (_ placemark: CLPlacemark?, _ error: Error?) -> ()) {         CLGeocoder().reverseGeocodeLocation(self) { completion($0?.first, $1) }     } } 

Usage:

let location = CLLocation(latitude: 37.331676, longitude: -122.030189) location.placemark { placemark, error in     guard let placemark = placemark else {          print("Error:", error ?? "nil")         return     }     print(placemark.postalAddressFormatted ?? "") } 

This will print

1 Infinite Loop
Cupertino CA 95014
United States


like image 162
Leo Dabus Avatar answered Sep 23 '22 21:09

Leo Dabus