How to get formatted address NSString from AddressDictionary in iOS9? - ios

Since ABCreateStringWithAddressDictionary is deprecated in iOS9, what other option is it to get address string from CLGeocoder?

This is my solution:
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in
if error != nil {
print("Error: \(error?.localizedDescription)")
}
if let myMarks = placemarks {
if let placemark = myMarks.last {
if let addressLine = (placemark.addressDictionary?["FormattedAddressLines"] as? [String]) {
self.addressLabel.text = addressLine.joined(separator: ", ")
}
}
}
})
El Key "FormattedAddressLines" return an array with this order: Name, Street, City, State, ZIP, Country. if you print addressLine, you'll see something like this: "Apple Inc., 1 Infinite Loop, Cupertino, CA 95014, United States".

Related

forward geocoding completionHandler is not executing in iOS swift4

I am trying convert to addresses into latlongs to place them on googleMap but, when I pass the address String to geoCoder.geoAddressString(fullAddress) and running application, completionHandler is not executing, I tried with breakpoint at geoCoder.geocodeAddressString(fullAddress) { (placemarks, error) and when I click on stepover it is coming out if the completionHandler..
Now, I have no idea why this is happening... Does anyone know? please Help..
see My code Here:
func loadMarkers() {
for i in 0..<self.professioanlDetailsAH.count {
let fullAddress = "\(self.professioanlDetailsAH[i]["searchAddress"]!)"
if !fullAddress.isEmpty {
var geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(fullAddress) { (placemarks, error) in
guard
let placemarks = placemarks,
let addressLocation = placemarks.first?.location
else {
// handle no location found
return
}
let latitude = addressLocation.coordinate.latitude
let longitude = addressLocation.coordinate.longitude
}
}
}
}
Edit:
func loadMarkers() {
for i in 0..<self.professioanlDetailsAH.count {
print(self.professioanlDetailsAH[i]["firstName"]!)
let fullAddress = "\(self.professioanlDetailsAH[i]["searchAddress"]!)"
print(fullAddress)
if !fullAddress.isEmpty {
geoCoder.geocodeAddressString(fullAddress) {(placemarks, error) in
if error != nil {
print(error!)
}
else{
guard
let placemarks = placemarks,
let addressLocation = placemarks.first?.location
else {return}
let latitude = addressLocation.coordinate.latitude
let longitude = addressLocation.coordinate.longitude
print("lat:\(latitude), long:\(longitude)")
}
}
}
}

Unable to get city name by current latitude and longitude in swift

I'm trying to get city name from my current location coordiate by using CLGeocoder().reverseGeocodeLocation.
It gives me country name, street name, state and many other things but not city. Is there anything wrong with my code?
Here's my code:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
CLGeocoder().reverseGeocodeLocation(location) { (placeMark, error) in
if error != nil{
print("Some errors: \(String(describing: error?.localizedDescription))")
}else{
if let place = placeMark?[0]{
print("country: \(place.administrativeArea)")
self.lblCurrentLocation.text = place.administrativeArea
}
}
} }
I use the below code too. But doesn't work for me. Here's the another way.
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: (self.locationManager.location?.coordinate.latitude)!, longitude: (self.locationManager.location?.coordinate.longitude)!)
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark!
placeMark = placemarks?[0]
// Address dictionary
print(placeMark.addressDictionary as Any)
// Location name
if let locationName = placeMark.addressDictionary!["Name"] as? NSString {
print("locationName: \(locationName)")
}
// Street address
if let street = placeMark.addressDictionary!["Thoroughfare"] as? NSString {
print("street: \(street)")
}
// City
if let city = placeMark.addressDictionary!["City"] as? NSString {
print("city : \(city)")
}
// Zip code
if let zip = placeMark.addressDictionary!["ZIP"] as? NSString {
print("zip :\(zip)")
}
// Country
if let country = placeMark.addressDictionary!["Country"] as? NSString {
print("country :\(country)")
}
})
Please someone help me to get city name.
The field is called locality
if let locality = placeMark.addressDictionary!["locality"] as? NSString {
print("locality :\(locality)")
}
Locality Apple docs
https://developer.apple.com/documentation/corelocation/clplacemark/1423507-locality?language=objc
CLPlacemark
https://developer.apple.com/documentation/corelocation/clplacemark?language=objc
Update:
Try this
import Foundation
import CoreLocation
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: 40.730610, longitude: -73.935242) // <- New York
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, _) -> Void in
placemarks?.forEach { (placemark) in
if let city = placemark.locality { print(city) } // Prints "New York"
}
})

Convert address to coordinates swift

