1

How can I use address for to create a route with google maps? Without use latitude and longitude, because in my firebase i don't use latitude and longitude. I use only full address.

Example: John F.Kennedy International Airport, Van Wyck Expressway, Jamaica, New York.

My code to build the route with google maps:

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    if (control as? UIButton)?.buttonType == UIButtonType.detailDisclosure {

        mapView.deselectAnnotation(view.annotation, animated: false)

    } else if (control as? UIButton)?.buttonType == UIButtonType.custom {

        mapView.deselectAnnotation(view.annotation, animated: false)

        let alertController = UIAlertController(title: "Выберите навигатор для построение маршрута", message: nil, preferredStyle: .actionSheet)

        let googleMaps = UIAlertAction(title: "Google Maps", style: .default, handler: { (action: UIAlertAction) in

            if (UIApplication.shared.canOpenURL(URL(string: "comgooglemaps://")!)) {

                let googleUrl = URL(string: "comgooglemaps://?daddr=John+F.+Kennedy+International+Airport,+Van+Wyck+Expressway,+Jamaica,+New+York&directionsmode=driving")!

                UIApplication.shared.open(googleUrl, options: [:], completionHandler: nil)

            } else {

                let itunesGoogleMaps = URL(string: "https://itunes.apple.com/us/app/google-maps-gps-navigation/id585027354?mt=8")

                UIApplication.shared.open(itunesGoogleMaps!, options: [:], completionHandler: nil)

            }

        })

        let cancel = UIAlertAction(title: "Отмена", style: .cancel, handler: nil)

        alertController.addAction(googleMaps)
        alertController.addAction(cancel)

        self.present(alertController, animated: true, completion: nil)

    }
}

And i use variable to get address from firebase and build the route:

var studioInfoFromDetail: Hall?

studioInfoFromDetail?.studioAddress

This variable have address on rus language.

Example:

Москва, ул. Правды д.24, строение 3 in English would be so Moscow, Pravdy street, home 24, building 1

Москва, ул.Электрозаводская, д.21 in English would be so Moscow, Elektrozavodska street, home 21

So how can i place in this variable

let googleUrl = URL(string: "comgooglemaps://?daddr=John+F.+Kennedy+International+Airport,+Van+Wyck+Expressway,+Jamaica,+New+York&directionsmode=driving")! 

my address from firebase?

I tried to write so:

let googleUrl = URL(string: "comgooglemaps://?daddr=\(self.studioInfoFromDetail?.studioAddress)&directionsmode=driving")!

But i get a nil :(

2 Answers2

0

I think you need to escape the non-ASCII part of the url string. Call the method addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) on your studioAddress before inserting in into the url string.

Update:

Since you are using a String optional (aka String? / Optional<String>) in your interpolation (see this question that I mentioned in the comment):

let str = "comgooglemaps://?daddr=\(self.studioInfoFromDetail?.studioAddress)&directionsmode=driving"

You will get:

"comgooglemaps://?daddr=\Optional(<... your string ...>)&directionsmode=driving"

Thus you need to unwrap the optional before using it.

if let address = self.studioInfoFromDetail?.studioAddress {
    let str = "comgooglemaps://?daddr=\(address)&directionsmode=driving"
}

You can also force unwrap (with an operator !), but I would not recommend doing that.

ivanmoskalev
  • 2,004
  • 1
  • 16
  • 25
  • I tried `let originalString = "\(self.studioInfoFromDetail!.studioAddress)" let escapingString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) print("string: \(escapingString!)")` and i get this `string: %D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0,%201-%D0%B9%20%D0%9A%D1%80%D0%B0%D1%81%D0%BD%D0%BE%D0%B3%D0%B2%D0%B0%D1%80%D0%B4%D0%B5%D0%B9%D1%81%D0%BA%D0%B8%D0%B9%20%D0%BF%D1%80%D0%BE%D0%B5%D0%B7%D0%B4,%20%D0%B4.21%20%D1%81%D1%82%D1%80.2` that's what you mean? – Дмитрий Деникаев Oct 24 '17 at 08:02
  • Yes. This should allow you to create an instance of `URL`. Originally, you got `nil` because the url string you passed into the constructor was ill-formed, with cyrillic text in its query part. – ivanmoskalev Oct 24 '17 at 08:09
  • i add `escapingString` in `let googleUrl = URL(string: "comgooglemaps://?daddr=\(escapingString)&directionsmode=driving")!` but I still got nil – Дмитрий Деникаев Oct 24 '17 at 08:11
  • Try `let urlString = "comgooglemaps://?daddr=\(escapingString)&directionsmode=dri‌​ving"; print(urlString)` Please post here what is printed. It is most likely that you run into [this](https://stackoverflow.com/questions/31417853/swift-string-interpolation-displaying-optional). – ivanmoskalev Oct 24 '17 at 08:13
  • i got this: `comgooglemaps://?daddr=Optional("%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0,%201-%D0%B9%20%D0%9A%D1%80%D0%B0%D1%81%D0%BD%D0%BE%D0%B3%D0%B2%D0%B0%D1%80%D0%B4%D0%B5%D0%B9%D1%81%D0%BA%D0%B8%D0%B9%20%D0%BF%D1%80%D0%BE%D0%B5%D0%B7%D0%B4,%20%D0%B4.21%20%D1%81%D1%82%D1%80.2")&directionsmode=dri‌​‌​ving` – Дмитрий Деникаев Oct 24 '17 at 08:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157353/discussion-between-ivanmoskalev-and--). – ivanmoskalev Oct 24 '17 at 08:41
  • 1
    I decided to try CLGeocoder and I got what I wanted. In any case, thanks for the help. – Дмитрий Деникаев Oct 24 '17 at 09:26
0

I try this and it help me

let googleMaps = UIAlertAction(title: "Google Maps", style: .default, handler: { (action: UIAlertAction) in

            if (UIApplication.shared.canOpenURL(URL(string: "comgooglemaps://")!)) {

                let geocoder = CLGeocoder()
                geocoder.geocodeAddressString((self.studioInfoFromDetail?.studioAddress)!, completionHandler: { (placemarks, error) in

                    guard error == nil else { return }

                    guard let placemarks = placemarks else { return }

                    let placemark = placemarks.first

                    let longitude = placemark?.location?.coordinate.longitude
                    let latitude = placemark?.location?.coordinate.latitude

                    print("lat: \(latitude!), lon: \(longitude!)")

                    let googleUrl = URL(string: "comgooglemaps://?daddr=\(latitude!),\(longitude!)&directionsmode=driving")!

                    UIApplication.shared.open(googleUrl, options: [:], completionHandler: nil)

                })

            } else {

                let itunesGoogleMaps = URL(string: "https://itunes.apple.com/us/app/google-maps-gps-navigation/id585027354?mt=8")

                UIApplication.shared.open(itunesGoogleMaps!, options: [:], completionHandler: nil)

            }

        })

    }