Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directions Interface Compatibility Update #2350

Merged
merged 20 commits into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 5.6
binary "https://www.mapbox.com/ios-sdk/MapboxNavigationNative.json" ~> 6.2.1
github "mapbox/mapbox-directions-swift" == 1.0.0-alpha.1
github "mapbox/mapbox-directions-swift" "jerrad/directions-use-result" #== 1.0.0-alpha.1
github "mapbox/turf-swift" ~> 0.3
github "mapbox/mapbox-events-ios" ~> 0.10
github "ceeK/Solar" ~> 2.1.0
Expand Down
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ github "Quick/Nimble" "v8.0.5"
github "Quick/Quick" "v2.2.0"
github "ceeK/Solar" "2.1.0"
github "mapbox/MapboxGeocoder.swift" "v0.10.2"
github "mapbox/mapbox-directions-swift" "v1.0.0-alpha.1"
github "mapbox/mapbox-directions-swift" "742f1d944b5484734a504c5b72567d16769efb25"
github "mapbox/mapbox-events-ios" "v0.10.2"
github "mapbox/mapbox-speech-swift" "v0.3.0"
github "mapbox/turf-swift" "v0.3.0"
Expand Down
2 changes: 1 addition & 1 deletion MapboxCoreNavigation/EventDetails.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ struct NavigationEventDetails: EventDetails {
coordinate = dataSource.router.rawLocation?.coordinate
startTimestamp = session.departureTimestamp ?? nil
sdkIdentifier = defaultInterface ? "mapbox-navigation-ui-ios" : "mapbox-navigation-ios"
profile = dataSource.routeProgress.route.routeOptions.profileIdentifier.rawValue
profile = dataSource.routeProgress.routeOptions.profileIdentifier.rawValue
simulation = dataSource.locationProvider is SimulatedLocationManager.Type

sessionIdentifier = session.identifier.uuidString
Expand Down
4 changes: 2 additions & 2 deletions MapboxCoreNavigation/LegacyRouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ open class LegacyRouteController: NSObject, Router, InternalRouter, CLLocationMa
return routeProgress.route
}
set {
routeProgress = RouteProgress(route: newValue)
routeProgress = RouteProgress(route: newValue, options: routeProgress.routeOptions)
}
}

Expand All @@ -80,7 +80,7 @@ open class LegacyRouteController: NSObject, Router, InternalRouter, CLLocationMa

