From 4b818e9d81e8076b548a6304c726dc48c6433f7d Mon Sep 17 00:00:00 2001 From: Maxim Makhun Date: Tue, 27 Jul 2021 17:17:16 -0700 Subject: [PATCH 1/5] Make `NavigationService` optional to be able to skip implementation of delegate method on client side as `CarPlayManager` provides default `MapboxNavigationService` implementation anyway. --- Sources/MapboxNavigation/CarPlayManager.swift | 13 +++++++------ .../MapboxNavigation/CarPlayManagerDelegate.swift | 15 +++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Sources/MapboxNavigation/CarPlayManager.swift b/Sources/MapboxNavigation/CarPlayManager.swift index 3da3dfcd890..972d7adc27c 100644 --- a/Sources/MapboxNavigation/CarPlayManager.swift +++ b/Sources/MapboxNavigation/CarPlayManager.swift @@ -286,7 +286,7 @@ extension CarPlayManager: CPApplicationDelegate { interfaceController.delegate = self self.interfaceController = interfaceController - if let shouldDisableIdleTimer = delegate?.carplayManagerShouldDisableIdleTimer(self) { + if let shouldDisableIdleTimer = delegate?.carPlayManagerShouldDisableIdleTimer(self) { UIApplication.shared.isIdleTimerDisabled = shouldDisableIdleTimer } else { UIApplication.shared.isIdleTimerDisabled = true @@ -321,7 +321,7 @@ extension CarPlayManager: CPApplicationDelegate { eventsManager.sendCarPlayDisconnectEvent() - if let shouldDisableIdleTimer = delegate?.carplayManagerShouldDisableIdleTimer(self) { + if let shouldDisableIdleTimer = delegate?.carPlayManagerShouldDisableIdleTimer(self) { UIApplication.shared.isIdleTimerDisabled = !shouldDisableIdleTimer } else { UIApplication.shared.isIdleTimerDisabled = false @@ -564,7 +564,8 @@ extension CarPlayManager: CPMapTemplateDelegate { let desiredSimulationMode: SimulationMode = simulatesLocations ? .always : .onPoorGPS let navigationService = self.navigationService ?? - delegate?.carPlayManager(self, navigationServiceAlong: route, + delegate?.carPlayManager(self, + navigationServiceAlong: route, routeIndex: routeIndex, routeOptions: options, desiredSimulationMode: desiredSimulationMode) ?? @@ -576,7 +577,7 @@ extension CarPlayManager: CPMapTemplateDelegate { // Store newly created `MapboxNavigationService`. self.navigationService = navigationService - if simulatesLocations == true { + if simulatesLocations { navigationService.simulationSpeedMultiplier = simulatedSpeedMultiplier } popToRootTemplate(interfaceController: interfaceController, animated: false) @@ -867,7 +868,7 @@ extension CarPlayManager { interfaceController.delegate = self self.interfaceController = interfaceController - if let shouldDisableIdleTimer = delegate?.carplayManagerShouldDisableIdleTimer(self) { + if let shouldDisableIdleTimer = delegate?.carPlayManagerShouldDisableIdleTimer(self) { UIApplication.shared.isIdleTimerDisabled = shouldDisableIdleTimer } else { UIApplication.shared.isIdleTimerDisabled = true @@ -900,7 +901,7 @@ extension CarPlayManager { eventsManager.sendCarPlayDisconnectEvent() - if let shouldDisableIdleTimer = delegate?.carplayManagerShouldDisableIdleTimer(self) { + if let shouldDisableIdleTimer = delegate?.carPlayManagerShouldDisableIdleTimer(self) { UIApplication.shared.isIdleTimerDisabled = !shouldDisableIdleTimer } else { UIApplication.shared.isIdleTimerDisabled = false diff --git a/Sources/MapboxNavigation/CarPlayManagerDelegate.swift b/Sources/MapboxNavigation/CarPlayManagerDelegate.swift index 43e9ebb5412..d9bac15bf48 100644 --- a/Sources/MapboxNavigation/CarPlayManagerDelegate.swift +++ b/Sources/MapboxNavigation/CarPlayManagerDelegate.swift @@ -9,7 +9,7 @@ import MapboxMaps Implement this protocol and assign an instance to the `delegate` property of the shared instance of `CarPlayManager`. - If no delegate is set, a default built-in MapboxNavigationService will be created and used when a trip begins. + If no delegate is set, a default built-in `MapboxNavigationService` will be created and used when a trip begins. */ @available(iOS 12.0, *) public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { @@ -63,7 +63,7 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter desiredSimulationMode: The desired simulation mode to use. - returns: A navigation service that manages location updates along `route`. */ - func carPlayManager(_ carPlayManager: CarPlayManager, navigationServiceAlong route: Route, routeIndex: Int, routeOptions: RouteOptions, desiredSimulationMode: SimulationMode) -> NavigationService + func carPlayManager(_ carPlayManager: CarPlayManager, navigationServiceAlong route: Route, routeIndex: Int, routeOptions: RouteOptions, desiredSimulationMode: SimulationMode) -> NavigationService? /** Called when the CarPlay manager fails to fetch a route. @@ -137,7 +137,7 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter carPlayManager: The CarPlay manager instance. - returns: A Boolean value indicating whether to disable idle timer when carplay is connected and enable when disconnected. */ - func carplayManagerShouldDisableIdleTimer(_ carPlayManager: CarPlayManager) -> Bool + func carPlayManagerShouldDisableIdleTimer(_ carPlayManager: CarPlayManager) -> Bool /** Called when the CarPlayManager presents a new CarPlayNavigationViewController upon start of a navigation session. @@ -189,6 +189,13 @@ public extension CarPlayManagerDelegate { return nil } + /** + `UnimplementedLogging` prints a warning to standard output the first time this method is called. + */ + func carPlayManager(_ carPlayManager: CarPlayManager, navigationServiceAlong route: Route, routeIndex: Int, routeOptions: RouteOptions, desiredSimulationMode: SimulationMode) -> NavigationService? { + return nil + } + /** `UnimplementedLogging` prints a warning to standard output the first time this method is called. */ @@ -245,7 +252,7 @@ public extension CarPlayManagerDelegate { /** `UnimplementedLogging` prints a warning to standard output the first time this method is called. */ - func carplayManagerShouldDisableIdleTimer(_ carPlayManager: CarPlayManager) -> Bool { + func carPlayManagerShouldDisableIdleTimer(_ carPlayManager: CarPlayManager) -> Bool { logUnimplemented(protocolType: CarPlayManagerDelegate.self, level: .debug) return false } From ca0bdae6c372761b7ffb07ee26f71fb9dcc4213d Mon Sep 17 00:00:00 2001 From: Maxim Makhun Date: Tue, 27 Jul 2021 17:23:20 -0700 Subject: [PATCH 2/5] Fix compilation warning. --- Example/AppDelegate+CarPlay.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/AppDelegate+CarPlay.swift b/Example/AppDelegate+CarPlay.swift index 724fa4f7a3f..f4c564aae70 100644 --- a/Example/AppDelegate+CarPlay.swift +++ b/Example/AppDelegate+CarPlay.swift @@ -73,7 +73,7 @@ extension AppDelegate: CarPlayManagerDelegate { navigationServiceAlong route: Route, routeIndex: Int, routeOptions: RouteOptions, - desiredSimulationMode: SimulationMode) -> NavigationService { + desiredSimulationMode: SimulationMode) -> NavigationService? { if let navigationViewController = self.window?.rootViewController?.presentedViewController as? NavigationViewController, let navigationService = navigationViewController.navigationService { // Do not set simulation mode if we already have an active navigation session. From 01523815abf4a8f1f81cb99eab78c72774f367de Mon Sep 17 00:00:00 2001 From: Maxim Makhun Date: Tue, 27 Jul 2021 18:33:49 -0700 Subject: [PATCH 3/5] Remove boilerplate code from `CarPlayManagerDelegate`. --- .../CarPlayManagerDelegate.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/MapboxNavigation/CarPlayManagerDelegate.swift b/Sources/MapboxNavigation/CarPlayManagerDelegate.swift index d9bac15bf48..4e2527a9384 100644 --- a/Sources/MapboxNavigation/CarPlayManagerDelegate.swift +++ b/Sources/MapboxNavigation/CarPlayManagerDelegate.swift @@ -84,7 +84,7 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter trip: The trip that will be previewed. - returns: The actual trip to be previewed. This can be the same trip or a new/alternate trip if desired. */ - func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip) -> (CPTrip) + func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip) -> CPTrip /** Offers the delegate the opportunity to customize a trip preview text configuration for a given trip. @@ -94,7 +94,7 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter previewTextConfiguration: The trip preview text configuration that will be presented alongside the trip. - returns: The actual preview text configuration to be presented alongside the trip. */ - func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip, with previewTextConfiguration: CPTripPreviewTextConfiguration) -> (CPTripPreviewTextConfiguration) + func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip, with previewTextConfiguration: CPTripPreviewTextConfiguration) -> CPTripPreviewTextConfiguration /** Offers the delegate the opportunity to react to selection of a trip. Certain trips may have alternate route(s). @@ -103,7 +103,7 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter trip: The trip to begin navigating along. - parameter routeChoice: The possible route for the chosen trip. */ - func carPlayManager(_ carPlayManager: CarPlayManager, selectedPreviewFor trip: CPTrip, using routeChoice: CPRouteChoice) -> () + func carPlayManager(_ carPlayManager: CarPlayManager, selectedPreviewFor trip: CPTrip, using routeChoice: CPRouteChoice) /** Called when navigation begins so that the containing app can update accordingly. @@ -111,14 +111,14 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter carPlayManager: The CarPlay manager instance. - parameter service: The navigation service that has begun managing location updates for a navigation session. */ - func carPlayManager(_ carPlayManager: CarPlayManager, didBeginNavigationWith service: NavigationService) -> () + func carPlayManager(_ carPlayManager: CarPlayManager, didBeginNavigationWith service: NavigationService) /** Called when navigation ends so that the containing app can update accordingly. - parameter carPlayManager: The CarPlay manager instance. */ - func carPlayManagerDidEndNavigation(_ carPlayManager: CarPlayManager) -> () + func carPlayManagerDidEndNavigation(_ carPlayManager: CarPlayManager) /** Called when the CarPlayManager detects the user arrives at the destination waypoint for a route leg. @@ -147,7 +147,7 @@ public protocol CarPlayManagerDelegate: AnyObject, UnimplementedLogging { - parameter carPlayManager: The CarPlay manager instance. - parameter navigationViewController: The CarPlayNavigationViewController that was presented on the CarPlay display. */ - func carPlayManager(_ carPlayManager: CarPlayManager, didPresent navigationViewController: CarPlayNavigationViewController) -> () + func carPlayManager(_ carPlayManager: CarPlayManager, didPresent navigationViewController: CarPlayNavigationViewController) /** Tells the receiver that the `PointAnnotation` representing the final destination was added to either `CarPlayMapViewController` or `CarPlayNavigationViewController`. @@ -207,7 +207,7 @@ public extension CarPlayManagerDelegate { /** `UnimplementedLogging` prints a warning to standard output the first time this method is called. */ - func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip) -> (CPTrip) { + func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip) -> CPTrip { logUnimplemented(protocolType: CarPlayManagerDelegate.self, level: .debug) return trip } @@ -215,7 +215,7 @@ public extension CarPlayManagerDelegate { /** `UnimplementedLogging` prints a warning to standard output the first time this method is called. */ - func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip, with previewTextConfiguration: CPTripPreviewTextConfiguration) -> (CPTripPreviewTextConfiguration) { + func carPlayManager(_ carPlayManager: CarPlayManager, willPreview trip: CPTrip, with previewTextConfiguration: CPTripPreviewTextConfiguration) -> CPTripPreviewTextConfiguration { logUnimplemented(protocolType: CarPlayManagerDelegate.self, level: .debug) return previewTextConfiguration } From 0f34e3149582143a8fc0e93d312c5cffa250c261 Mon Sep 17 00:00:00 2001 From: Maxim Makhun Date: Wed, 28 Jul 2021 14:11:39 -0700 Subject: [PATCH 4/5] Fix failing `testMapViewShowsTrafficAndIncidents` by increasing timeout. --- Tests/MapboxNavigationTests/MapViewTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/MapboxNavigationTests/MapViewTests.swift b/Tests/MapboxNavigationTests/MapViewTests.swift index c8d0273eb27..101ef36d44b 100644 --- a/Tests/MapboxNavigationTests/MapViewTests.swift +++ b/Tests/MapboxNavigationTests/MapViewTests.swift @@ -39,7 +39,7 @@ class MapViewTests: XCTestCase { let styleJSON: String = ValueConverter.toJson(forValue: styleJSONObject) XCTAssertFalse(styleJSON.isEmpty, "ValueConverter should create valid JSON string.") - let mapLoadingErrorExpectation = expectation(description: "Style loaded expectation") + let mapLoadingErrorExpectation = expectation(description: "Map loading error expectation") mapView.mapboxMap.onNext(.mapLoadingError, handler: { event in mapLoadingErrorExpectation.fulfill() @@ -109,7 +109,7 @@ class MapViewTests: XCTestCase { let styleJSON: String = ValueConverter.toJson(forValue: styleJSONObject) XCTAssertFalse(styleJSON.isEmpty, "ValueConverter should create valid JSON string.") - let mapLoadingErrorExpectation = expectation(description: "Style loaded expectation") + let mapLoadingErrorExpectation = expectation(description: "Map loading error expectation") mapView.mapboxMap.onNext(.mapLoadingError, handler: { event in mapLoadingErrorExpectation.fulfill() @@ -117,7 +117,7 @@ class MapViewTests: XCTestCase { mapView.mapboxMap.loadStyleJSON(styleJSON) - wait(for: [mapLoadingErrorExpectation], timeout: 1.0) + wait(for: [mapLoadingErrorExpectation], timeout: 10.0) XCTAssertEqual(mapView.mapboxMap.style.allSourceIdentifiers.count, 1, From 7fb421622ff732a9f3eccb87cd220d23cabd46b4 Mon Sep 17 00:00:00 2001 From: Maxim Makhun Date: Wed, 28 Jul 2021 14:41:25 -0700 Subject: [PATCH 5/5] Update changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76e9338119f..c157db9fb36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,8 @@ * Added the `CarPlayMapViewControllerDelegate` public protocol, which provides methods for reacting to events during free-drive navigation or route previewing. ([#3190](https://github.com/mapbox/mapbox-navigation-ios/pull/3190)) * Added the `CarPlayMapViewControllerDelegate.carPlayMapViewController(_:didAdd:pointAnnotationManager:)`, `CarPlayNavigationViewControllerDelegate.carPlayNavigationViewController(_:didAdd:pointAnnotationManager:)` and `CarPlayManager.carPlayManager(_:didAdd:to:pointAnnotationManager:)` delegate methods, which will be called whenever the `PointAnnotation` representing the final destination is added to `CarPlayMapViewController`, `CarPlayNavigationViewController` and `CarPlayManager`, respectively. ([#3190](https://github.com/mapbox/mapbox-navigation-ios/pull/3190)) * Added the ability to show speed limit indicator on CarPlay during free-drive. ([#3197](https://github.com/mapbox/mapbox-navigation-ios/pull/3197)) +* `CarPlayManagerDelegate.carPlayManager(_:navigationServiceAlong:routeIndex:routeOptions:desiredSimulationMode:)` now requires optional `NavigationService`. In case if `NavigationService` was not provided `MapboxNavigationService` will be used by default. ([#3208](https://github.com/mapbox/mapbox-navigation-ios/pull/3208)) +* `CarPlayManagerDelegate.carplayManagerShouldDisableIdleTimer(_:)` was renamed to `CarPlayManagerDelegate.carPlayManagerShouldDisableIdleTimer(_:)`. ([#3208](https://github.com/mapbox/mapbox-navigation-ios/pull/3208)) ### Other changes