iOS 9 Swift Programming Cookbook (2015)
Chapter 8. Maps and Location
8.6 Providing an ETA for Transit Transport Type
Problem
You want your app to provide routing options to the user when she is in the iOS maps app.
Solution
Mark your app as a routing app and construct an instance of the MKDirectionsRequest class. Set the transportType property of that request to Transit and send your request to Apple to calculate an estimated time of arrival (ETA), using thecalculateETAWithCompletionHandler(_:) method of the MKDirections class.
NOTE
We use Geo JSON files in this recipe, so read the spec for that format first, please.
Discussion
Create a single view application. Then head to the Capabilities tab in Xcode, enable the Maps section, and mark the routing options that you believe your app will be able to provide (see Figure 8-5). I’ve enabled all these items for demonstration purposes. You probably wouldn’t want to enable all of these in your app.
Figure 8-5. Transportation routing options
Create a new Directions.geoJson file in your app and then head over to GeoJson.io to create the polygon that defines your routing coverage area. Then copy and paste the generated content and place it in the aforementioned file in your project. Now go and edit your target’s scheme. Under Run and then Options, find the Routing App Coverage file section and select your file (see Figure 8-6).
Figure 8-6. Here I am selecting the routing coverage file for my project
NOTE
You can always go to GeoJsonLint to validate your Geo JSON files.
This will allow the maps app to open my app whenever the user asks for transit information on the iOS maps app. Now code the application(_:openURL:options:) method of your app delegate and handle the routing request there:
func application(app: UIApplication, openURL url: NSURL,
options: [String : AnyObject]) -> Bool {
guard MKDirectionsRequest.isDirectionsRequestURL(url) else{
return false
}
//now we have the url
let req = MKDirectionsRequest(contentsOfURL: url)
guard req.source != nil && req.destination != nil else{
return false
}
req.transportType = .Transit
req.requestsAlternateRoutes = true
let dir = MKDirections(request: req)
dir.calculateETAWithCompletionHandler {response, error in
guard let resp = response where error == nil else{
//handle the error
print(error!)
return
}
print("ETA response = \(resp)")
}
return true
}
Now open the maps app and ask for directions from one location to another. If the maps app couldn’t handle the request, it will show a little “View Routing Apps” button. Regardless of whether the maps app could or couldn’t show the routing options, the user can always press the little navigation button to open alternative routing apps (see Figure 8-7). Your app will be displayed in the list of routing apps if the user asks for a routing option you support, and if the starting and stopping points are within the shape you defined in your Geo JSON file. When the user opens your app, your app delegate will be informed and will calculate an ETA.
Figure 8-7. Our app, displayed in the list of routing apps
See Also