4

I'm trying to implement a function that open the Apple Map app's driving direction screen by passing actual address.

The address is not just random addresses but business addresses which are mostly registered and searchable on Apple maps. So by passing the address, it should be matched and correctly show direction to that business instead of pointing to an unknown annotation on the map. Such case happens when I pass longitude and latitude directly so I don't want to use geocodeAddressString() to convert the address to geocoordination.

How can I achieve it?

2 Answers2

10

Simply use the Apple Maps API. If you can find a business by tiping its name in Apple Maps, you can find it through the APIs. In your case, the correct parameter is daddr, like this:

http://maps.apple.com/?daddr=1+Infinite+Loop,+Cupertino,+CA

You can combine multiple parameters, such as your starting location:

http://maps.apple.com/?saddr=1024+Market+St,+San+Francisco,+CA&daddr=1+Infinite+Loop,+Cupertino,+CA

You can find the list of supported parameters here.

Remember to open the URL via UIApplication.shared().open(url: URL, options: [String: AnyObject], completionHandler: ((Bool) -> Void)?) - in iOS 10 - or UIApplication.shared.open(url: URL)

Nicola Giancecchi
  • 3,045
  • 2
  • 25
  • 41
  • Id avoid the protocol and use MKMapItems .. they were made for this after all – Daij-Djan Dec 20 '16 at 23:24
  • also: building strings in code? and urls even.. you'd have to worry about URLEncoding and everything :) – Daij-Djan Dec 20 '16 at 23:39
  • @Nicola Giancecchi Thank you for the code. it works well – androisojavaswift Dec 21 '16 at 15:10
  • 1
    @Nicola Giancecchi And forgot to mention on above comment that I ended up using q and sll parameters instead of using just daddr. (i.e. http://maps.apple.com/?aq=q=Home%20of%20Hot%20Taste&sll=43.8055499,-79.42004)This way gives me correct location – androisojavaswift Dec 21 '16 at 15:18
  • This answer worked for me. If you are wondering how to change the spaces to + you can check this answer to help with that. Hope this helps someone in the future. https://stackoverflow.com/a/24201206/943571 – Jiraheta Mar 27 '18 at 23:28
1

You could call maps with a url (as detailed by Nicola) but there is also a proper api for this : MKMapItem

  1. basically you create map items for POIs / addresses [1 or more]
  2. open Maps with them [use the launchOptions for starting with directions]

    func showMap() {
        //---
        //create item 1
    
        //address
        let coords = CLLocationCoordinate(coordinateField.doubleValue!,coordinateField.doubleValue!)
        let addressDict =
               [CNPostalAddressStreetKey: address.text!,
                CNPostalAddressCityKey: city.text!,
                CNPostalAddressStateKey: state.text!,
                CNPostalAddressPostalCodeKey: zip.text!]        
        //item
        let place = MKPlacemark(coordinate: coords!,
                                 addressDictionary: addressDict)
        let mapItem = MKMapItem(placemark: place)
    
        //---
        //create item 2
    
        //address
        let coords2 = CLLocationCoordinate(coordinateField2.doubleValue!,coordinateField2.doubleValue!)
        let addressDict2 =
               [CNPostalAddressStreetKey: address2.text!,
                CNPostalAddressCityKey: city2.text!,
                CNPostalAddressStateKey: state2.text!,
                CNPostalAddressPostalCodeKey: zip2.text!]
        //item2
        let place2 = MKPlacemark(coordinate: coords2!,
                                 addressDictionary: addressDict2)
        let mapItem2 = MKMapItem(placemark: place2)
    
        //-----
        //launch it     
        let options = [MKLaunchOptionsDirectionsModeKey:
                            MKLaunchOptionsDirectionsModeDriving]
    
        //for 1 only.       
        mapItem.openInMaps(launchOptions: options)
        //for 1 or N items 
        var mapItems = [mapItem, mapItem2] //src to destination
        MKMapItem.openMaps(withItems:mapItems, launchOptions: options)
    }
    
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • 1
    There are some pros with this approach. But there are cons too: 1) @androisojavaswift wants to find the business by its name, not only by its address or city 2) CNPostalAddress keys are available only since iOS 9.0; the URI schema is used since iOS 6 3) You need to import Contacts framework only for this piece of code – Nicola Giancecchi Dec 20 '16 at 23:40
  • 1
    1) :) finding by name is what the CLGeocoder does for you - it builds place marks. you don't need an address for THOSE - or coordinates even :) – Daij-Djan Dec 20 '16 at 23:42
  • 1
    2. the keys are identical to the old address book keys so this works on lower versions to if you need to build with old base sdk .. 3) not if you want places only anyway :) – Daij-Djan Dec 20 '16 at 23:43
  • My code doesn't make use of the geocoder, like @androisojavaswift wants in his question. It's a debatable choice... obviously, your implementation is more clear and verbose – Nicola Giancecchi Dec 20 '16 at 23:54
  • @Daij-Djan Thank you for the code. It's very helpful and I have chance to play with mapkit. but I end up using solution provided by Nicola Giancecchi – androisojavaswift Dec 21 '16 at 14:49