Ведение

YMKGuidance - содержит информацию о текущей сессии ведения, позволяет подписаться на различные события во время ведения. Для его получения используйте метод YMKNavigation.guidance.

Отслеживание локации

По умолчанию, YMKNavigation создается в режиме suspended, в котором локация не отслеживается и ведение не работает. Для включения отслеживания текущей локации устройства, чтобы местоположение пользователя оставалось актуальным, используется режим resumed.

Для управления режимом слежения за локацией используются методы YMKNavigation.resume() и YMKNavigation.suspend().

Совет

Хорошей практикой является переключение YMKNavigation в режим suspended при сворачивании приложение с картой, и переключение в resumed при повторном открытии приложения.

Не рекомендуется переводить YMKNavigation в режим suspended если вы реализуете сценарий фонового ведения.

Старт/стоп ведения

Начать ведение по маршруту можно с помощью метода YMKNavigation.startGuidance(with:). В качестве единственного аргумента он принимает маршрут, по которому начнется ведение.

Для окончание ведения существует симметричный метод YMKNavigation.stopGuidance().

Примечание

Число возможных активных сессий ведения ограничено. В любой возможный момент времени можно иметь не больше одной запущенной сессии ведения.

Данные во время ведении

Рассмотрим основные данные, доступ к которым предоставляет YMKGuidance во время ведения.

  • Текущий маршрут - YMKGuidance.currentRoute() содержит маршрут, по которому в текущий момент активно ведение, либо значение null если ведения нет. В ходе ведения текущий маршрут может быть изменен, если, например, пользователь съехал с маршрута или был выбран другой альтернативный маршрут.

  • Локация пользователя - YMKGuidance.location содержит текущую локацию пользователя. Она состоит из координат, определяющих местоположение, текущего направления, точности определения локации, скорости ведения и т.д.

  • Превышение скорости - YMKGuidance.speedLimit и YMKGuidance.speedLimitStatus предоставляют информацию о максимально разрешенной скорости на данном участке маршрута. YMKGuidance.speedLimitsPolicy содержит информацию о скоростных ограничений для данного региона в различных местностях (в городе, загородом и на шоссе).

Полный API приведен в документации YMKGuidance.

Windshield

С помощью сущности YMKNavigationWindshield предоставляется информация о предстоящих маневрах на маршруте, о дорожной разметке и событиях, скоростных ограничениях и указателях.

Для обращения к объекту YMKNavigationWindshield используется метод YMKGuidance.windshield.

Состояние сущности YMKNavigationWindshield определяется следующими данным:

  • Маневры - с помощью YMKGuidance.Manoeuvres можно получить список предстоящих маневров на маршруте. Каждый маневр описывается позицией на маршруте, его местоположением и объектом YMKDrivingAnnotation, который содержит информацию о его типе.

  • Дорожная разметка - YMKGuidance.laneSigns возвращает список, где каждый элемент содержит информацию в какой полосе дороги пользователь должен находиться, он характеризуется позицией на маршруте, и объектом YMKDrivingLaneSign, который определяет вид разметки на данном участке дороги. Объект YMKDrivingLaneSign содержит список YMKDrivingLane с информацией о каждой конкретной полосе дороги, ее направлении, типе и вариантах маневров.

  • Дорожные события - при помощи YMKGuidance.roadEvents можно получить список предстоящих дорожных событий на маршруте вместе с информацией о скоростных ограничениях.

  • Указатели - метод YMKGuidance.directionSigns возвращает список предстоящих указателей на дороге. Например, указатель того, что следующий участок маршрута будет проходить через туннель или через скоростное шоссе.

С помощью YMKNavigationWindshieldListener можно подписаться на события изменения состояния YMKNavigationWindshield.

С примером использования YMKNavigationWindshield для реализации UI-компонента, который отображает информацию о следующем маневре и полосной разметке, можно ознакомиться в демо-приложении.

События

В ходе ведения приложения состояние ведения постоянно изменяется. Для подписки на события ведения используется интерфейс YMKGuidanceListener.

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 предоставляет возможность подписаться на события навигации (съезда с маршрута, возвращение к маршруту, достижение промежуточных и конечных точек маршрута) и изменения состояния ведения (текущей локации пользователя, маршрута, названия улицы, информации о лимитах скорости, списка альтернатив и т.д).

Альтернативы во время ведения

Альтернативные маршруты, которые доступны во время ведения, называются локальными альтернативами. Они имеют свойство автоматически перестраиваться. Для подписки на это событие используется метод YMKGuidanceListener.onAlternativesChanged().

Для смены текущего маршрута на альтернативный используется метод YMKGuidance.switchToRoute(with:).

Более быстрые альтернативы

Сессия ведения по маршруту может быть очень продолжительной, иногда достигать нескольких часов. В таких случаях маршрут, который был построен на момент начала ведения, через некоторое время может устареть и стать не таким оптимальным. Эта проблема особенно актуальна при ведении в городе, где дорожная ситуация на дороге способна меняться достаточно часто. NaviKit SDK решает данную проблему и предоставляет возможность получить более быстрый альтернативный маршрут.