How can I convert a String address to CLLocation coordinates with Swift?
I have no code yet; I looked for a solution but couldn't find any.
Use CLGeocoder to reverse geocode the address into latitude/longitude coordinates:
let address = "1 Infinite Loop, Cupertino, CA 95014"
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { (placemarks, error) in
guard
let placemarks = placemarks,
let location = placemarks.first?.location
else {
// handle no location found
return
}
// Use your location
}
You will also need to add and import CoreLocation framework.
You can use CLGeocoder, you can convert address(string) to coordinate and you vice versa, try this:
import CoreLocation
var geocoder = CLGeocoder()
geocoder.geocodeAddressString("your address") {
placemarks, error in
let placemark = placemarks?.first
let lat = placemark?.location?.coordinate.latitude
let lon = placemark?.location?.coordinate.longitude
print("Lat: \(lat), Lon: \(lon)")
}
Here's what I came up with to return a CLLocationCoordinat2D object:
func getLocation(from address: String, completion: #escaping (_ location: CLLocationCoordinate2D?)-> Void) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { (placemarks, error) in
guard let placemarks = placemarks,
let location = placemarks.first?.location?.coordinate else {
completion(nil)
return
}
completion(location)
}
}
So let's say I've got this address:
let address = "Springfield, Illinois"
Usage
getLocation(from: address) { location in
print("Location is", location.debugDescription)
// Location is Optional(__C.CLLocationCoordinate2D(latitude: 39.799372, longitude: -89.644458))
}
Swift 5 and Swift 5.1
import CoreLocation
var geocoder = CLGeocoder()
geocoder.geocodeAddressString("your address") { placemarks, error in
let placemark = placemarks?.first
let lat = placemark?.location?.coordinate.latitude
let lon = placemark?.location?.coordinate.longitude
print("Lat: \(lat), Lon: \(lon)")
}
This works
let geocoder = CLGeocoder()
let address = "8787 Snouffer School Rd, Montgomery Village, MD 20879"
geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in
if((error) != nil){
print("Error", error ?? "")
}
if let placemark = placemarks?.first {
let coordinates:CLLocationCoordinate2D = placemark.location!.coordinate
print("Lat: \(coordinates.latitude) -- Long: \(coordinates.longitude)")
}
})
The CLLocationManager object reports locations as a latitude/longitude pair. While these values uniquely represent any location on the planet, they are not values that users immediately associate with the location. Users are more familiar with names that describe a location, such as street names or city names. The CLGeocoder class lets you convert between geographic coordinates and the user-friendly names associated with that location. You can convert from either a latitude/longitude pair to a user friendly place name, or the other way around.
func getCoordinate( addressString : String,
completionHandler: #escaping(CLLocationCoordinate2D, NSError?) -> Void ) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(addressString) { (placemarks, error) in
if error == nil {
if let placemark = placemarks?[0] {
let location = placemark.location!
completionHandler(location.coordinate, nil)
return
}
}
completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
}
}

zipcode/postcode to latitude and longitude coordinates

How does one convert a zip, or in my case a postal code(UK) to lat long coordinates?
I read upon using google geocoding api but read that is has a fair amount of restrictions such as using google maps in the application and limit to requests.
I also found this but I'm not to sure how to go about implementing it
You would want to use the GeocodeAddressDictionary which accepts a dictionary of specific address types.
In your case, you would do the following.
let geocoder = CLGeocoder()
let dic = [NSTextCheckingZIPKey: yourZipCode]
geocoder.geocodeAddressDictionary(dic) { (placemark, error) in
if((error) != nil){
print(error!)
}
if let placemark = placemark?.first {
let lat = placemark.location!.coordinate.latitude
let long = placemark.location!.coordinate.longitude
}
}
With this code you can do it providing the address (Will be more accurate because a zip code is not a concrete coordinate but an address it is).
Remember to import CoreLocation at the top of the class.
let address = "1 Infinite Loop, CA, USA"
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in
if((error) != nil){
print("Error", error)
}
if let placemark = placemarks?.first {
let coordinates:CLLocationCoordinate2D = placemark.location!.coordinate
}
})

'[CLPlacemark]?' is not convertible to '[CLPlacemark]' -> swift2

this is a part of code I found on StackOverflow.
It was working in Swift 1.2
Why this code is not working anymore in swift 2:
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
let placeArray = placemarks as [CLPlacemark] // !!! ERROR HERE !!!
// Place details
var placeMark: CLPlacemark!
placeMark = placeArray[0]
// Address dictionary
print(placeMark.addressDictionary)
// Location name
if let locationName = placeMark.addressDictionary["Name"] as? NSString {
print(locationName)
}
// Street address
if let street = placeMark.addressDictionary["Thoroughfare"] as? NSString {
print(street)
}
// City
if let city = placeMark.addressDictionary["City"] as? NSString {
print(city)
}
// Zip code
if let zip = placeMark.addressDictionary["ZIP"] as? NSString {
print(zip)
}
// Country
if let country = placeMark.addressDictionary["Country"] as? NSString {
print(country)
}
})
Error is GetLocationViewController.swift:67:41: '[CLPlacemark]?' is not convertible to '[CLPlacemark]'
Looks like you need to unwrap the placemarks array (implicitly or optional chaining) before assigning it to a type of [CLPlacemarks]
For your example, you should use optional chaining so
if let validPlacemark = placemarks?[0]{
let placemark = validPlacemark as? CLPlacemark;
}
Than place all your logic inside the braces so if it finds a valid placemark array, it will execute your desired commands. If not, it will do nothing or you can handle it however you please
placemarks is not guaranteed to have a value, you could do this:
let placeArray: [CLPlacemark] = placemarks as? [CLPlacemark] ?? []
Which reads as,
if placemarks can be casted as [CLPlacemark], then do so. Otherwise, assign an empty array.
Here's this code in practice:
I'm realizing now that you're on Xcode 7! It's even easier there, all you need is this:
let placeArray = placemarks ?? []
In Xcode 7.0, Objective-C has generic arrays, so your placemarks array is no longer [AnyObject]? but is now [CLLocation]?. You don't need to cast the array, you can just unwrap the optional. With the addition of guard statements, your completion block is now as simple as:
geocoder.reverseGeocodeLocation(location) { placemarks, error in
guard let placemarks = placemarks else { print(error); return; }
guard let placemark = placemarks.first else { return; }
// ...
}
if let pm = placemarks?[0]{
// Example: get the country
print("Your country: \(pm.country!)")
}

Resources