sumesh
sumesh

Reputation: 2249

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.

Upvotes: 65

Views: 89559

Answers (22)

Chamod Hettiarachchi
Chamod Hettiarachchi

Reputation: 11

Here is a answer for Swift 4

First add two items to LSApplicationQueriesSchemes in the info.plist.

<key>LSApplicationQueriesSchemes</key>
        <array>
        <string>comgooglemaps</string>
        <string>comgooglemaps-x-callback</string>
        </array>

Then you can use the below code to open Google maps and show directions.

if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")! as URL)) {
  UIApplication.shared.open(NSURL(string:"comgooglemaps://?saddr=\(sLat),\(sLng)&daddr=\(self.venueLat!),\(self.venueLng!)&directionsmode=driving")! as URL)
  
} else {
  //            Open in browser
  let urlString = "https://www.google.com/maps/dir/?api=1&origin=\(sLat),\(sLng)&destination=\(self.venueLat!),\(self.venueLng!)&travelmode=driving"
  if let urlDestination = URL.init(string: urlString) {
      UIApplication.shared.open(urlDestination)
  }
}

here,

  • sLat - Starting position latitude
  • sLang - Starting position longitude
  • venueLat - Destination latitude
  • venueLng - Destination logitude

for more references - https://developers.google.com/maps/documentation/ios-sdk/urlscheme

Upvotes: 0

Mark
Mark

Reputation: 788

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)

Upvotes: 2

Pradeep Singh
Pradeep Singh

Reputation: 160

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) 

Upvotes: 1

kazuwombat
kazuwombat

Reputation: 1653

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

Upvotes: 3

Rattanakoudom Sambath
Rattanakoudom Sambath

Reputation: 514

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.

Upvotes: 1

hbk
hbk

Reputation: 11184

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:

enter image description here

Upvotes: 3

Kakumanu siva krishna
Kakumanu siva krishna

Reputation: 714

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

Upvotes: 1

Gurpreet Singh
Gurpreet Singh

Reputation: 953

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>

Upvotes: 49

samuel samer
samuel samer

Reputation: 311

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)

    }
}

Upvotes: 0

Saharat Sittipanya
Saharat Sittipanya

Reputation: 321

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.")

    }

}

Upvotes: 0

Erik Peruzzi
Erik Peruzzi

Reputation: 535

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://");
        }
    }

Upvotes: 0

Alex Kolovatov
Alex Kolovatov

Reputation: 879

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

First you should find your info.plist and open it as Source Code.

Step 2: Add these lines between <dict> and </dict>

enter image description here

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

Upvotes: 2

Haktan Enes Bi&#231;er
Haktan Enes Bi&#231;er

Reputation: 682

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.

Upvotes: 8

kuzdu
kuzdu

Reputation: 7524

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.

Upvotes: 7

syed aurangzaib
syed aurangzaib

Reputation: 11

// 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

Upvotes: 1

Mudith Chathuranga Silva
Mudith Chathuranga Silva

Reputation: 7434

Here is the Swift 3 Update

First, you need to two items to LSApplicationQueriesSchemes in the info.plist.

enter image description here

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.")
        }
}

Upvotes: 10

Anoop
Anoop

Reputation: 419

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

Upvotes: 14

Abedalkareem Omreyh
Abedalkareem Omreyh

Reputation: 2329

For those that the solution for the accepted answer didn't work for them, remember to add comgooglemaps to LSApplicationQueriesSchemes in the info.plist.

info.plist

Upvotes: 28

Hardik Thakkar
Hardik Thakkar

Reputation: 15951

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://");
        }
    }

Upvotes: 7

Sachin Kishore
Sachin Kishore

Reputation: 324

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

Upvotes: 6

user3745635
user3745635

Reputation: 955

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://");
}

Upvotes: 32

sumesh
sumesh

Reputation: 2249

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

Upvotes: 77

Related Questions