Open Apple Maps programmatically - ios

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

Related

How to send apple maps link containing an annotation?

My objective is to convert an address into an Apple Maps link and share it with UIActivityViewController, and when it is clicked, it opens Apple Maps and displays an annotation with the address, along with the "directions" button at the bottom, etc. Pretty much make it seem link someone searched for that address. I am able to convert the address, and share the link. Additionally, when the link is clicked, Apple Maps opens, and is centred on my desired location. However, I am unable to create the annotation and include it in the link. I have attempted to make an annotation with the correct coordinates, but have no clue how to add it to the link. To make things less complicated, I removed the annotation code, but here is what I have so far.
func activityItems(latitude: Double, longitude: Double) -> [AnyObject]? {
//this function does most of the work, creating the link and returning it
var items = [AnyObject]()
let URLString = "https://maps.apple.com?ll=\(latitude),\(longitude)"
if let url = NSURL(string: URLString) {
items.append(url)
}
let locationVCardString = [
"BEGIN:VCARD",
"VERSION:3.0",
"PRODID:-//Joseph Duffy//Blog Post Example//EN",
"N:;Shared Location;;;",
"FN:Shared Location",
"item1.URL;type=pref:\(URLString)",
"item1.X-ABLabel:map url",
"END:VCARD"
].joined(separator: "\n")
guard let vCardData : NSSecureCoding = locationVCardString.data(using: .utf8) as NSSecureCoding? else {
return nil
}
let vCardActivity = NSItemProvider(item: vCardData, typeIdentifier: "kUTTypeVCard" as String)
let annotation = MKPointAnnotation()
annotation.coordinate.latitude = latitude
annotation.coordinate.longitude = longitude
items.append(vCardActivity)
items.append(annotation)
return items
}
#IBAction func sendAddress(_ sender: UIButton) {
//this is the IBAction func, from the button tap. it uses the other function to present the activityViewController.
let address = self.donation.object(forKey: "Address") as! String
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { placemarks, error in
if let error = error{
print(error.localizedDescription)
return
}
if let placemarks = placemarks{
if let location = placemarks[0].location{
let lat = location.coordinate.latitude
let long = location.coordinate.longitude
if let shareObject = self.activityItems(latitude: lat, longitude: long) {
// making activity view controller
let textToShare = [ shareObject.first, shareObject.last ]
let activityViewController = UIActivityViewController(activityItems: textToShare as [Any], applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// present
self.present(activityViewController, animated: true, completion: nil)
}
}
}
}
}

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.

How to open Google Maps to show route using Swift

