Returning address only in English from reverseGeocodeLocation - ios

My app is geolocation based app and each entry in tableview has location of the entry. The weird thing I found is that when users are from outside of US, the location is written in their language. For example, there was one user from Vietnam and the address was written in Vietnamese.
I'm using reverseGeocodeLocation like below to retrieve the address of an entry's location. Is there a way to get results only in English? I tried the code out there in other stackoverflow questions, but did not work.
And I am first getting geopoint using Parse. I do not need to do this way, but I just decided to do.
PFGeoPoint.geoPointForCurrentLocationInBackground {
(geoPoint: PFGeoPoint?, error: NSError?) -> Void in
var location = CLLocation(latitude: GlobalVariable.userLocation!.latitude, longitude: GlobalVariable.userLocation!.longitude)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription, terminator: "")
return}
if placemarks!.count > 0 {
let pm = placemarks![0] as CLPlacemark
GlobalVariable.detailedLocation = "\(pm.subLocality)," + " \(pm.locality)," + " \(pm.ISOcountryCode)" }

you can pass parameter "preferredLocale" to specific language
let locale = Locale(identifier: "en_US")
CLGeocoder().reverseGeocodeLocation(location, preferredLocale: locale, completionHandler: {(placemarks, error) in
})

Related

geocodePostalAddress - get Address from zip code

I'm trying to get the address from the postal code, but I'm getting the error and no placemarks. It seems the device cannot find the location. Why is this?
Locale doesn't matter, I tried with and without and the result is same.
let geocoder = CLGeocoder()
let postalAddress = CNMutablePostalAddress()
postalAddress.postalCode = zipCode
geocoder.geocodePostalAddress(postalAddress, preferredLocale: Locale(identifier: "en_US")) { (placemarks, err) in
if let placemark = placemarks?[0] {
completionHandler(placemark)
return
}
completionHandler(nil)
}
err = (Error?) domain: "kCLErrorDomain" - code: 8
I'm going to guess there's something wrong with your testing procedure or your device, because I can't reproduce the problem. I don't have a completion handler so I changed the code to this:
let geocoder = CLGeocoder()
let postalAddress = CNMutablePostalAddress()
postalAddress.postalCode = "93023"
geocoder.geocodePostalAddress(postalAddress, preferredLocale: Locale(identifier: "en_US")) { (placemarks, err) in
if let placemark = placemarks?[0] {
print(placemark)
return
}
print(err)
}
I got
93023, Ojai, CA 93023, United States...
which is correct. Maybe you've been hammering the geocoder so you got throttled? Or maybe there's some bad setting on your device? Or it could be something more subtle.
CLGeocoder also works for me, but if its not working for you try this MKLocalSearch Playground instead:
import UIKit
import MapKit
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = "93023"
let search = MKLocalSearch(request: searchRequest)
search.start { response, error in
guard let response = response else {
print(error?.localizedDescription ?? "This should be impossible")
return
}
print(response.mapItems.first?.placemark.title ?? "No Placemarks")
}
output:
Ojai, CA 93023, United States

finding distance of a Autocomplete resulted location from current location IOS

I m working on application like Uber and Careem. When user searches for a location using Google Places Autocomplete API, I want to show the distance as well along with the name of the autocomplete resulted place like Uber and Careem does this.
Plz have a look on this image for further clarification
Edit:
where cuGMS is array of GMSAutocompletePrediction
let cuGMS = self.resultsArray[indexPath.row]
let placesClient = GMSPlacesClient()
placesClient.lookUpPlaceID(cuGMS.placeID!, callback: { (response , error) in
print("response \(response)")
if(error == nil)
{
let coor = response?.coordinate
let lat = coor?.latitude
let lon = coor?.longitude
}
else
{
}
})
try this
let loc1:CLLocation = CLLocation.init(latitude: 30.0000, longitude:29.2545)
let loc2:CLLocation = CLLocation.init(latitude: 28.02002, longitude:27.00021)
let dis = loc1.distance(from: loc2)

Google geo coding keeps returning the city centre location for different places

I am using google auto complete(GMSAutocompletePrediction) to get the attributedFullText(result.attributedFullText.string), the chosen suggestions is used in the following code, which is the geocoding to get the latitude and longitude from the attributedFullText. For many different places the returned origin is the city centre of the city i am looking on.
Knowing that the language used is Arabic
if let correctedAddress = self.allAddresses[0][(indexPath as NSIndexPath).row].full.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
if let url = URL(string: "https://maps.googleapis.com/maps/api/geocode/json?address=\(correctedAddress)&sensor=false") {
print(correctedAddress)
print(self.allAddresses[0][(indexPath as NSIndexPath).row].full)
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
// 3
do {
if data != nil{
if let jsonObject = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:Any],
let results = jsonObject["results"] as? [[String:Any]], !results.isEmpty,
let geometry = results[0]["geometry"] as? [String:Any],
let location = geometry["location"] as? [String:Double],
let lat = location["lat"], let lng = location["lng"] {
print("\(lat) - \(lng)")
let newAddress = Address(name: self.allAddresses[0][(indexPath as NSIndexPath).row].name , detail: self.allAddresses[0][(indexPath as NSIndexPath).row].detail, latitude: String(lat), longitude: String(lng))
// go back to the previous view controller
self.delegate?.userDidChooseLocation(newAddress)
self.dismiss(animated: true, completion: nil)
}
}
}catch {
print("Error")
}
})
// 5
task.resume()
}
}
}
You'll be much better of using the Place ID:
https://developers.google.com/places/ios-api/reference/interface_g_m_s_autocomplete_prediction.html#a1c5f68fbd615425c3dcc5cb60b8b16c7
You can also query the Google Maps Geocoding API web service with the Place ID from Autocomplete:
https://maps.googleapis.com/maps/api/geocode/json?place_id=(placeId)&key=YOUR_API_KEY
Note that an API key is required for this kind of requests.
Also, the sensor parameter was retired long ago.

