MapQuest Navigation SDK provides a way to easily add turn by turn navigation in any app. This SDK does not generate transactions on your account and is available free to use.
Navigation SDK is only available in the U.S. at this time. If you would like to use Navigation SDK outside of the U.S. please contact your account manager or customer support
The following APIs are often used with the Navigation SDK and are currently being used within the sample app, but do incur their normal transaction costs.
In order to use MapQuest APIs and SDKs you will need a MapQuest Key. We use this key to associate your requests to APIs with your account. You can find your existing Keys or create a new one at Applications page.
If you don't have a MapQuest Developer Account you can sign up for one. Sign Up Here.
You can get these for free from the Mac App Store. Download Xcode Here
You can use your personal devices or Xcode’s iOS Simulator for this guide without an Apple Developer Account. If you want to distribute your app to others, you’ll need to sign up and pay for an account. Sign Up Here
Download the zipped SDK that contains the framework and a resource bundle that need to be included in the project
Use the Navigation SDK within your own Xcode project using CocoaPods.
You need to include the following in the podfile:
source 'https://github.com/CocoaPods/Specs'
source 'https://github.com/MapQuest/podspecs-ios.git'
platform :ios, '8.0'
use_frameworks!
target :'<targetName>' do
pod 'MQNavigation', '~> 3.5.0'
end
To use the MapQuest SDK in your app, you need to place your MapQuest Key inside the app’s Info.plist file:
You will also need to allow arbitrary loads in your app. You can do this by adding NSAppTransportSecurity to your Info.plist with NSAllowsArbitraryLoads set to true. We are actively working on resolving this requirement.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Host app developers instantiate MQNavigationManager which provides delegate methods for navigation-related events. Events are triggered when:
The Objective-C and Swift examples here demonstrate how to create a route from New York City to Boston and start a turn-by-turn navigation session.
The examples here set the userLocationTrackingConsentStatus
flag to granted
for
sample purposes only and cannot be used for production. Read more about Traffic Data
Collection here.
//include the umbrella header
#import "MQNavigation.h"
//declare properties for MQNavigationManager and MQRouteService
@property (nonatomic, strong) MQNavigationManager *navigationManager;
@property (nonatomic, strong) MQRouteService *routeService;
//instantiate MQNavigationManager and assign delegates.
self.navigationManager = [[MQNavigationManager alloc] initWithDelegate:self promptDelegate:self];
self.navigationManager.userLocationTrackingConsentStatus = MQUserLocationTrackingConsentStatusGranted; // Production code requires this be set by providing the user with a Terms of Service dialog.
//instantiate MQRouteService
self.routeService = [[MQRouteService alloc] init];
//set up start and destination for the route
CLLocation *nyc = [[CLLocation alloc] initWithLatitude:40.7326808 longitude:-73.9843407];
CLLocation *boston = [[CLLocation alloc] initWithLatitude:42.355097 longitude:-71.055464];
//set up route options
MQRouteOptions *options = [MQRouteOptions new];
//get route/s from MQRouteService
[self.routeService requestRoutesWithStartLocation:nyc destinationLocations:@[boston] options:options completion:^(NSArray<MQRoute
*> * _Nullable routes, NSError * _Nullable error) {
if(error) {
NSLog(@"ERROR:%@",error);
} else if(routes) {
if (routes.count > 0) {
//start navigating with the route.
[self.navigationManager startNavigationWithRoute:routes[0]];
}
}
}];
// This is the only required delegate for MQNavigationManager
- (void)navigationManager:(nonnull MQNavigationManager *)navigationManager failedToStartNavigationWithError:(nonnull NSError*)error {
// Check for an error on why Navigation did not start
}
//import the module
import MQNavigation`
//declare properties for MQNavigationManager and MQRouteService
fileprivate lazy var navigationManager: MQNavigationManager! = {
let manager = MQNavigationManager(delegate: self, promptDelegate: self)
manager?.userLocationTrackingConsentStatus = .granted; // Production code requires this be set by providing the user with a Terms of Service dialog.
return manager
}()
fileprivate lazy var routeService = MQRouteService()
//set up start and destination for the route
fileprivate let nyc = CLLocation(latitude:40.7326808, longitude:-73.9843407)
fileprivate let boston = CLLocation(latitude:42.355097, longitude:-71.055464)
//request route
routeService.requestRoutes(withStart: nyc, destinationLocations:[boston], options: routeOptions) { [weak self] (routes, error) in
guard let strongSelf = self else { return }
//handle error
if let error = error {
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
strongSelf.present(alert, animated: true, completion: nil)
return
}
guard let routes = routes, routes.isEmpty == false else { return }
//start navigation with first route
strongSelf.navigationManager.startNavigation(with: routes[0])
}
// This is the only required delegate for MQNavigationManager
func navigationManager(_ navigationManager: MQNavigationManager, failedToStartNavigationWithError error: Error) {
// Check for an error on why Navigation did not start
}
MQNavigation provides a simple class for you to set route restrictions, system of measurement, and language locale when requesting a route.
Restrictions may be provided to influence the route path to avoid certain features like tolls, unpaved roads, and others. The following restriction types are available:
Each type can be set to one of: allow, avoid, or disallow.
System of measurement for Prompts may be changed to Metric or Imperial by setting systemOfMeasurementForDisplayText to one of MQSystemOfMeasurementUnitedStatesCustomary or MQSystemOfMeasurementMetric.
Language allows the navigation prompts, instructions, and maneuvers to be localized in a supported language.
Current supported languages include (default) US English en_US
and US Spanish
es_US
.
MQRouteOptions *options = [MQRouteOptions new];
options.highways = MQRouteOptionTypeAllow;
options.tolls = MQRouteOptionTypeDisallow;
options.ferries = MQRouteOptionTypeAvoid;
options.unpaved = MQRouteOptionTypeAllow;
options.internationalBorders = MQRouteOptionTypeDisallow;
options.seasonalClosures = MQRouteOptionTypeAvoid;
options.maxRoutes = 3;
options.systemOfMeasurementForDisplayText = MQSystemOfMeasurementUnitedStatesCustomary;
options.language = @"en_US";
//build route options
let options = MQRouteOptions()
options.highways = .allow
options.tolls = .disallow
options.ferries = .avoid
options.unpaved = .allow
options.internationalBorders = .disallow
options.seasonalClosures = .avoid
options.maxRoutes = 3
options.systemOfMeasurementForDisplayText = .unitedStatesCustomary
options.language = "en_US"
As the user progresses along the route, the MQNavigation periodically queries a server to receive updated arrival time and traffic information based on current traffic conditions. Developers may capture these events to obtain and update the displayed traffic information and ETA.
//make your view controller conform to MQNavigationManagerDelegate protocol
@interface ViewController () <MQNavigationManagerDelegate> {
}
//this method is called before the network call is made to get new ETA
- (void)navigationManagerWillUpdateETA:(nonnull MQNavigationManager *)navigationManager {
//TODO: may be a spinner to show that something is happening in the background.
}
//This method will provide updated ETA.
- (void)navigationManagerDidUpdateETA:(nonnull MQNavigationManager *)navigationManager withETAByRouteLegId:(nonnull NSDictionary<NSString*,MQEstimatedTimeOfArrival*> *)etaByRouteLegId {
//TODO: handle ETA update
}
//This method will provide details of errors if the network call to get new ETA fails for any reason.
- (void)navigationManager:(nonnull MQNavigationManager *)navigationManager failedToUpdateEtaWithError:(nonnull NSError *)error {
//TODO: failed to get an ETA update. Do something.
}
//this method is called before the network call is made to get new Traffic
- (void)navigationManagerWillUpdateTraffic:(MQNavigationManager *)navigationManager {
//TODO: may be a spinner to show that something is happening in the background.
}
//This method will provide updated Traffic for each leg of the route.
- (void)navigationManagerDidUpdateTraffic:(MQNavigationManager *)navigationManager withTrafficByRouteLegId:(NSDictionary *)trafficByRouteLegId {
//TODO: update UI to show new traffic details on the route.
}
//This method is called when a faster route is available that avoids traffic congestions.
- (void)navigationManager:(MQNavigationManager *)navigationManager foundTrafficReroute:(MQRoute *)route {
//TODO: ask the user if they want to follow a different route and start navigation with new route.
}
//This method will provide details of errors if the network call to get new Traffic fails for any reason.
- (void)navigationManager:(MQNavigationManager *)navigationManager failedToUpdateTrafficWithError:(nonnull NSError *)error {
//TODO: handle error
}
//make your view controller conform to MQNavigationManagerDelegate protocol
class ViewController: UIViewController, MQNavigationManagerDelegate{
}
//this method is called before the network call is made to get new ETA
func navigationManagerWillUpdateETA(_ navigationManager: MQNavigationManager) {
//TODO: may be a spinner to show that something is happening in the background.
}
//This method will provide updated ETA.
func navigationManagerDidUpdateETA(_ navigationManager: MQNavigationManager, withETAByRouteLegId etaByRouteLegId: [String : MQEstimatedTimeOfArrival]) {
//TODO: handle ETA update
}
//This method will provide details of errors if the network call to get new ETA fails for any reason.
func navigationManager(_ navigationManager: MQNavigationManager, failedToUpdateEtaWithError error: Error) {
//TODO: failed to get an ETA update. Do something.
}
//this method is called before the network call is made to get new Traffic
func navigationManagerWillUpdateTraffic(_ navigationManager: MQNavigationManager) {
//TODO: may be a spinner to show that something is happening in the background.
}
//This method will provide updated Traffic for each leg of the route.
func navigationManagerDidUpdateTraffic(_ navigationManager: MQNavigationManager, withTrafficByRouteLegId trafficByRouteLegId: [AnyHashable : Any]) {
//TODO: update UI to show new traffic details on the route.
}
//This method is called when a faster route is available that avoids traffic congestions.
func navigationManager(_ navigationManager: MQNavigationManager, foundTrafficReroute route: MQRoute) {
//TODO: ask the user if they want to follow a different route and start navigation with new route.
}
//This method will provide details of errors if the network call to get new Traffic fails for any reason.
func navigationManager(_ navigationManager: MQNavigationManager, failedToUpdateTrafficWithError error: Error) {
//TODO: handle error
}
As the user progresses along the route, Whenever the speed limit changes, a delegate method is invoked specifying the speed limit zones exited and entered. These examples demonstrate how to listen to speed limit changes and update a speed limit display.
//make your view controller conform to MQNavigationManagerDelegate protocol
@interface ViewController () <MQNavigationManagerDelegate> {
}
//Implement the delegate method and handle changes in speed limits.
- (void)navigationManager:(nonnull MQNavigationManager *)navigationManager crossedSpeedLimitBoundariesWithExitedZones:(nullable NSSet <MQSpeedLimit *> *)exitedSpeedLimits enteredZones:(nullable NSSet <MQSpeedLimit *> *)enteredSpeedLimits
{
// update UI to reflect new speeed limits.
}
//make your view controller conform to MQNavigationManagerDelegate protocol
class ViewController: UIViewController, MQNavigationManagerDelegate{
}
////Implement the delegate method and handle changes in speed limits.
func navigationManager(_ navigationManager: MQNavigationManager, crossedSpeedLimitBoundariesWithExitedZones exitedSpeedLimits: Set<MQSpeedLimit>?, enteredZones enteredSpeedLimits: Set<MQSpeedLimit>?) {
// update UI to reflect new speeed limits.
}
When MQNavigation detects that user has gone off-route, the host app is informed via an optional delegate method requesting permission to reroute. If the delegate method returns TRUE or does not exist MQNavigation will attempt a reroute request which if successful will invoke a delegate method specifying a new route from the current location to the destination. These examples demonstrate how to listen to off-route reroutes.
//called providing the host app the ability to choose whether a reroute occurs or not
- (BOOL)navigationManagerShouldReroute:(nonnull MQNavigationManager *)navigationManager {
return YES;
}
//called after MQNavigation gets a new route.
-(void)navigationManager:(MQNavigationManager *)navigationManager didReroute:(MQRoute *)route {
//TODO: update UI with new route
//TODO: start navigation using the new route
}
//if the user gets back on the route before a new route is acquired, new route is discarded
-(void)navigationManagerDiscardedReroute:(MQNavigationManager *)navigationManager {
//TODO: update UI to show that background network call is completed
}
//called when SDK fails to get a reroute.
-(void)navigationManager:(MQNavigationManager *)navigationManager failedToRerouteWithError:(NSError *)error {
//TODO: note that there was an error
}
//called providing the host app the ability to choose whether a reroute occurs or not
func navigationManagerShouldReroute(_ navigationManager: MQNavigationManager) -> Bool {
return true
}
//called after MQNavigation gets a new route.
func navigationManager(_ navigationManager: MQNavigationManager, didReroute route: MQRoute) {
//TODO: update UI with new route
//TODO: start navigation using the new route
}
//if the user gets back on the route before a new route is acquired, new route is discarded
func navigationManagerDiscardedReroute(_ navigationManager: MQNavigationManager) {
//TODO: update UI to show that backgrond network call is completed
}
//called when SDK fails to get a reroute.
func navigationManager(_ navigationManager: MQNavigationManager, failedToRerouteWithError error: Error) {
//TODO: note that there was an error
}
During navigation, when it is time to alert user of an upcoming maneuver or give an update on the route, a delegate method is invoked specifying Prompt object that is suppose to be spoken. Host app developers are responsible for using a TTS engine to speak the prompt. These examples demonstrate how to listen to Prompt updates.
//make your class conform to MQNavigationManagerPromptDelegate protocol
@interface ViewController () <MQNavigationManagerDelegate> {
}
//this method is called when it is time to speak the prompt.
- (void)navigationManager:(nonnull MQNavigationManager *)navigationManager receivedPrompt:(nonnull MQPrompt *)promptToSpeak userInitiated:(BOOL)userInitiated {
//TODO: use any Text To Speech engine to speak promptToSpeak.speech
//TODO: If the app is in background, post a local notification with promptToSpeak.text
}
//this is called when the current prompt (if there is one spoken) is not valid anymore.
- (void)cancelPromptsForNavigationManager:(nonnull MQNavigationManager *)navigationManager {
//TODO: stop speaking any prompt.
}
//make your class conform to MQNavigationManagerPromptDelegate protocol
class ViewController: UIViewController, MQNavigationManagerPromptDelegate {
}
//this method is called when it is time to speak the prompt.
func navigationManager(_ navigationManager: MQNavigationManager, receivedPrompt promptToSpeak: MQPrompt, userInitiated: Bool) {
//TODO: use any Text To Speech engine to speak promptToSpeak.speech
//TODO: If the app is in background, post a local notification with promptToSpeak.text
}
//this is called when the current prompt (if there is one spoken) is not valid anymore.
func cancelPrompts(for navigationManager: MQNavigationManager) {
//TODO: stop speaking any prompt.
}
Often you may need to provide a quick ETA (estimated time to arrival) and traffic information before you even start a navigation session. This may be useful as a dashboard for ETA to different points (such as home/work) or as users inquire about points of interest on the map or in your application. The route summary service provides a very quick response providing you with the ETA, Traffic, and Length to a specific destination without the heavy network bandwidth used for a whole route request.
The main advantages of using the route summary call over getting a route are: performance, optimized data delivery, and ease of use.
To get a route summary is very similar to getting a full route request. The differences are that you don't provide any route options and only one destination is supported.
@interface Destination : NSObject <MQRouteDestination>
@property (nonatomic, copy) CLLocation* location;
@property (nonatomic, copy, nullable) NSString* mqid;
-(instancetype)initWithLocation:(CLLocation*)location mqID:(nullable NSString*)mqID;
@end
- (void)getRouteSummary {
//set up start and destination for the route summary
CLLocation *nyc = [[Destination alloc] initWithLocation:[[CLLocation alloc] initWithLatitude:40.7326808 longitude:-73.9843407] mqID:nil]
CLLocation *boston = [[Destination alloc] initWithLocation:[[CLLocation alloc] initWithLatitude:42.355097 longitude:-71.055464] mqID:nil];
//get route summary from MQRouteService
[self.routeService requestRouteSummaryWithStartLocation:nyc destination:boston completion:^(MQEstimatedTimeOfArrival *estimatedTimeOfArrival, MQTrafficOverview trafficConditions, CLLocationDistance routeLength, NSError * _Nullable error) {
//Show Summary on main thread
}];
}
class Destination: NSObject, MQRouteDestination {
var location: CLLocation
var mqid: String?
required init(location: CLLocation, mqid: String? = nil) {
self.location = location
self.mqid = mqid
}
}
func getRouteSummary() {
//set up start and destination for the route summary
fileprivate let nyc = Destination(location: CLLocation(latitude:40.7326808, longitude:-73.9843407), mqid: nil)
fileprivate let boston = Destination(location: CLLocation(latitude:42.355097, longitude:-71.055464), mqid: nil)
//request route
routeService.requestRouteSummary(withStart: nyc, destination:boston, ) { [weak self] (estimatedTimeOfArrival, trafficConditions, routeLength, error) in
guard let strongSelf = self else { return }
OperationQueue.main.addOperation {
//handle error
if let error = error {
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
strongSelf.present(alert, animated: true, completion: nil)
return
}
//Show route summary
}
}
}
MQRouteService provides two ways to designate a destination for your route: by passing in your own coordinates or
by passing in an object that conforms to the new MQRouteDestination
protocol. Passing in your own
coordinates is useful if you are routing to a known location, or if you use a geocoder to retrieve a street
address or dropped pin. The MQRouteDestination protocol is used when you have both the coordinates and an MQID
associated with a Point of Interest (POI) provided by a MapQuest service like our Search Ahead SDK. Routing using
an MQID provides the routing engine with more detail and the ability to generate a route with considerations such
as parking lot or the front door of an establishment.
The MQRouteDestination
protocol also allows you to create a rich object that encapsulates properties and logic for the
destinations - for example a display name, or formatted address, along with the required properties of MQID and
coordinate. The protocol is defined to allow you maximum flexibility. While the MQID property is required to be
implemented in your class, the property itself can be null. In all cases the location coordinate must be filled in
– even with an MQID. The array of destinations passed into the route request is also available as a property on
the MQRoute
object that you receive back.
The Our Navigation SDK uses a default radius of 50m and which is
optimized for most destinations; however in some cases you may wish to customize the arrival radius of a destination
to better match its size profile. For example a city center or a stadium may be better handled with a larger radius.
To add a custom destination arrival radius, simply implement the CLLocationDistance arrivalAcceptanceRadius
property in your MQRouteDestination
compliant class and set it to a value or 0 to use the default.
If the value is <=0, we will use the default arrival radius. The SDK may evaluate the radius against certain rules and
elect to use it selectively.New in 3.4.0
Upon reaching a destination MQNavigationManager provides an optional delegate method which provides the destination reached and if it is the final destination. If you implement this delegate method you are required to call the acceptance block to continue to the next destination or finish navigation – otherwise MQNavigationManager will assume the destination has been accepted.
By default navigation automatically stops when reaching the final destination. For intermediate destinations, you may want to pause navigation and update the user-interface to allow the user to resume.
@interface Destination : NSObject <MQRouteDestination>
@property (nonatomic, copy) CLLocation* location;
@property (nonatomic, copy, nullable) NSString* mqid;
-(instancetype)initWithLocation:(CLLocation*)location mqID:(nullable NSString*)mqID;
@end
- (void)startNavigation {
//set up start and destination for the route
CLLocation *nyc = [[Destination alloc] initWithLocation:[[CLLocation alloc] initWithLatitude:40.7326808 longitude:-73.9843407] mqID:nil]
CLLocation *boston = [[Destination alloc] initWithLocation:[[CLLocation alloc] initWithLatitude:42.355097 longitude:-71.055464] mqID:nil];
CLLocation *paulRevereHouse = [[Destination alloc] initWithLocation:[[CLLocation alloc] initWithLatitude:42.3637 longitude:-71.0537] mqID:@"173568"];
//set up route options
MQRouteOptions *options = [MQRouteOptions new];
//get route/s from MQRouteService
[self.routeService requestRoutesWithStartLocation:nyc destinations:@[boston, paulRevereHouse] options:options completion:^(NSArray<MQRoute *> * _Nullable routes, NSError * _Nullable error) {
if(error) {
NSLog(@"ERROR:%@",error);
} else if(routes) {
if (routes.count > 0) {
//start navigating with the route.
[self.navigationManager startNavigationWithRoute:routes[0]];
}
}
}];
}
//make your class conform to MQNavigationManagerPromptDelegate protocol
@interface ViewController () <MQNavigationManagerDelegate> {
}
- (void)navigationManager:(nonnull MQNavigationManager *)navigationManager reachedDestination:(nonnull id<MQRouteDestination>)routeDestination forRouteLeg:(nonnull MQRouteLeg *)completedRouteLeg isFinalDestination:(BOOL)isFinalDestination confirmArrival:(nonnull MQConfirmArrivalBlock)confirmArrival {
// Handle Destination
confirmArrival(YES);
}
class Destination: NSObject, MQRouteDestination {
var location: CLLocation
var mqid: String?
required init(location: CLLocation, mqid: String? = nil) {
self.location = location
self.mqid = mqid
}
}
func startNavigation() {
//set up start and destination for the route
fileprivate let nyc = Destination(location: CLLocation(latitude:40.7326808, longitude:-73.9843407), mqid: nil)
fileprivate let boston = Destination(location: CLLocation(latitude:42.355097, longitude:-71.055464), mqid: nil)
fileprivate let paulRevereHouse = Destination(location: CLLocation(latitude:42.3637, longitude:-71.0537), mqid: "173568")
//request route
routeService.requestRoutes(withStart: nyc, destinations:[boston, paulRevereHouse], options: routeOptions) { [weak self] (routes, error) in
guard let strongSelf = self else { return }
//handle error
if let error = error {
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
strongSelf.present(alert, animated: true, completion: nil)
return
}
guard let routes = routes, routes.isEmpty == false else { return }
//start navigation with first route
strongSelf.navigationManager.startNavigation(with: routes[0])
}
}
//make your class conform to MQNavigationManagerPromptDelegate protocol
class ViewController: UIViewController, MQNavigationManagerPromptDelegate {
}
func navigationManager(_ navigationManager: MQNavigationManager, reachedDestination routeDestination: MQRouteDestination, for completedRouteLeg: MQRouteLeg, isFinalDestination: Bool, confirmArrival: @escaping MQConfirmArrivalBlock) {
// Handle Destination
confirmArrival(true)
}
MQNavigation provides battery savings by letting you know if you've been running in the background, on battery, and without moving for a period of time. The framework will call you and you can decide what to do at that point. Some common options include:
/// Called when the app is in the background and navigating, but has not moved enough in a period of time
- (void)navigationManagerBackgroundTimerExpired:(nonnull MQNavigationManager *)navigationManager {
UNMutableNotificationContent* content = [UNMutableNotificationContent new];
content.title = @"Do you wish to continue navigating?";
content.body = @"You haven't moved in awhile while navigation has been in the background. Please let us know if you wish to continue navigating.";
content.sound = [UNNotificationSound default];
content.categoryIdentifier = @"BackgroundTimer";
UNNotificationRequest* request = [UNNotificationRequest initWithIdentifier: @"BackgroundTimerExpired" content: content trigger:nil];
// Schedule the notification
UNUserNotificationCenter* center = [UNUserNotificationCenter current];
[center removeAllPendingNotificationRequests];
[center addRequest:request withCompletionHandler:nil];
}
/// Called when the app is in the background and navigating, but has not moved enough in a period of time
func navigationManagerBackgroundTimerExpired(_ navigationManager: MQNavigationManager) {
let content = UNMutableNotificationContent()
content.title = "Do you wish to continue navigating?"
content.body = "You haven't moved in awhile while navigation has been in the background. Please let us know if you wish to continue navigating."
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "BackgroundTimer"
let request = UNNotificationRequest(identifier: "BackgroundTimerExpired", content: content, trigger: nil)
// Schedule the notification.
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
center.add(request, withCompletionHandler: nil)
}
The MapQuest Navigation SDK is designed to collect location data during active navigation sessions in order to improve the quality of our routes and traffic data. Verizon/MapQuest believes the user's privacy is of the highest importance. Your application is required to request explicit consent to collect location data and to use it for the purposes enumerated below before navigation will proceed. Verizon may share de-identified location information with third parties for limited aggregate purposes, such as traffic reporting.
Your in-app disclosure language should include:
MQNavigationManager's userLocationTrackingConsentStatus
flag has three possible states:
While in the awaiting consent state, navigation will not start and you will receive an error that consent has not been set. You may persist the user's response and set it for future navigation sessions.
The MapQuest Navigation SDK provides the NSError domain MQNavigationErrorDomain and a list of potential error codes listed in the MQNavigation SDK Documentation. Furthermore we also provide a set of error delegate methods that provide error information for situations such as:
Refer to the Navigation SDK Reference Sample Application code to see a complete example of how to leverage the MQNavigation iOS SDK to create turn-by-turn navigation experience.