Guidance

YMKGuidance contains information on the current guidance session and lets you follow events in guidance mode. Use the YMKNavigation.guidance method to get it.

Track location

By default, YMKNavigation is created in suspended mode, where location isn't tracked and guidance is off. To start tracking the current device location, use resumed mode. That keeps the user's location up to date.

To manage the location tracking mode, use the YMKNavigation.resume() and YMKNavigation.suspend() methods.

Tip

It's a good idea to switch YMKNavigation to suspended mode when you collapse the app and the map and switch it back to resumed when you reopen the app.

We don't recommend switching YMKNavigation to suspended mode for the background guidance scenario.

Start/stop guidance

To start route guidance, use the YMKNavigation.startGuidance(with:) method. It takes the route as its only argument.

To stop guidance, use the matching YMKNavigation.stopGuidance() method.

Note

The number of possible active guidance sessions is limited. There can only be one active guidance session at a time.

Guidance data

Let's look at the main data YMKGuidance provides access to.

  • Current route: YMKGuidance.currentRoute() contains the route where guidance is currently active or the null value if guidance is inactive. In guidance mode, the current route can change, for example, if the user deviates from the route or chooses an alternate route.

  • User location: YMKGuidance.location contains the current user location. That includes the location coordinates, current direction, location precision, guidance speed, and more.

  • Speeding: YMKGuidance.speedLimit and YMKGuidance.speedLimitStatus provide information on the speed limit for the current route section. YMKGuidance.speedLimitsPolicy provides information about speed limits for different areas in the current region (in the city, outside the city, and on highways).

The complete API is available in the YMKGuidance documentation.

Windshield

The YMKNavigationWindshield entity is used to provide information about oncoming maneuvers on the route, road markings and events, speed limits, and road signs.

To access the YMKNavigationWindshield instance, use the YMKGuidance.windshield method.

The YMKNavigationWindshield entity status is defined by the following data:

  • Maneuvers: Using YMKGuidance.Manoeuvres, you can get a list of maneuvers on the route. Each maneuver is described by its position on the route, location, and the YMKDrivingAnnotation instance that contains information about its type.

  • Road markings: YMKGuidance.laneSigns returns a list where each instance contains information about the lane the user must be on. It is characterized by its position on the route and the YMKDrivingLaneSign instance, which defines the road markings type at a road section. The YMKDrivingLaneSign instance contains the list of YMKDrivingLane with information about each separate traffic lane, its direction, type, and possible maneuvers.

  • Road events: Using YMKGuidance.roadEvents, you can get a list of road events on the route as well as information about speed limits.

  • Road signs: The YMKGuidance.directionSigns method returns a list of road signs on the route. For example, a sign that indicates the next route section includes a tunnel or a highway

Using YMKNavigationWindshieldListener, you can follow YMKNavigationWindshield status change events.

You can see an example of how YMKNavigationWindshield can be used for implementing the UI component that displays information about the next maneuver and lane markings in the demo app.

Events

In guidance mode, the guidance status changes constantly. Use the YMKGuidanceListener interface to follow guidance events.

class GuidanceListener: NSObject, YMKGuidanceListener {
    func onLocationChanged() {}
    func onCurrentRouteChanged(with reason: YMKRouteChangeReason) {}
    func onRouteLost() {}
    func onReturnedToRoute() {}
    func onRouteFinished() {}
    func onWayPointReached() {}
    func onStandingStatusChanged() {}
    func onRoadNameChanged() {}
    func onSpeedLimitUpdated() {}
    func onSpeedLimitStatusUpdated() {}
    func onAlternativesChanged() {}
    func onFastestAlternativeChanged() {}
}
let guidanceListener = GuidanceListener()
guidance.addListener(with: guidanceListener)

YMKGuidanceListener lets you follow navigation events (deviation from the route, return to the route, and arrival at intermediate and final stops) and guidance status changes (for the current user location, street name, speed limit information, list of alternatives, and more).

Guidance alternatives

Local alternatives are the alternate routes available in guidance mode. They're recalculated automatically. To follow this event, use the YMKGuidanceListener.onAlternativesChanged() method.

To switch from the current route to an alternate one, use the YMKGuidance.switchToRoute(with:) method.

Faster alternative routes

Route guidance sessions might sometimes last as long as several hours. In these cases, the initially built route might become outdated and less convenient with time. This is relevant for city guidance since the traffic situation might change quite often. NaviKit SDK solves this problem and provides an opportunity to get a faster alternative route.