Метод YMKGuidance.fastestAlternative возвращает информацию о более быстрой альтернативе во время ведения, если она существует. Начните ведение по такому маршруту, чтобы изменить текущий маршрут на более оптимальный.

При помощи метода-обработчика YMKGuidanceListener.onFastestAlternativeChanged() можно подписаться на оповещения об изменении более быстрого маршрута.

Аннотации

Для настройки голосовых подсказок на маршруте (голосовых аннотаций), используется класс YMKAnnotator.

Для включения и выключения аннотаций используются методы YMKAnnotator.mute() и YMKAnnotator.unmute().

Чтобы аннотатор начал свою работу необходимо добавить в него делегат - объект с типом YMKSpeaker, который нужно реализовать самостоятельно.

Примечание

NaviKit SDK не предоставляет свою реализацию YMKSpeaker.

С примером реализации YMKSpeaker с помощью iOS AVSpeechSynthesizer можно ознакомиться в демо-приложении.

Язык аннотаций можно изменять при помощи метода YMKNavigation.annotationLanguage.

Аннотации делятся на несколько видов, связанные с дорожными событиями YMKAnnotatedRoadEvents и с предупреждениями на маршруте YMKAnnotatedEvents. При помощи методов YMKAnnotator.annotatedRoadEvents и YMKAnnotator.annotatedEvents можно изменять активность отдельных аннотаций.

Существует возможность подписаться на события класса YMKAnnotator с помощью интерфейса YMKAnnotatorListener. Он оповещает о действиях аннотатора - какой тип события был воспроизведен.

Восстановление состояния

Существует возможность восстановления состояния ведения при помощи механизма сериализации/десериализации YMKNavigation.

  1. Сначала сериализуйте YMKNavigation, используя метод YMKNavigationSerialization.serialize(_:).

    let serializedNavigation = YMKNavigationSerialization().serialize(navigation)
    
  2. Теперь в serializedNavigation хранится слепок навигации. Его можно куда-нибудь сохранить, например на диск, а позже восстановить используя десериализацию.

  3. С помощью YMKNavigationSerialization.deserialize(_:) создайте новый инстанс навигации.

    let navigation = YMKNavigationSerialization().deserialize(serializedNavigation)
    

Таким образом, перед закрытием приложения можно сохранить YMKNavigation на диск, и затем при следующем открытии восстановить его. Так как состояние ведения содержится в YMKGuidance, а ведение является частью YMKNavigation, оно тоже восстановится и последняя сессия ведения продолжится.

С примером реализации логики восстановления состояния ведения можно ознакомиться в нашем демо-приложении.

Симуляция ведения

В ходе разработки и тестирования навигационных приложений часто требуется проверить как работает сценарий ведения по маршруту. Для этого можно использовать сторонние средства симуляции локации пользователя или воспользоваться готовым API симуляции из NaviKit SDK.

Cуществует возможность включения симуляции движения по маршруту или произвольной траектории, для этого используется YMKLocationSimulator класс.

Пример реализации менеджера для симуляции ведения по маршруту:

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!
}

Метод startSimulation принимает маршрут, по которому должна начаться симуляция ведения. Затем при помощи YMKMapKit.createLocationSimulator(withGeometry:) создается новый экземпляр YMKLocationSimulator, который нужно сконфигурировать:

  1. подписаться на событие завершения симуляции при помощи YMKLocationSimulatorListener;
  2. выставить значение скорости движения во время ведения;
  3. заменить реализацию YMKLocationManager на только что созданный locationSimulator;
  4. начать симуляцию.

В resetSimulation происходит сброс симуляции. При помощи YMKMapKit.resetLocationManagerToDefault() менеджер симуляции локации меняется на вариант по умолчанию, который считывает настоящую позицию пользователя.

Более подробно с примером реализации симуляции по маршруту можно ознакомиться в демо-приложении.

Фоновое ведение

Фоновым ведением называется такая сессия ведения, которая способна продолжаться после того, как приложение перешло в фоновый режим.

После того, как приложение переходит в фоновый режим, система iOS может завершить работу приложения для освобождения ресурсов. Для обеспечения работы iOS-приложения в фоне, можено использовать механизм отслеживания локации устройства.

Для реализации фонового ведения подпишитесь на изменения локации устройства, когда приложение перейдет в фоновый режим. После закрытия приложения YMKNavigation должен оставаться в режиме resumed. В этом случае приложение будет защищено от уничтожения со стороны iOS-системы и ведение с голосовыми подсказками будет работать в фоновом режиме.

Примечание

NaviKit SDK не осуществляет подписку на локацию, следовательно, не обеспечивает работу приложения в фоновом режиме. Для реализации сценария фонового ведение вам потребуется реализовать подписку на локацию самостоятельно.

С примером реализации сервиса фонового ведения можно ознакомиться в демо-приложении.