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 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
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" "c91d3ba051fa67759b905299dad85a163697efcf"
github "mapbox/turf-swift" ~> 0.3
github "mapbox/mapbox-events-ios" ~> 0.10
github "ceeK/Solar" ~> 2.1.0
Expand Down
6 changes: 3 additions & 3 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" "5.7.0"
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" "5.8.0"
binary "https://www.mapbox.com/ios-sdk/MapboxNavigationNative.json" "6.2.1"
github "AndriiDoroshko/SnappyShrimp" "1.6.4"
github "CedarBDD/Cedar" "v1.0"
github "Quick/Nimble" "v8.0.5"
github "Quick/Nimble" "v8.0.7"
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" "c91d3ba051fa67759b905299dad85a163697efcf"
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
5 changes: 3 additions & 2 deletions Example/AppDelegate+CarPlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ extension AppDelegate: CPApplicationDelegate {

@available(iOS 12.0, *)
extension AppDelegate: CarPlayManagerDelegate {
func carPlayManager(_ carPlayManager: CarPlayManager, navigationServiceAlong route: Route, desiredSimulationMode: SimulationMode) -> NavigationService {
func carPlayManager(_ carPlayManager: CarPlayManager, navigationServiceAlong route: Route, routeOptions: RouteOptions, desiredSimulationMode: SimulationMode) -> NavigationService {

if let nvc = self.window?.rootViewController?.presentedViewController as? NavigationViewController, let service = nvc.navigationService {
//Do not set simulation mode if we already have an active navigation session.
return service
}
return MapboxNavigationService(route: route, simulating: desiredSimulationMode)
return MapboxNavigationService(route: route, routeOptions: routeOptions, simulating: desiredSimulationMode)
}

// MARK: CarPlayManagerDelegate
Expand Down
4 changes: 3 additions & 1 deletion Example/CustomViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class CustomViewController: UIViewController, MGLMapViewDelegate {
var simulateLocation = false

var userRoute: Route?

var userRouteOptions: RouteOptions?

// Start voice instructions
var voiceController: MapboxVoiceController!
Expand All @@ -38,7 +40,7 @@ class CustomViewController: UIViewController, MGLMapViewDelegate {
super.viewDidLoad()

let locationManager = simulateLocation ? SimulatedLocationManager(route: userRoute!) : NavigationLocationManager()
navigationService = MapboxNavigationService(route: userRoute!, locationSource: locationManager, simulating: simulateLocation ? .always : .onPoorGPS)
navigationService = MapboxNavigationService(route: userRoute!, routeOptions: userRouteOptions!, locationSource: locationManager, simulating: simulateLocation ? .always : .onPoorGPS)
voiceController = MapboxVoiceController(navigationService: navigationService)

mapView.delegate = self
Expand Down
2 changes: 1 addition & 1 deletion Example/ViewController+GuidanceCards.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MapboxDirections
/// :nodoc:
extension ViewController: InstructionsCardCollectionDelegate {
public func instructionsCardCollection(_ instructionsCardCollection: InstructionsCardViewController, didPreview step: RouteStep) {
guard let route = routes?.first else { return }
guard let route = response?.routes?.first else { return }

// find the leg that contains the step, legIndex, and stepIndex
guard let leg = route.legs.first(where: { $0.steps.contains(step) }),
Expand Down
94 changes: 48 additions & 46 deletions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MapboxDirections
import UserNotifications
import AVKit

private typealias RouteRequestSuccess = (([Route]) -> Void)
private typealias RouteRequestSuccess = ((RouteResponse) -> Void)
private typealias RouteRequestFailure = ((Error) -> Void)

class ViewController: UIViewController {
Expand Down Expand Up @@ -35,14 +35,15 @@ class ViewController: UIViewController {
}
}

var routes: [Route]? {
var response: RouteResponse? {
didSet {
startButton.isEnabled = (routes?.count ?? 0 > 0)
guard let routes = routes, let current = routes.first else {
guard let routes = response?.routes, let current = routes.first else {
startButton.isEnabled = false
mapView?.removeRoutes()
return

}

startButton.isEnabled = true
mapView?.show(routes)
mapView?.showWaypoints(on: current)
}
Expand All @@ -52,17 +53,17 @@ class ViewController: UIViewController {

// MARK: Directions Request Handlers

fileprivate lazy var defaultSuccess: RouteRequestSuccess = { [weak self] (routes) in
guard let current = routes.first else { return }
fileprivate lazy var defaultSuccess: RouteRequestSuccess = { [weak self] (response) in
guard let routes = response.routes, !routes.isEmpty, case let .route(options) = response.options else { return }
self?.mapView?.removeWaypoints()
self?.routes = routes
self?.waypoints = current.routeOptions.waypoints
self?.response = response
self?.waypoints = options.waypoints
self?.clearMap.isHidden = false
self?.longPressHintView.isHidden = true
}

fileprivate lazy var defaultFailure: RouteRequestFailure = { [weak self] (error) in
self?.routes = nil //clear routes from the map
self?.response = nil //clear routes from the map
print(error.localizedDescription)
self?.presentAlert(message: error.localizedDescription)
}
Expand Down Expand Up @@ -207,62 +208,63 @@ class ViewController: UIViewController {
fileprivate func requestRoute(with options: RouteOptions, success: @escaping RouteRequestSuccess, failure: RouteRequestFailure?) {
// Calculate route offline if an offline version is selected
let shouldUseOfflineRouting = Settings.selectedOfflineVersion != nil
Settings.directions.calculate(options, offline: shouldUseOfflineRouting) { (waypoints, routes, error) in
if let error = error { failure?(error) }
guard let routes = routes else { return }
return success(routes)
Settings.directions.calculate(options, offline: shouldUseOfflineRouting) { (session, result) in
switch result {
case let .success(response):
success(response)
case let .failure(error):
failure?(error)
}
}
}

// MARK: Basic Navigation

func startBasicNavigation() {
guard let route = routes?.first else { return }
guard let response = response, let route = response.routes?.first, case let .route(routeOptions) = response.options else { return }

let service = navigationService(route: route)
let service = navigationService(route: route, options: routeOptions)
let navigationViewController = self.navigationViewController(navigationService: service)

presentAndRemoveMapview(navigationViewController, completion: beginCarPlayNavigation)
}

func startNavigation(styles: [Style]) {
guard let route = routes?.first else { return }
guard let response = response, let route = response.routes?.first, case let .route(routeOptions) = response.options else { return }

let options = NavigationOptions(styles: styles, navigationService: navigationService(route: route))
let navigationViewController = NavigationViewController(for: route, options: options)
let options = NavigationOptions(styles: styles, navigationService: navigationService(route: route, options: routeOptions))
let navigationViewController = NavigationViewController(for: route, routeOptions: routeOptions, navigationOptions: options)
navigationViewController.delegate = self

presentAndRemoveMapview(navigationViewController, completion: beginCarPlayNavigation)
}

func navigationViewController(navigationService: NavigationService) -> NavigationViewController {
let route = navigationService.route
let options = NavigationOptions( navigationService: navigationService)
let options = NavigationOptions(navigationService: navigationService)

let navigationViewController = NavigationViewController(for: route, options: options)
let navigationViewController = NavigationViewController(for: navigationService.route, routeOptions: navigationService.routeProgress.routeOptions, navigationOptions: options)
navigationViewController.delegate = self
navigationViewController.mapView?.delegate = self
return navigationViewController
}

public func beginNavigationWithCarplay(navigationService: NavigationService) {
self.routes = [navigationService.route]

let navigationViewController = activeNavigationViewController ?? self.navigationViewController(navigationService: navigationService)
navigationViewController.didConnectToCarPlay()

guard activeNavigationViewController == nil else { return }

presentAndRemoveMapview(navigationViewController, completion: nil)
}

// MARK: Custom Navigation UI
func startCustomNavigation() {
guard let route = routes?.first else { return }
guard let route = response?.routes?.first, let responseOptions = response?.options, case let .route(routeOptions) = responseOptions else { return }

guard let customViewController = storyboard?.instantiateViewController(withIdentifier: "custom") as? CustomViewController else { return }

customViewController.userRoute = route
customViewController.userRouteOptions = routeOptions

let destination = MGLPointAnnotation()
destination.coordinate = route.shape!.coordinates.last!
Expand All @@ -275,34 +277,34 @@ class ViewController: UIViewController {
// MARK: Styling the default UI

func startStyledNavigation() {
guard let route = routes?.first else { return }
guard let response = response, let route = response.routes?.first, case let .route(routeOptions) = response.options else { return }

let styles = [CustomDayStyle(), CustomNightStyle()]
let options = NavigationOptions(styles:styles, navigationService: navigationService(route: route))
let navigationViewController = NavigationViewController(for: route, options: options)
let options = NavigationOptions(styles:styles, navigationService: navigationService(route: route, options: routeOptions))
let navigationViewController = NavigationViewController(for: route, routeOptions: routeOptions, navigationOptions: options)
navigationViewController.delegate = self

presentAndRemoveMapview(navigationViewController, completion: beginCarPlayNavigation)
}

// MARK: Guidance Cards
func startGuidanceCardsNavigation() {
guard let route = routes?.first else { return }
guard let response = response, let route = response.routes?.first, case let .route(routeOptions) = response.options else { return }

let instructionsCardCollection = InstructionsCardViewController()
instructionsCardCollection.cardCollectionDelegate = self

let options = NavigationOptions(navigationService: navigationService(route: route), topBanner: instructionsCardCollection)
let navigationViewController = NavigationViewController(for: route, options: options)
let options = NavigationOptions(navigationService: navigationService(route: route, options: routeOptions), topBanner: instructionsCardCollection)
let navigationViewController = NavigationViewController(for: route, routeOptions: routeOptions, navigationOptions: options)
navigationViewController.delegate = self

presentAndRemoveMapview(navigationViewController, completion: beginCarPlayNavigation)
}

func navigationService(route: Route) -> NavigationService {
func navigationService(route: Route, options: RouteOptions) -> NavigationService {
let simulate = simulationButton.isSelected
let mode: SimulationMode = simulate ? .always : .onPoorGPS
return MapboxNavigationService(route: route, directions: Settings.directions, simulating: mode)
return MapboxNavigationService(route: route, routeOptions: options, directions: Settings.directions, simulating: mode)
}

func presentAndRemoveMapview(_ navigationViewController: NavigationViewController, completion: CompletionHandler?) {
Expand Down Expand Up @@ -361,7 +363,7 @@ extension ViewController: MGLMapViewDelegate {

self.mapView?.localizeLabels()

if let routes = routes, let currentRoute = routes.first, let coords = currentRoute.shape?.coordinates {
if let routes = response?.routes, let currentRoute = routes.first, let coords = currentRoute.shape?.coordinates {
mapView.setVisibleCoordinateBounds(MGLPolygon(coordinates: coords, count: UInt(coords.count)).overlayBounds, animated: false)
self.mapView?.show(routes)
self.mapView?.showWaypoints(on: currentRoute)
Expand All @@ -372,7 +374,7 @@ extension ViewController: MGLMapViewDelegate {
// MARK: - NavigationMapViewDelegate
extension ViewController: NavigationMapViewDelegate {
func navigationMapView(_ mapView: NavigationMapView, didSelect waypoint: Waypoint) {
guard let routeOptions = routes?.first?.routeOptions else { return }
guard let responseOptions = response?.options, case let .route(routeOptions) = responseOptions else { return }
let modifiedOptions = routeOptions.without(waypoint: waypoint)

presentWaypointRemovalActionSheet { _ in
Expand All @@ -381,10 +383,10 @@ extension ViewController: NavigationMapViewDelegate {
}

func navigationMapView(_ mapView: NavigationMapView, didSelect route: Route) {
guard let routes = routes else { return }
guard let routes = response?.routes else { return }
guard let index = routes.firstIndex(where: { $0 === route }) else { return }
self.routes!.remove(at: index)
self.routes!.insert(route, at: 0)
self.response!.routes!.remove(at: index)
self.response!.routes!.insert(route, at: 0)
}

private func presentWaypointRemovalActionSheet(completionHandler approve: @escaping ((UIAlertAction) -> Void)) {
Expand Down Expand Up @@ -435,22 +437,22 @@ extension ViewController: VoiceControllerDelegate {
func navigationViewController(_ navigationViewController: NavigationViewController, shouldRerouteFrom location: CLLocation) -> Bool {
let shouldUseOfflineRouting = Settings.selectedOfflineVersion != nil

guard shouldUseOfflineRouting == true else {
guard shouldUseOfflineRouting == true, let responseOptions = response?.options, case let .route(routeOptions) = responseOptions else {
return true
}

let currentRoute = navigationViewController.route
let profileIdentifier = currentRoute.routeOptions.profileIdentifier
let profileIdentifier = routeOptions.profileIdentifier

var waypoints: [Waypoint] = [Waypoint(location: location)]
var remainingWaypoints = currentRoute.routeOptions.waypoints
var remainingWaypoints = navigationViewController.navigationService.routeProgress.remainingWaypoints
remainingWaypoints.removeFirst()
waypoints.append(contentsOf: remainingWaypoints)

let options = NavigationRouteOptions(waypoints: waypoints, profileIdentifier: profileIdentifier)

Settings.directions.calculate(options, offline: true) { (waypoints, routes, error) in
guard let route = routes?.first else { return }
Settings.directions.calculate(options, offline: true) { (session, result) in
guard case let .success(response) = result, let routes = response.routes, let route = routes.first else { return }

navigationViewController.navigationService.route = route
}

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
Loading