Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions Sources/MapboxCoreNavigation/LegacyRouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,27 @@ open class LegacyRouteController: NSObject, Router, InternalRouter, CLLocationMa
var lastRerouteLocation: CLLocation?

public var initialManeuverAvoidanceRadius: TimeInterval = RerouteController.DefaultManeuverAvoidanceRadius

public var refreshesRoute: Bool = true


/**
Controls whether the route controller automatically updates ETA and traffic congestion data.

When enabled, the route controller periodically refreshes route information at intervals defined by `RouteControllerProactiveReroutingInterval`.
By default, route refreshing is enabled only for routes using `.automobileAvoidingTraffic` or another `driving-traffic` profile.
If `reroutesProactively` is also enabled, the route controller runs the rerouting check after the route refresh completes.

- Important: Route refresh is currently supported only for `driving-traffic` profiles. Enabling this property for other profiles (such as walking, cycling, or standard driving) may result in server errors or undefined behavior.
*/
public var refreshesRoute: Bool {
didSet {
if refreshesRoute {
let profile = indexedRouteResponse.validatedRouteOptions.profileIdentifier
if !profile.isAutomobileAvoidingTraffic {
Log.error("An incorrect route refresh was enabled for :\(profile.rawValue) navigation profile.", category: .navigation)
}
}
}
}

var lastRouteRefresh: Date?

var isRefreshing = false
Expand Down Expand Up @@ -272,7 +290,7 @@ open class LegacyRouteController: NSObject, Router, InternalRouter, CLLocationMa
let options = indexedRouteResponse.validatedRouteOptions
self.routeProgress = RouteProgress(route: indexedRouteResponse.currentRoute!, options: options)
self.dataSource = source
self.refreshesRoute = options.profileIdentifier.isAutomobileAvoidingTraffic && options.refreshingEnabled
self.refreshesRoute = indexedRouteResponse.supportsRefreshes
UIDevice.current.isBatteryMonitoringEnabled = true

super.init()
Expand Down
43 changes: 34 additions & 9 deletions Sources/MapboxCoreNavigation/RouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,27 @@ open class RouteController: NSObject {
rerouteController.initialManeuverAvoidanceRadius = newValue
}
}

public var refreshesRoute: Bool = true


/**
Controls whether the route controller automatically updates ETA and traffic congestion data.

When enabled, the route controller periodically refreshes route information at intervals defined by `RouteControllerProactiveReroutingInterval`.
By default, route refreshing is enabled only for routes using `.automobileAvoidingTraffic` or another `driving-traffic` profile.
If `reroutesProactively` is also enabled, the route controller runs the rerouting check after the route refresh completes.

- Important: Route refresh is currently supported only for `driving-traffic` profiles. Enabling this property for other profiles (such as walking, cycling, or standard driving) may result in server errors or undefined behavior.
*/
public var refreshesRoute: Bool {
didSet {
if refreshesRoute {
let profile = indexedRouteResponse.validatedRouteOptions.profileIdentifier
if !profile.isAutomobileAvoidingTraffic {
Log.error("An incorrect route refresh was enabled for :\(profile.rawValue) navigation profile.", category: .navigation)
}
}
}
}

var isRefreshing = false

var lastRouteRefresh: Date?
Expand Down Expand Up @@ -643,7 +661,7 @@ open class RouteController: NSObject {
guard !hasFinishedRouting else { return }
navigationSessionManager.reportStopNavigation()
}