iOS 9 redirect to apple map from app

I am using swift 2.0, XCode 7.2 and deployment target is 9.2.
On button click I wish to redirect to apple maps to show a location. Following is my code which is not working:
var addr = self.sortedDict.valueForKey("ADDRESS1").objectAtIndex(cellIndexPath!.row).objectAtIndex(0) as! String + "," + (self.sortedDict.valueForKey("CITY").objectAtIndex(cellIndexPath!.row).objectAtIndex(0) as! String) + "," + (self.sortedDict.valueForKey("STATE").objectAtIndex(cellIndexPath!.row).objectAtIndex(0) as! String)
let strUrl: String = "http://maps.apple.com?address=" + addr
let url: NSURL = NSURL(string: strUrl.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!)!
if UIApplication.sharedApplication().canOpenURL(url) {
UIApplication.sharedApplication().openURL(url)
} else {
print(UIApplication.sharedApplication().canOpenURL(url))
}
Error I get is:
-canOpenURL: failed for URL: "http%3A%2F%2Fmaps.apple.com%3Faddress=4702%20Katy%20Hockley%20Cut%20Off%20Rd,Katy,TX" - error: "Invalid input URL"
false
In iOS 9 you must whitelist any URL schemes your App wants to query in Info.plist under the LSApplicationQueriesSchemes key.
What key should I specify for apple maps?
You can use MKMapItem to open apple map directly, instead of opening a URL
//your address to be opened
let address: String = "4702 Katy Hockley Cut Off Rd,Katy,TX"
let geocoder: CLGeocoder = CLGeocoder()
// Get place marks for the address to be opened
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
if (placemarks?.count > 0) {
if let placemark = placemarks?.first {
let mkPlacemark = MKPlacemark(placemark: placemark)
//Create map item and open in map app
let item = MKMapItem(placemark: mkPlacemark)
item.name = address
item.openInMapsWithLaunchOptions(nil)
}
}
})

Open Apple Maps programmatically

I want to open the Apple Maps App in my own Swift App, but I have only zipcode, city & street. I have NO Coordinates. I researched a lot, but there were only ways with using coordination information.
You can just pass your address information as URL parameters in the URL with which you open the maps app. Say you wanted the maps app to open centered on The White House.
UIApplication.sharedApplication().openURL(NSURL(string: "http://maps.apple.com/?address=1600,PennsylvaniaAve.,20500")!)
The Maps app opens with the ugly query string in the search field but it shows the right location. Note that the city and state are absent from the search query, it's just the street address and the zip.
A potentially better approach, depending on your needs, would be to get the CLLocation of the address info you have using CLGeocoder.
let geocoder = CLGeocoder()
let str = "1600 Pennsylvania Ave. 20500" // A string of the address info you already have
geocoder.geocodeAddressString(str) { (placemarksOptional, error) -> Void in
if let placemarks = placemarksOptional {
print("placemark| \(placemarks.first)")
if let location = placemarks.first?.location {
let query = "?ll=\(location.coordinate.latitude),\(location.coordinate.longitude)"
let path = "http://maps.apple.com/" + query
if let url = NSURL(string: path) {
UIApplication.sharedApplication().openURL(url)
} else {
// Could not construct url. Handle error.
}
} else {
// Could not get a location from the geocode request. Handle error.
}
} else {
// Didn't get any placemarks. Handle error.
}
}
Swift 4 and above
Use this version to get the coordinates for the Address, there is also a way to open it directly with the address, but that is susceptible to errors
import CoreLocation
let myAddress = "One,Apple+Park+Way,Cupertino,CA,95014,USA"
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(myAddress) { (placemarks, error) in
guard let placemarks = placemarks?.first else { return }
let location = placemarks.location?.coordinate ?? CLLocationCoordinate2D()
guard let url = URL(string:"http://maps.apple.com/?daddr=\(location.latitude),\(location.longitude)") else { return }
UIApplication.shared.open(url)
}
Apple has a Documentation about the Map URL Scheme. Look here: https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html#//apple_ref/doc/uid/TP40007899-CH5-SW1
Using Swift 4 and Xcode 9
At the top:
import CoreLocation
Then:
let geocoder = CLGeocoder()
let locationString = "London"
geocoder.geocodeAddressString(locationString) { (placemarks, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let location = placemarks?.first?.location {
let query = "?ll=\(location.coordinate.latitude),\(location.coordinate.longitude)"
let urlString = "http://maps.apple.com/".appending(query)
if let url = URL(string: urlString) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
}
Swift 5: Directly open maps app
///Opens text address in maps
static func openAddressInMap(address: String?){
guard let address = address else {return}
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { (placemarks, error) in
guard let placemarks = placemarks?.first else {
return
}
let location = placemarks.location?.coordinate
if let lat = location?.latitude, let lon = location?.longitude{
let destination = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lon)))
destination.name = address
MKMapItem.openMaps(
with: [destination]
)
}
}
}

Resources