I read around the Internet but couldn't find a legit answer. I need to open Google Maps when the user clicks a button to show directions. Start and destination must be automatically filled.
How can I achieve this in Swift?
If anyone has a solution, please provide me with a sample code. The start is always going to be the user's current location.
OK I found the answer myself.
If you want to show directions from the user's current location, leave the field saddr blank and in the field daddr you can enter the destination coordinates.
This is how I did it
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?saddr=&daddr=\(place.latitude),\(place.longitude)&directionsmode=driving")!)
} else {
NSLog("Can't use comgooglemaps://");
}
}
for any further queries you can refer to this link Google Map URL Scheme
Swift 5 - Code
func openGoogleMap() {
guard let lat = booking?.booking?.pickup_lat, let latDouble = Double(lat) else {Toast.show(message: StringMessages.CurrentLocNotRight);return }
guard let long = booking?.booking?.pickup_long, let longDouble = Double(long) else {Toast.show(message: StringMessages.CurrentLocNotRight);return }
if (UIApplication.shared.canOpenURL(URL(string:"comgooglemaps://")!)) { //if phone has an app
if let url = URL(string: "comgooglemaps-x-callback://?saddr=&daddr=\(latDouble),\(longDouble)&directionsmode=driving") {
UIApplication.shared.open(url, options: [:])
}}
else {
//Open in browser
if let urlDestination = URL.init(string: "https://www.google.co.in/maps/dir/?saddr=&daddr=\(latDouble),\(longDouble)&directionsmode=driving") {
UIApplication.shared.open(urlDestination)
}
}
}
Don't forget to write this in info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>comgooglemaps</string>
<string>comgooglemaps-x-callback</string>
</array>
The Answer is already there but in older versions of Swift
In Swift 3
//Working in Swift new versions.
if (UIApplication.shared.canOpenURL(URL(string:"comgooglemaps://")!))
{
UIApplication.shared.openURL(NSURL(string:
"comgooglemaps://?saddr=&daddr=\(Float(latitude!)),\(Float(longitude!))&directionsmode=driving")! as URL)
} else
{
NSLog("Can't use com.google.maps://");
}
For those that the solution for the accepted answer didn't work for them, remember to add comgooglemaps to LSApplicationQueriesSchemes in the info.plist.
#IBAction func NavigationTrackerPressedPressed(_ sender: UIButton){
if let UrlNavigation = URL.init(string: "comgooglemaps://") {
if UIApplication.shared.canOpenURL(UrlNavigation){
if self.destinationLocation?.longitude != nil && self.destinationLocation?.latitude != nil {
let lat = (self.destinationLocation?.latitude)!
let longi = (self.destinationLocation?.longitude)!
if let urlDestination = URL.init(string: "comgooglemaps://?saddr=&daddr=\(lat),\(longi)&directionsmode=driving") {
UIApplication.shared.openURL(urlDestination)
}
}
}
else {
NSLog("Can't use comgooglemaps://");
self.openTrackerInBrowser()
}
}
else
{
NSLog("Can't use comgooglemaps://");
self.openTrackerInBrowser()
}
}
func openTrackerInBrowser(){
if self.destinationLocation?.longitude != nil && self.destinationLocation?.latitude != nil {
let lat = (self.destinationLocation?.latitude)!
let longi = (self.destinationLocation?.longitude)!
if let urlDestination = URL.init(string: "https://www.google.co.in/maps/dir/?saddr=&daddr=\(lat),\(longi)&directionsmode=driving") {
UIApplication.shared.openURL(urlDestination)
}
}
}
Here is the Swift 3 Update
First, you need to two items to LSApplicationQueriesSchemes in the info.plist.
Then you can use this function to load address on Google maps.
let primaryContactFullAddress = "No 28/A, Kadalana, Moratuwa, Sri Lanka"
#IBAction func showLocaionOnMaps(_ sender: Any) {
let testURL: NSURL = NSURL(string: "comgooglemaps-x-callback://")!
if UIApplication.shared.canOpenURL(testURL as URL) {
if let address = primaryContactFullAddress.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) {
let directionsRequest: String = "comgooglemaps-x-callback://" + "?daddr=\(address)" + "&x-success=sourceapp://?resume=true&x-source=AirApp"
let directionsURL: NSURL = NSURL(string: directionsRequest)!
let application:UIApplication = UIApplication.shared
if (application.canOpenURL(directionsURL as URL)) {
application.open(directionsURL as URL, options: [:], completionHandler: nil)
}
}
} else {
NSLog("Can't use comgooglemaps-x-callback:// on this device.")
}
}
Swift 4 Working Code
if let url = URL(string: "comgooglemaps://?saddr=&daddr=\(location.coordinate.latitude),\(location.coordinate.longitude)&directionsmode=driving") {
UIApplication.shared.open(url, options: [:])
}
this code works for me. And ı didn't insert
* LSApplicationQueriesSchemes
If you use emulator can't see the results. Don't forget work your project on the Phone.
1) Method: You can pass the only destination address current address will be automatically fetched by google map application.
let strLat : String = "23.035007"
let strLong : String = "72.529324"
override func viewDidLoad() {
super.viewDidLoad()
if (UIApplication.shared.canOpenURL(URL(string:"comgooglemaps://")!)) {
UIApplication.shared.openURL(URL(string:"comgooglemaps://?saddr=&daddr=\(strLat),\(strLong)&directionsmode=driving")!)
}
else {
print("Can't use comgooglemaps://");
}
}
2) You can pass both start and destination address
let strLat : String = "23.035007"
let strLong : String = "72.529324"
let strLat1 : String = "23.033331"
let strLong2 : String = "72.524510"
override func viewDidLoad() {
super.viewDidLoad()
if (UIApplication.shared.canOpenURL(URL(string:"comgooglemaps://")!)) {
UIApplication.shared.openURL(URL(string:"comgooglemaps://?saddr=\(strLat),\(strLong)&daddr=\(strLat1),\(strLong2)&directionsmode=driving&zoom=14&views=traffic")!)
}
else {
print("Can't use comgooglemaps://");
}
}
I want the possibility that the user can open Google Maps via browser (only works when user hasn't the Google Maps App)
Google gives a documentation for that here.
Since iOS 9 you have to set a scheme. This you will find here.
For me the google solution doesn't work. Maybe you are smarter and find a solution (please post!).
Anyway I made a simple web call:
let lat = 37.7
let lon = -122.4
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"https://maps.google.com")!))
{
UIApplication.sharedApplication().openURL(NSURL(string:
"https://maps.google.com/?q=#\(lat),\(lon)")!)
}
This could be use as a kind of fallback from sumeshs answer.
let lat = self.upcomingListArr[indexPath.item].latitude!
let long = self.upcomingListArr[indexPath.item].longitude!
if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")! as URL)) {
UIApplication.shared.openURL(NSURL(string:
"comgooglemaps://?saddr=&daddr=\(String(describing: lat)),\(String(describing: long))")! as URL)
} else {
UIApplication.shared.openURL(NSURL(string:
"https://www.google.co.in/maps/dir/?saddr=&daddr=\(String(describing: lat)),\(String(describing: long))")! as URL)
}
You can create small builder for URL, that will redirect you to GoogleMaps
/*
add to InfoPlist:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>comgooglemaps</string>
<string>comgooglemaps-x-callback</string>
</array>
*/
final public class GoogleMapsURIConstructor {
public enum NavigationType: String {
case driving
case transit
case walking
}
public class func prepareURIFor(latitude lat: Double,
longitude long: Double,
fromLatitude fromLat: Double? = nil,
fromLongitude fromLong: Double? = nil,
navigation navigateBy: NavigationType) -> URL? {
if let googleMapsRedirect = URL(string: "comgooglemaps://"),
UIApplication.shared.canOpenURL(googleMapsRedirect) {
if let fromLat = fromLat,
let fromLong = fromLong {
let urlDestination = URL(string: "comgooglemaps-x-callback://?saddr=\(fromLat),\(fromLong)?saddr=&daddr=\(lat),\(long)&directionsmode=\(navigateBy.rawValue)")
return urlDestination
} else {
let urlDestination = URL(string: "comgooglemaps-x-callback://?daddr=\(lat),\(long)&directionsmode=\(navigateBy.rawValue)")
return urlDestination
}
} else {
if let fromLat = fromLat,
let fromLong = fromLong {
let urlDestination = URL(string: "https://www.google.co.in/maps/dir/?saddr=\(fromLat),\(fromLong)&daddr=\(lat),\(long)&directionsmode=\(navigateBy.rawValue)")
return urlDestination
} else {
let urlDestination = URL(string: "https://www.google.co.in/maps/dir/?saddr=&daddr=\(lat),\(long)&directionsmode=\(navigateBy.rawValue)")
return urlDestination
}
}
}
}
usage:
let uri = GoogleMapsURIConstructor.prepareURIFor(latitude: lat,
longitude: long,
fromLatitude: userLatitude,
fromLongitude: userLongitude,
navigation: .driving)
UIApplication.shared.open(uri, options: [: ], completionHandler: nil)
result:
First off all, thank you guys for your answers beyond. But when I'm working around, I didn't find the working answer for me. And as result I've made working code with two cases: when user has the google maps app and if not.
Here is my version of code. Xcode 10, Swift 4.2. Hope it will help.
Step 1: Find your info.plist and Open As -> Source Code
Step 2: Add these lines between <dict> and </dict>
Step 3: In your action add this code. Don't forget to set your latitude and longitude.
let latitude = 44.987781
let longitude = 88.987781
let appDomen: String = "comgooglemaps://"
let browserDomen: String = "https://www.google.co.in/maps/dir/"
let directionBody: String = "?saddr=&daddr=\(latitude),\(longitude)&directionsmode=driving"
// Make route with google maps application
if let appUrl = URL(string: appDomen), UIApplication.shared.canOpenURL(appUrl) {
guard let appFullPathUrl = URL(string: appDomen + directionBody) else { return }
UIApplication.shared.openURL(appFullPathUrl)
// If user don't have an application make route in browser
} else if let browserUrl = URL(string: browserDomen), UIApplication.shared.canOpenURL(browserUrl) {
guard let browserFullPathUrl = URL(string: browserDomen + directionBody) else { return }
UIApplication.shared.openURL(browserFullPathUrl)
}
If google map app not installed, open with apple map version.
import Foundation
import CoreLocation
import UIKit
import MapKit
struct GoogleMapApp {
func openWithDirection(cordinate: CLLocationCoordinate2D, locationName: String) {
let hasGoogleMapApp = UIApplication.shared.canOpenURL(URL(string: "comgooglemaps://")!)
if hasGoogleMapApp {
let urlString = "comgooglemaps-x-callback://?saddr=&daddr=\(cordinate.latitude),\(cordinate.longitude)&directionsmode=driving"
if let url = URL(string: urlString) {
UIApplication.shared.open(url, options: [:])
}
} else {
// If google map not installed, open with Apple Map App
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: cordinate, addressDictionary: nil))
mapItem.name = locationName
mapItem.openInMaps(launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
}
}
}
// I hope it will work perfactly.
let googleURL = NSURL(string: "comgooglemaps://?q=")
if(UIApplication.shared.canOpenURL(googleURL! as URL)) {
UIApplication.shared.open(URL(string:"comgooglemaps://?saddr=\(DEVICE_LAT),\(DEVICE_LONG)&daddr=\(addressLat),\(addressLng)&directionsmode=driving")!, options: [:], completionHandler: nil)
}
//Also set permission from info.plist according to attached image.
enter image description here
We can use this method to open google maps. If google maps is not installed it will redirect to browser.
func redirectToGoogleMap(coordinates : String) {
if let url = URL(string: "comgooglemaps://?saddr=&daddr=\(coordinates)&directionsmode=driving"),
UIApplication.shared.canOpenURL(url) {
print("comgoogle maps worked")
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(url)
}
} else{
if let url = URL(string: "https://www.google.co.in/maps/dir/?saddr=&daddr=\(coordinates)&directionsmode=driving"),
UIApplication.shared.canOpenURL(url) {
print("google com maps worked")
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(url)
}
}else{
kSweetAlert.showAlert(CommonMethods.setLangText("oops"), subTitle: "Oops! Could not open google maps", style: AlertStyle.error)
}
}
}`
SWIFT 5.1 (WORKED FOR ME)
// Destination Address (Lat/Long)
let place = business?.businessAddresse
// Google URL
let stringURL = "comgooglemaps://"
// Checking Nil
if !(place?.latitude == nil) || !(place?.longitude == nil) {
if UIApplication.shared.canOpenURL(URL(string: stringURL)!) {
// If have Google Map App Installed
if let url = URL(string: "comgooglemaps://?saddr=&daddr=\(place?.latitude ?? 0.0),\(place?.longitude ?? 0.0)&directionsmode=driving") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
} else {
// If have no Google Map App (Run Browser Instead)
if let destinationURL = URL(string: "https://www.google.co.in/maps/dir/?saddr=&daddr=\(place?.latitude ?? 0.0),\(place?.longitude ?? 0.0)&directionsmode=driving") {
UIApplication.shared.open(destinationURL, options: [:], completionHandler: nil)
}
}
} else {
// Show Alert When No Location Found
self.delegate?.noDirectionError(title: "Error", message: "There's no direction available for this restaurant")
}
Note: This code only work on iOS Version 11 or Later, I hope this helps you guys too, cheer.
Here is the simple solution to choose navigation application between apple and google map(if installed, Otherwise system will navigate to default apple map).
Add this OpenMaps class in your project.
class OpenMaps {
// Presenting Action Sheet with Map Options Like Google And Apple Maps.
/// - Parameter coordinate: coordinate of destination
static func presentActionSheetwithMapOption(coordinate: CLLocationCoordinate2D) {
let latitude = coordinate.latitude
let longitude = coordinate.longitude
// Google MAP URL
let googleURL = "comgooglemaps://?daddr=\(latitude),\(longitude)&directionsmode=driving"
let googleItem = ("Google Maps", URL(string:googleURL)!)
// Apple MAP URL
let appleURL = "maps://?daddr=\(latitude),\(longitude)"
var installedNavigationApps = [("Apple Maps", URL(string:appleURL)!)]
if UIApplication.shared.canOpenURL(googleItem.1) {
installedNavigationApps.append(googleItem)
}
if installedNavigationApps.count == 1 {
if let app = installedNavigationApps.first {
self.openMap(app: app)
}
return
}
// If there are google map install in the device then System will ask choose map application between apple and google map.
let alert = UIAlertController(title: nil,
message: "Choose application",
preferredStyle: .actionSheet)
for app in installedNavigationApps {
let button = UIAlertAction(title: app.0,
style: .default, handler: { _ in
self.openMap(app: app)
})
alert.addAction(button)
}
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alert.addAction(cancel)
guard let vc = AlertViewManager.shared.getTopViewController() else {
debugPrint("Unable To open the action sheet for maps. Function: \(#function), Line: \(#line)")
return
}
vc.present(alert, animated: true)
}
// Open Selected Map
/// - Parameter app: Selected Map Application Details
private static func openMap(app: (String, URL)) {
guard UIApplication.shared.canOpenURL(app.1) else {
debugPrint("Unable to open the map.")
return
}
UIApplication.shared.open(app.1, options: [:], completionHandler: nil)
}
}
Usage:
let coordinate = CLLocationCoordinate2D(latitude: 30.7333,
longitude: 76.7794)
OpenMaps.presentActionSheetwithMapOption(coordinate: coordinate)
Using Swift 5 and XCode 13, I was able to use Google's Universal cross-platform syntax to open Google Maps app in directions mode.
The link will open the google maps app if it is installed on the phone. If maps is not installed it will open the url in the browser.
let url = "https://www.google.com/maps/dir/?api=1&destination=\(coords.latitude)%2C\(coords.longitude)"
guard let googleUrl = URL.init(string: url) else {
// handle error
return
}
UIApplication.shared.open(googleUrl)
In Swift 4:
if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")! as URL)) {
UIApplication.shared.open((NSURL(string:
"comgooglemaps://?saddr=&daddr=\(trashDictionarySorted[indexPath.section][0])&directionsmode=driving")! as URL), options: [:], completionHandler: nil)
} else {
NSLog("Can't use comgooglemaps://");
}
}
The Answer is already there but in older versions of Swift, And this code can open Google Map in browser if your iPhone did't install Google Map Application.
In Swift 4
import MapKit
func openGoogleDirectionMap(_ destinationLat: String, _ destinationLng: String) {
let LocationManager = CLLocationManager()
if let myLat = LocationManager.location?.coordinate.latitude, let myLng = LocationManager.location?.coordinate.longitude {
if let tempURL = URL(string: "comgooglemaps://?saddr=&daddr=\(destinationLat),\(destinationLng)&directionsmode=driving") {
UIApplication.shared.open(tempURL, options: [:], completionHandler: { (isSuccess) in
if !isSuccess {
if UIApplication.shared.canOpenURL(URL(string: "https://www.google.co.th/maps/dir///")!) {
UIApplication.shared.open(URL(string: "https://www.google.co.th/maps/dir/\(myLat),\(myLng)/\(destinationLat),\(destinationLng)/")!, options: [:], completionHandler: nil)
} else {
print("Can't open URL.")
}
}
})
} else {
print("Can't open GoogleMap Application.")
}
} else {
print("Prease allow permission.")
}
}
func openTrackerInBrowser(lat: String, long: String, dlat: String, dlong: String){
if let urlDestination = URL.init(string: "https://www.google.co.in/maps/dir/?saddr=\(lat),\(long)&daddr=\(dlat),\(dlong)&directionsmode=driving") {
UIApplication.shared.open(urlDestination, options: [:], completionHandler: nil)
}
}

Resources