required public init(along route: Route, directions: Directions = Directions.shared, dataSource source: RouterDataSource) {
self.directions = directions
self._routeProgress = RouteProgress(route: route)
self._routeProgress = RouteProgress(route: route, options: ) //FIXME: Finish This
JThramer marked this conversation as resolved.
Show resolved Hide resolved
self.dataSource = source
UIDevice.current.isBatteryMonitoringEnabled = true

Expand Down
5 changes: 3 additions & 2 deletions MapboxCoreNavigation/NavigationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ public class MapboxNavigationService: NSObject, NavigationService {
- parameter routerType: An optional router type to use for traversing the route.
*/
required public init(route: Route,
routeOptions: RouteOptions,
directions: Directions? = nil,
locationSource: NavigationLocationManager? = nil,
eventsManagerType: NavigationEventsManager.Type? = nil,
Expand All @@ -240,8 +241,8 @@ public class MapboxNavigationService: NSObject, NavigationService {
router = routerType.init(along: route, directions: self.directions, dataSource: self)

let eventType = eventsManagerType ?? NavigationEventsManager.self
eventsManager = eventType.init(dataSource: self, accessToken: route.accessToken)
locationManager.activityType = route.routeOptions.activityType
eventsManager = eventType.init(dataSource: self, accessToken: directions!.credentials.accessToken)
locationManager.activityType = routeOptions.activityType
bootstrapEvents()

router.delegate = self
Expand Down
26 changes: 16 additions & 10 deletions MapboxCoreNavigation/RouteController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ open class RouteController: NSObject {
return routeProgress.route
}
set {
routeProgress = RouteProgress(route: newValue)
routeProgress = RouteProgress(route: newValue, options: routeProgress.routeOptions)
updateNavigator(with: routeProgress)
}
}
Expand Down Expand Up @@ -137,9 +137,9 @@ open class RouteController: NSObject {
return snappedLocation ?? rawLocation
}

required public init(along route: Route, directions: Directions = Directions.shared, dataSource source: RouterDataSource) {
required public init(along route: Route, options: RouteOptions, directions: Directions = Directions.shared, dataSource source: RouterDataSource) {
self.directions = directions
self._routeProgress = RouteProgress(route: route)
self._routeProgress = RouteProgress(route: route, options: options)
self.dataSource = source
UIDevice.current.isBatteryMonitoringEnabled = true

Expand All @@ -161,7 +161,7 @@ open class RouteController: NSObject {
/// updateNavigator is used to pass the new progress model onto nav-native.
private func updateNavigator(with progress: RouteProgress) {
let encoder = JSONEncoder()
encoder.userInfo[.options] = progress.route.routeOptions
encoder.userInfo[.options] = progress.routeOptions
guard let routeData = try? encoder.encode(progress.route),
let routeJSONString = String(data: routeData, encoding: .utf8) else {
return
Expand Down Expand Up @@ -401,25 +401,31 @@ extension RouteController: Router {
if isRerouting { return }
isRerouting = true

getDirections(from: location, along: progress) { [weak self] (route, error) in
getDirections(from: location, along: progress) { [weak self] (session, result) in
self?.isRerouting = false

guard let strongSelf: RouteController = self else {
return
}

if let error = error {
switch result {
case let .success(response):
guard let route = response.routes?.first else { return }
guard case let .route(routeOptions) = response.options else { return } //TODO: Can a match hit this codepoint?
strongSelf._routeProgress = RouteProgress(route: route, options: routeOptions, legIndex: 0)
strongSelf._routeProgress.currentLegProgress.stepIndex = 0
strongSelf.announce(reroute: route, at: location, proactive: false)

case let .failure(error):
strongSelf.delegate?.router(strongSelf, didFailToRerouteWith: error)
NotificationCenter.default.post(name: .routeControllerDidFailToReroute, object: self, userInfo: [
NotificationUserInfoKey.routingErrorKey: error,
])
return
}


guard let route = route else { return }
strongSelf._routeProgress = RouteProgress(route: route, legIndex: 0)
strongSelf._routeProgress.currentLegProgress.stepIndex = 0
strongSelf.announce(reroute: route, at: location, proactive: false)

}
}
}
Expand Down
9 changes: 6 additions & 3 deletions MapboxCoreNavigation/RouteProgress.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ open class RouteProgress: NSObject {
Returns the current `Route`.
*/
public let route: Route

public let routeOptions: RouteOptions

/**
Index representing current `RouteLeg`.
Expand Down Expand Up @@ -94,7 +96,7 @@ open class RouteProgress: NSObject {
The waypoints remaining on the current route, including any waypoints that do not separate legs.
*/
func remainingWaypointsForCalculatingRoute() -> [Waypoint] {
let (currentLegViaPoints, remainingWaypoints) = route.routeOptions.waypoints(fromLegAt: legIndex)
let (currentLegViaPoints, remainingWaypoints) = routeOptions.waypoints(fromLegAt: legIndex)
let currentLegRemainingViaPoints = currentLegProgress.remainingWaypoints(among: currentLegViaPoints)
return currentLegRemainingViaPoints + remainingWaypoints
}
Expand Down Expand Up @@ -171,8 +173,9 @@ open class RouteProgress: NSObject {
- parameter route: The route to follow.
- parameter legIndex: Zero-based index indicating the current leg the user is on.
*/
public init(route: Route, legIndex: Int = 0, spokenInstructionIndex: Int = 0) {
public init(route: Route, options: RouteOptions, legIndex: Int = 0, spokenInstructionIndex: Int = 0) {
self.route = route
self.routeOptions = options
self.legIndex = legIndex
self.currentLegProgress = RouteLegProgress(leg: route.legs[legIndex], stepIndex: 0, spokenInstructionIndex: spokenInstructionIndex)
super.init()
Expand Down Expand Up @@ -254,7 +257,7 @@ open class RouteProgress: NSObject {
}

func reroutingOptions(with current: CLLocation) -> RouteOptions {
let oldOptions = route.routeOptions
let oldOptions = routeOptions
let user = Waypoint(coordinate: current.coordinate)

if (current.course >= 0) {
Expand Down
30 changes: 21 additions & 9 deletions MapboxCoreNavigation/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,13 @@ extension InternalRouter where Self: Router {
if isRerouting { return }
isRerouting = true

getDirections(from: location, along: routeProgress) { [weak self] (route, error) in
getDirections(from: location, along: routeProgress) { [weak self] (session, result) in
self?.isRerouting = false

guard let route = route else { return }
guard case let .success(response) = result else {
return
}
guard let route = response.routes?.first else { return }

self?.lastProactiveRerouteDate = nil

Expand All @@ -148,19 +151,28 @@ extension InternalRouter where Self: Router {
}
}

func getDirections(from location: CLLocation, along progress: RouteProgress, completion: @escaping (_ route: Route?, _ error: Error?)->Void) {
func getDirections(from location: CLLocation, along progress: RouteProgress, completion: @escaping Directions.RouteCompletionHandler) {
routeTask?.cancel()
let options = progress.reroutingOptions(with: location)

lastRerouteLocation = location

routeTask = directions.calculate(options) {(waypoints, routes, error) in
guard let routes = routes else {
return completion(nil, error)
routeTask = directions.calculate(options) {(session, result) in

guard case let .success(response) = result else {
return completion(session, result)
}


guard let mostSimilar = response.routes?.mostSimilar(to: progress.route) else {
return completion(session, result)
}

var modifiedResponse = response
modifiedResponse.routes?.removeAll { $0 == mostSimilar }
modifiedResponse.routes?.insert(mostSimilar, at: 0)

let mostSimilar = routes.mostSimilar(to: progress.route)
return completion(mostSimilar ?? routes.first, error)
return completion(session, .success(modifiedResponse))
}
}

Expand All @@ -174,7 +186,7 @@ extension InternalRouter where Self: Router {
didFindFasterRoute = false
}

routeProgress = RouteProgress(route: route, legIndex: 0, spokenInstructionIndex: spokenInstructionIndex)
routeProgress = RouteProgress(route: route, options: routeProgress.routeOptions, legIndex: 0, spokenInstructionIndex: spokenInstructionIndex)
}

func announce(reroute newRoute: Route, at location: CLLocation?, proactive: Bool) {
Expand Down
19 changes: 13 additions & 6 deletions MapboxNavigation/NavigationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,22 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
- parameter route: The route to navigate along.
- parameter options: The navigation options to use for the navigation session.
*/
required public init(for route: Route,
required public init(for response: RouteResponse,
options: NavigationOptions? = nil) {
super.init(nibName: nil, bundle: nil)

let route = response.routes!.first! //TODO: Safe-ish, but is there a better way?
JThramer marked this conversation as resolved.
Show resolved Hide resolved

guard case let .route(routeOptions) = response.options else {
preconditionFailure() //FIXME: This is a smell.
}

self.navigationService = options?.navigationService ?? MapboxNavigationService(route: route)
self.navigationService.delegate = self
self.voiceController = options?.voiceController ?? MapboxVoiceController(navigationService: navigationService, speechClient: SpeechSynthesizer(accessToken: navigationService?.directions.accessToken, host: navigationService?.directions.apiEndpoint.host))
let credentials = navigationService.directions.credentials
self.voiceController = options?.voiceController ?? MapboxVoiceController(navigationService: navigationService, speechClient: SpeechSynthesizer(accessToken: credentials.accessToken, host: credentials.host.absoluteString))

NavigationSettings.shared.distanceUnit = route.routeOptions.locale.usesMetric ? .kilometer : .mile
NavigationSettings.shared.distanceUnit = routeOptions.locale.usesMetric ? .kilometer : .mile

styleManager = StyleManager()
styleManager.delegate = self
Expand Down Expand Up @@ -249,7 +256,7 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
mapViewController.view.pinInSuperview()
mapViewController.reportButton.isHidden = !showsReportFeedback

if !(route.routeOptions is NavigationRouteOptions) {
if !(routeOptions is NavigationRouteOptions) {
print("`Route` was created using `RouteOptions` and not `NavigationRouteOptions`. Although not required, this may lead to a suboptimal navigation experience. Without `NavigationRouteOptions`, it is not guaranteed you will get congestion along the route line, better ETAs and ETA label color dependent on congestion.")
}
}
Expand All @@ -260,9 +267,9 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
- parameter route: The route to navigate along.
- parameter navigationService: The navigation service that manages navigation along the route.
*/
convenience init(route: Route, navigationService service: NavigationService) {
convenience init(response: RouteResponse, navigationService service: NavigationService) {
let options = NavigationOptions(navigationService: service)
self.init(for: route, options: options)
self.init(for: response, options: options)
}

deinit {
Expand Down
2 changes: 1 addition & 1 deletion MapboxNavigationTests/RouteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class RouteTests: XCTestCase {
], profileIdentifier: .automobile)
options.shapeFormat = .polyline
let response = Fixture.mapMatchingResponse(from: "route-doubling-back", options: options)
let routes = response.routes
let routes = response.matches
let route = routes!.first!
let leg = route.legs.first!

Expand Down
7 changes: 1 addition & 6 deletions MapboxNavigationTests/StepsViewControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class StepsViewControllerTests: XCTestCase {
let directions = Directions(accessToken: bogusToken)
let dataSource = RouteControllerDataSourceFake()

let routeController = RouteController(along: initialRoute, directions: directions, dataSource: dataSource)
let routeController = RouteController(along: Constants.route, directions: directions, dataSource: dataSource)

let stepsViewController = StepsViewController(routeProgress: routeController.routeProgress)

Expand All @@ -28,11 +28,6 @@ class StepsViewControllerTests: XCTestCase {
return (stepsViewController: stepsViewController, routeController: routeController, firstLocation: firstLocation, lastLocation: lastLocation)
}()

lazy var initialRoute: Route = {
let route = Constants.route
route.accessToken = "nonsense"
return route
}()

func testRebuildStepsInstructionsViewDataSource() {
let stepsViewController = dependencies.stepsViewController
Expand Down