How to open Apple Maps driving direction by passing address - ios

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?

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)

You could call maps with a url (as detailed by Nicola) but there is also a proper api for this : MKMapItem
basically you create map items for POIs / addresses [1 or more]
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)
}

Related

Can't show the directions in iPhone's inbuilt Map application

This is my custom location set inside the iOS 10.0 iPhone 6 and iOS 11.2 iPhone 6 simulators.
And this is the code by which I am trying to open the iPhone's inbuilt Apple Map and show the directions from user's (above set) current location to the provided destination locations.
let regionDistance: CLLocationDistance = 1000
let coordinates = CLLocationCoordinate2D(latitude: 26.025860999999999, longitude: 56.089238999999999)
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span),
MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] as [String : Any]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = "Federal Electricity & Water Authority"
mapItem.openInMaps(launchOptions: options)
but this is not working for at all. It's showing me the error like below,
Note:
I have given the location access permission to the default Map
application.
All 4 MKLaunchOptionsDirectionsModeKey is not showing
the direction.
Tested it on the Simulator and a real device and it is not working in either place.
Setting destination coordinates like this doesn't help. let coordinates = CLLocationCoordinate2D(latitude: 26.025861, longitude: 56.089239)
Please help!
As Indrajeet commented, the directions in iPhone's Apple Map is limited to the countries which are listed in this URL.
So in my case, UAE is not listed currently.
Will update this answer in future once UAE will be listed.

Open Apple Maps for navigation with destination name set

I am fetching location data (like the coordinates used below) from Google's Places API.
When linking to Apple Maps for navigation from my app, I am currently using:
https://maps.apple.com/?daddr=[latitude],[longitude]
When Maps opens, it presents the coordinates for a short amount of time before resolving to an address. What I want is for the name of the destination to appear instead of coordinates or an address. Since I am using React Native, I would prefer a javascript-only solution (knowing that this essentially restricts a solution to this question to a url).
I have tried combinations of other parameters listed here to no avail.
Try with this function, you only need to pass the coordinates and place name, this works, I use this in several projects
static func openMapsAppWithLocation(coordinates:CLLocationCoordinate2D,placeName:String)
{
let regionDistance:CLLocationDistance = 10000
let regionSpan = MKCoordinateRegionMakeWithDistance(coordinates, regionDistance, regionDistance)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span)
]
let placemark = MKPlacemark(coordinate: coordinates, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = placeName
mapItem.openInMaps(launchOptions: options)
}
Hope this helps

How to get Apple Maps App (not MapKit) to add an annotation?

It's quite easy to add an annotation to a MapKit view which is inside your app.
theMap: MKMapView!
let pa = MKPointAnnotation()
pa.title = "title!!" etc
theMap.addAnnotation(pa)
But how the heck do you make the Maps App add an annotation??
Here's exactly how to open the Maps App to a certain address..
func appleMapApp() {
quickAddressText = "123 Smith St 90210"
let bottomText = "This shows at BOTTOM Of Maps App screen."
let g = CLGeocoder()
g.geocodeAddressString(quickAddressText) { placemarks, error in
if let found = placemarks?.first, let lok = found.location {
let p = MKPlacemark(coordinate: lok.coordinate, addressDictionary: nil)
let mapItem = MKMapItem(placemark: p)
mapItem.name = bottomText
mapItem.openInMaps(launchOptions: showing(location: lok))
}
}
}
// convenient function...
func showing(location: CLLocation, meters m: CLLocationDistance = 1000)->[String : Any]? {
let cr = MKCoordinateRegionMakeWithDistance(location.coordinate, m,m)
let options = [
MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: cr.center),
MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: cr.span)
]
return options
}
That's great - but how the heck do you pass in a MKPointAnnotation to the actual Maps app??
(Again - it's easy to add a MKPointAnnotation on a map view inside your own app.)
Any ideas? Is it actually possible??
I think openInMaps limits you only to the five possible launch options. But I wonder if you could get Apple Maps to open in the original way, openURL and maps.apple.com/maps, as shown in this SO question. With the newest iOS versions, though, it seems you also need to register the URL you're using in your info.plist under "URL Types ... URL Schemes" or "LSApplicationQueriesSchemes". You might be able to pass an annotation as a parameter with the URL.

Google Places iOS: How to provide context to API for relevant local results

Using Google Places API for iOS, I am using the Place AutoComplete feature. When I start typing a place name for example 'Starbucks' it gives me starbucks location in several countries but not my local starbucks. How do I pass the current location to the API so the search results start from closest to my location?
You can pass a GMSCoordinateBounds to the which is "object biasing the results to a specific area specified by latitude and longitude bounds".
They have an example on their site showing how to do this:
let visibleRegion = self.mapView.projection.visibleRegion()
let bounds = GMSCoordinateBounds(coordinate: visibleRegion.farLeft, coordinate: visibleRegion.nearRight)
let filter = GMSAutocompleteFilter()
filter.type = GMSPlacesAutocompleteTypeFilter.City
placesClient.autocompleteQuery("Sydney Oper", bounds: bounds, filter: filter, callback: { (results, error: NSError?) -> Void in
guard error == nil else {
print("Autocomplete error \(error)")
return
}
for result in results! {
print("Result \(result.attributedFullText) with placeID \(result.placeID)")
}
})
This example show how to pull this data from a map view but you can also create the GMSCoordinateBounds manually.
Hope this helps.

Load Apple Maps App with Placemark - slow performance

When ill load any placemark from my app into the Apple Maps App - it takes up to 15 Seconds to show a route.
First you see for maybe 1 second your position, then you see North America, and then (after 10-15 Seconds) you get your route.
Is there any chance to optimize the performance here? This is how i start the route at the moment (Ill provide already a lon and lat value)
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: CLLocationDegrees(lat),longitude: CLLocationDegrees(lon)), addressDictionary: nil)
let aMapItem = MKMapItem(placemark: placemark
aMapItem.name = mapItem.name
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeWalking]
let currentLocationMapItem:MKMapItem = MKMapItem.mapItemForCurrentLocation()
MKMapItem.openMapsWithItems([currentLocationMapItem, aMapItem], launchOptions: launchOptions)
Thanks in advance.

Resources