Reputation: 2249
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
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,
for more references - https://developers.google.com/maps/documentation/ios-sdk/urlscheme
Upvotes: 0
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
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
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
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
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:
Upvotes: 3
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
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
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
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
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
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
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)
}
Upvotes: 2
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
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
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.
Upvotes: 1
Reputation: 7434
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.")
}
}
Upvotes: 10
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
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.
Upvotes: 28
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
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
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
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