Use this guide to enable your app to listen and respond to a variety of events that change as a user navigates along a route. This guide does not cover defining a route, only responding to events along a route.
Overview
The Navigation SDK for iOS provides you with listeners
associated with the location of the user and conditions along the route and
important time and distance data. On the view controller of the map, your app
needs to adopt the protocols for these listeners: GMSRoadSnappedLocationProviderListener
and GMSNavigatorListener
.
This list shows the listener methods available for navigation events:
-
GMSNavigatorListener.didArriveAtWaypoint
, triggered when a destination is reached. -
GMSNavigatorListener.navigatorDidChangeRoute
, triggered when the route changes. -
GMSNavigatorListener.didUpdateRemainingTime
, called repeatedly as the time to the next destination changes, while guidance is active. -
GMSNavigatorListener.didUpdateRemainingDistance
, called repeatedly as the distance to the next destination changes, while guidance is active. -
GMSNavigatorListener.didUpdateDelayCategory
, called when the delay category to the next destination changes, while guidance is active. -
GMSNavigatorListener.didChangeSuggestedLightingMode
, triggered when the estimated lighting conditions are updated. For example when night falls at the user's current location the lighting changes. -
GMSNavigatorListener.didUpdateSpeedingPercentage
, triggered when the driver is exceeding the speed limit. -
GMSRoadSnappedLocationProviderListener.didUpdateLocation
, called repeatedly as the user's location changes.
See the code
Declaring conformance to the required protocols
Before implementing the navigation methods, the view controller must adopt the protocols:
Swift
class
ViewController
:
UIViewController
,
GMSNavigatorListener
,
GMSRoadSnappedLocationProviderListener
{
Objective-C
@interface
ViewController
()
< GMSNavigatorListener
,
GMSRoadSnappedLocationProviderListener
> @end
After adopting the navigation protocols, set the listeners to the view
controller. For example, you can add the following code to the viewDidLoad()
method.
Swift
mapView
.
navigator
?.
add
(
self
)
mapView
.
roadSnappedLocationProvider
?.
add
(
self
)
Objective-C
[
_mapView
.
navigator
addListener
:
self
];
[
_mapView
.
roadSnappedLocationProvider
addListener
:
self
];
Receiving or stopping location updates
Location updates are required for showing the user's progress on the map.
The location
instance exposes the following properties:
Location property | Description |
---|---|
altitude | Current altitude. |
coordinate.latitude | Current road-snapped latitude coordinate. |
coordinate.longitude | Current road-snapped longitude coordinate. |
course | Current bearing in degrees. |
speed | Current speed. |
timestamp | Date/time of current reading. |
To receive continuous location updates, call mapView.roadSnappedLocationProvider.startUpdatingLocation
, and use the GMSRoadSnappedLocationProviderListener
to handle the didUpdateLocation
event.
The following example shows calling startUpdatingLocation
:
Swift
mapView
.
roadSnappedLocationProvider
.
startUpdatingLocation
()
Objective-C
[
_mapView
.
roadSnappedLocationProvider
startUpdatingLocation
];
The following code creates a GMSRoadSnappedLocationProviderListener
that
handles the didUpdateLocation
event.
Swift
func
locationProvider
(
_
locationProvider
:
GMSRoadSnappedLocationProvider
,
didUpdate
location
:
CLLocation
)
{
print
(
"Location:
\(
location
.
description
)
"
)
}
Objective-C
-
(
void
)
locationProvider:
(
GMSRoadSnappedLocationProvider
*
)
locationProvider
didUpdateLocation
:(
CLLocation
*
)
location
{
NSLog
(
@"Location: %@"
,
location
.
description
);
}
To receive location updates when the app is in the background, set allowsBackgroundLocationUpdates
to true:
Swift
mapView
.
roadSnappedLocationProvider
.
allowsBackgroundLocationUpdates
=
true
Objective-C
_mapView
.
roadSnappedLocationProvider
.
allowsBackgroundLocationUpdates
=
YES
;
Detecting arrival events
Your app uses the didArriveAtWaypoint
event to detect when a destination has
been reached. You can resume guidance and advance to the next waypoint by
calling continueToNextDestination()
, and then re-enabling guidance. Your app
must re-enable guidance after
calling continueToNextDestination()
.
After the app calls continueToNextDestination
, the navigator no longer has
data about the previous destination. If you want to analyze information about a
route leg, you must retrieve this from the navigator prior to calling continueToNextDestination()
.
The following code example shows a method to handle the didArriveAtWaypoint
event:
Swift
func
navigator
(
_
navigator
:
GMSNavigator
,
didArriveAt
waypoint
:
GMSNavigationWaypoint
)
{
print
(
"You have arrived at:
\(
waypoint
.
title
)
"
)
mapView
.
navigator
?.
continueToNextDestination
()
mapView
.
navigator
?.
isGuidanceActive
=
true
}
Objective-C
-
(
void
)
navigator:
(
GMSNavigator
*
)
navigator
didArriveAtWaypoint
:(
GMSNavigationWaypoint
*
)
waypoint
{
NSLog
(
@"You have
arrived
at
:
%
@", waypoint.title); [_mapView.navigator
continueToNextDestination
];
_mapView
.
navigator
.
guidanceActive
=
YES
;
}
Receiving route change updates
To receive a notification whenever the route is changed, create a method to
handle the navigatorDidChangeRoute
event. You can access the new route by
using the routeLegs
and currentRouteLeg
properties of GMSNavigator
.
Swift
func
navigatorDidChangeRoute
(
_
navigator
:
GMSNavigator
)
{
print
(
"The route has
changed."
)
}
Objective-C
-
(
void
)
navigatorDidChangeRoute:
(
GMSNavigator
*
)
navigator
{
NSLog
(
@"The route
has
changed
.
"); }
Receiving time to destination updates
To receive continuous time to destination updates, create a method to handle the didUpdateRemainingTime
event. The time
parameter provides the estimated
time, in seconds, until the next destination is reached.
Swift
func
navigator
(
_
navigator
:
GMSNavigator
,
didUpdateRemainingTime
time
:
TimeInterval
)
{
print
(
"Time to next destination:
\(
time
)
"
)
}
Objective-C
-
(
void
)
navigator:
(
GMSNavigator
*
)
navigator
didUpdateRemainingTime
:(
NSTimeInterval
)
time
{
NSLog
(
@"Time to next
destination
:
%
f
", time); }
To set the minimum change in estimated time to the next destination, set the timeUpdateThreshold
property on GMSNavigator
. The value is specified in
seconds. If this property is not set, the services use a default value of one
second.
Swift
navigator
?.
timeUpdateThreshold
=
10
Objective-C
navigator
.
timeUpdateThreshold
=
10
;
Receiving distance to destination updates
To receive continuous distance to destination updates, create a method to handle
the didUpdateRemainingDistance
event. The distance
parameter provides the
estimated distance, in meters, to the next destination.
Swift
func
navigator
(
_
navigator
:
GMSNavigator
,
didUpdateRemainingDistance
distance
:
CLLocationDistance
)
{
let
miles
=
distance
*
0.00062137
print
(
"Distance to next
destination:
\(
miles
)
miles."
)
}
Objective-C
-
(
void
)
navigator:
(
GMSNavigator
*
)
navigator
didUpdateRemainingDistance
:(
CLLocationDistance
)
distance
{
double
miles
=
distance
*
0.00062137
;
NSLog
(
@"%@"
,
[
NSString
stringWithFormat
:
@"Distance to
next
destination
:
%
.2f
.
", miles]); }
To set the minimum change in estimated distance to the next destination, set the distanceUpdateThreshold
property on GMSNavigator
(value is specified in
meters). If this property is not set, the services use a default value of one
meter.
Swift
navigator
?.
distanceUpdateThreshold
=
100
Objective-C
navigator
.
distanceUpdateThreshold
=
100
;
Receiving traffic updates
To receive continuous updates of the traffic flow for the remaining route,
create a method to handle the didUpdateDelayCategory
event. A call to delayCategoryToNextDestination
returns GMSNavigationDelayCategory
which
provides a value of 0 to 3. Updates to the category are based on the current
position of the app user. If traffic data is unavailable, GMSNavigationDelayCategory
returns 0. The numbers, 1-3, indicate increasing
flow from light to heavy.
Swift
func
navigator
(
_
navigator
:
GMSNavigator
,
didUpdate
delayCategory
:
GMSNavigationDelayCategory
)
{
print
(
"Traffic flow to next destination:
\(
delayCategory
)
"
)
}
Objective-C
-
(
void
)
navigator:
(
GMSNavigator
*
)
navigator
didUpdateDelayCategory
:(
GMSNavigationDelayCategory
)
delayCategory
{
NSLog
(
@"Traffic flow to next destination: %ld"
,
(
long
)
delayCategory
);
}
The GMSNavigationDelayCategory
property exposes the following delay levels:
Delay category | Description |
---|---|
GMSNavigationDelayCategoryNoData | 0 - Unavailable, no data for traffic or : |
the route. | |
GMSNavigationDelayCategoryHeavy | 1 - Heavy. |
GMSNavigationDelayCategoryMedium | 2 - Medium. |
GMSNavigationDelayCategoryLight | 3 - Light. |
Receiving speeding updates
To receive updates when a driver is exceeding the speed limit, create a method
to handle the didUpdateSpeedingPercentage
event.
Swift
// Listener to handle speeding events. func navigator( _ navigator:
GMSNavigator
,
didUpdateSpeedingPercentage
percentageAboveLimit
:
CGFloat
)
{
print
(
"Speed is
\(
percentageAboveLimit
)
above the limit."
)
}
Objective-C
// Listener to handle speeding events. - (void)navigator:(GMSNavigator
*
)
navigator
didUpdateSpeedingPercentage
:
(
CGFloat
)
percentageAboveLimit
{
NSLog
(
@"Speed is %f percent above the limit."
,
percentageAboveLimit
);
}
Changing suggested lighting mode
To receive updates for estimated changes in lighting, create a method to handle
the didChangeSuggestedLightingMode
event.
Swift
// Define a listener for suggested changes to lighting mode. func navigator(_
navigator
:
GMSNavigator
,
didChangeSuggestedLightingMode
lightingMode
:
GMSNavigationLightingMode
)
{
print
(
"Suggested lighting mode has changed:
\(
String
(
describing
:
lightingMode
))
"
)
// Make the suggested change. mapView.lightingMode = lightingMode }
Objective-C
// Define a listener for suggested changes to lighting mode.
-(
void
)
navigator:
(
GMSNavigator
*
)
navigator
didChangeSuggestedLightingMode:
(
GMSNavigationLightingMode
)
lightingMode
{
NSLog
(
@"Suggested lighting mode has
changed
:
%
ld
", (long)lightingMode);
// Make the suggested change. _mapView.lightingMode = lightingMode; }