The YMKGuidance.fastestAlternative method returns information about a faster alternative route, if one exists. Start guidance along such a route to change the current route to a faster one.

Using the YMKGuidanceListener.onFastestAlternativeChanged() handler method, you can follow notifications about changes in the faster route.

Annotations

To set up voice guidance (voice annotations) for the route, use the YMKAnnotator class.

To enable and disable annotations, use the YMKAnnotator.mute() and YMKAnnotator.unmute() methods.

For the annotator to start working, add a YMKSpeaker delegate to it and implement it yourself.

Note

NaviKit SDK doesn't provide YMKSpeaker implementation.

There's an example of YMKSpeaker implementation using the iOS AVSpeechSynthesizer in the demo app.

To change the annotation language, use the YMKNavigation.annotationLanguage method.

Annotations are divided into two types: YMKAnnotatedRoadEvents are related to road events and YMKAnnotatedEvents are related to route warnings. You can manage the amount of activity for specific annotations using the YMKAnnotator.annotatedRoadEvents and YMKAnnotator.annotatedEvents methods.

You can follow YMKAnnotator class events using the YMKAnnotatorListener interface. It notifies you about annotator actions (the type of event that was performed).

Restore status

You can restore the guidance status by serializing/deserializing YMKNavigation.

  1. To do so, serialize YMKNavigation using the YMKNavigationSerialization.serialize(_:) method.

    let serializedNavigation = YMKNavigationSerialization().serialize(navigation)
    
  2. serializedNavigation now contains a navigation copy. You can save it to a disk and later restore it using deserialization.

  3. Using YMKNavigationSerialization.deserialize(_:), create a new navigation instance.

    let navigation = YMKNavigationSerialization().deserialize(serializedNavigation)
    

Before closing the app, you can save YMKNavigation to a disk and restore it when you open the app again later. Because guidance status is in YMKGuidance and guidance is part of YMKNavigation, it'll also be restored, and the last guidance session will continue.

There's an example of how to implement the logic for restoring guidance statuses in the demo app.

Guidance simulation

When developing and testing navigation apps, you may need to check how the guidance scenario works. To do so, use third-party tools for simulating user locations or the ready-made simulation API in NaviKit SDK.

To enable location simulation along a route or in an arbitrary direction, use the YMKLocationSimulator class.

Here's an example of how to implement the guidance simulation manager:

class SimulationManager: NSObject, YMKLocationSimulatorListener {

    // MARK: - Public methods

    func startSimulation(route: YMKDrivingRoute) {
        locationSimulator = YMKMapKit.sharedInstance().createLocationSimulator(withGeometry: route.geometry)

        locationSimulator.subscribeForSimulatorEvents(with: self)
        locationSimulator.speed = 20.0

        YMKMapKit.sharedInstance().setLocationManagerWith(locationSimulator)

        locationSimulator.startSimulation(with: .coarse)
    }

    func resetSimulation() {
        locationSimulator?.unsubscribeFromSimulatorEvents(with: self)
        locationSimulator = nil
        YMKMapKit.sharedInstance().resetLocationManagerToDefault()
    }

    func setSpeed(value: Double) {
        locationSimulator?.speed = speed
    }

    // MARK: - Private properties

    private var locationSimulator: YMKLocationSimulator!
}

The startSimulation method accepts the route for guidance simulation. When you use YMKMapKit.createLocationSimulator(withGeometry:), a new YMKLocationSimulator is created. You need to configure it:

  1. Follow the simulation finish event using YMKLocationSimulatorListener.
  2. Set the movement speed value.
  3. Change the YMKLocationManager implementation to the newly created locationSimulator.
  4. Start the simulation.

The simulation is reset in resetSimulation. With YMKMapKit.resetLocationManagerToDefault(), the location simulation manager changes to the default option, which reads the user's current location.

There's a detailed example of route simulation in the demo app.

Background guidance

Background guidance refers to a guidance session that can continue even after the application is moved to the background.

After the application moves to the background, the iOS system may suspend it to free up resources. For the iOS app to work even when application is in the background, it could track the device location.

To implement background guidance, subscribe to device location changes when the app is moved to the background. After the app is closed, YMKNavigation must stay in resumed mode. That way, the app won't be killed by the iOS system, and voice guidance will work in background mode.

Note

NaviKit SDK does not create a location subscription, so it does not guarantee that the application will work in a background. To implement the background guidance scenario, you need to implement location subscription by yourself.

There's an example of the background guidance service in the demo app.