private static func checkUniqueInstance() {
Self.instanceLock.lock()
let twoInstances = Self.instance != nil
Expand Down Expand Up @@ -671,14 +689,10 @@ open class RouteController: NSObject {
self.indexedRouteResponse = indexedRouteResponse
self.dataSource = source

var isRouteOptions = false
if case .route = indexedRouteResponse.routeResponse.options {
isRouteOptions = true
}
let options = indexedRouteResponse.validatedRouteOptions

self.routeProgress = RouteProgress(route: indexedRouteResponse.currentRoute!, options: options)
self.refreshesRoute = isRouteOptions && options.profileIdentifier.isAutomobileAvoidingTraffic && options.refreshingEnabled
self.refreshesRoute = indexedRouteResponse.supportsRefreshes

super.init()

Expand All @@ -702,6 +716,7 @@ open class RouteController: NSObject {
let options = indexedRouteResponse.validatedRouteOptions
self.routeProgress = RouteProgress(route: indexedRouteResponse.currentRoute!, options: options)
self.navigationSessionManager = navigationSessionManager
self.refreshesRoute = indexedRouteResponse.supportsRefreshes

super.init()

Expand Down Expand Up @@ -1209,3 +1224,13 @@ public enum AlternativeRouteError: Swift.Error {
/// The navigation engine has failed to provide alternatives.
case failedToUpdateAlternativeRoutes(reason: String)
}

extension IndexedRouteResponse {
var supportsRefreshes: Bool {
guard case .route = routeResponse.options else {
return false
}
return validatedRouteOptions.profileIdentifier.isAutomobileAvoidingTraffic && validatedRouteOptions.refreshingEnabled

}
}
10 changes: 7 additions & 3 deletions Sources/MapboxCoreNavigation/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,13 @@ public protocol Router: CLLocationManagerDelegate {
var reroutesProactively: Bool { get set }

/**
If true, the `RouteController` attempts to update ETA and route congestion on an interval defined by `RouteControllerProactiveReroutingInterval`.

Refreshing will be used only if route's mode of transportation profile is set to `.automobileAvoidingTraffic`. If `reroutesProactively` is enabled too, rerouting will be checked after route is refreshed.
Controls whether the route controller automatically updates ETA and traffic congestion data.

When enabled, the route controller periodically refreshes route information at intervals defined by `RouteControllerProactiveReroutingInterval`.
By default, route refreshing is enabled only for routes using `.automobileAvoidingTraffic` or another `driving-traffic` profile.
If `reroutesProactively` is also enabled, the route controller runs the rerouting check after the route refresh completes.

- Important: Route refresh is currently supported only for `driving-traffic` profiles. Enabling this property for other profiles (such as walking, cycling, or standard driving) may result in server errors or undefined behavior.
*/
var refreshesRoute: Bool { get set }

Expand Down
24 changes: 24 additions & 0 deletions Tests/MapboxCoreNavigationTests/RouteControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,30 @@ class RouteControllerTests: TestCase {
customRoutingProvider: routingProvider,
dataSource: dataSource)
XCTAssertFalse(controller2.refreshesRoute, "Should not refresh for automobile")

indexedRouteResponse.validatedRouteOptions.profileIdentifier = .init(rawValue: "custom/driving-traffic")
let controller3 = RouteController(indexedRouteResponse: indexedRouteResponse,
customRoutingProvider: routingProvider,
dataSource: dataSource)
XCTAssertTrue(controller3.refreshesRoute, "Should refresh for custom driving traffic")

let mapMatchinOptions = NavigationMatchOptions(
coordinates: [
.init(latitude: 59.3379254707993, longitude: 18.0768391763866),
.init(latitude: 59.3376613543215, longitude: 18.0758977499228),
.init(latitude: 59.3371292341531, longitude: 18.0754779388695),
],
profileIdentifier: .automobileAvoidingTraffic)
let response = Fixture.mapMatchingResponse(from: "route-doubling-back", options: mapMatchinOptions)
let routeRseponse = try! RouteResponse(
matching: response,
options: mapMatchinOptions,
credentials: .mocked)
let indexedResponse = IndexedRouteResponse(routeResponse: routeRseponse, routeIndex: 0)
let controller4 = RouteController(indexedRouteResponse: indexedResponse,
customRoutingProvider: routingProvider,
dataSource: dataSource)
XCTAssertFalse(controller4.refreshesRoute, "Should not refresh for map matching response")
}

func testReturnIsFirstLocation() {
Expand Down