diff --git a/Sources/MapboxNavigation/CarPlayManager.swift b/Sources/MapboxNavigation/CarPlayManager.swift index 22e5cc8ba0b..befec6b805c 100644 --- a/Sources/MapboxNavigation/CarPlayManager.swift +++ b/Sources/MapboxNavigation/CarPlayManager.swift @@ -2,6 +2,7 @@ import CarPlay import MapboxCoreNavigation import MapboxDirections import MapboxMaps +import os.log /** `CarPlayManager` is the main object responsible for orchestrating interactions with a Mapbox map on CarPlay. @@ -77,6 +78,7 @@ public class CarPlayManager: NSObject { private weak var navigationService: NavigationService? private var idleTimerCancellable: IdleTimerManager.Cancellable? + private let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "CarPlayManager") /** Programatically begins a CarPlay turn-by-turn navigation session. @@ -93,6 +95,7 @@ public class CarPlayManager: NSObject { locationProvider.stopUpdatingHeading() if let passiveLocationProvider = locationProvider as? PassiveLocationProvider { passiveLocationProvider.locationManager.pauseTripSession() + os_log("Trip session paused", log: logger, type: .debug) } } @@ -143,6 +146,7 @@ public class CarPlayManager: NSObject { routingProvider: RoutingProvider, eventsManager: NavigationEventsManager? = nil, carPlayNavigationViewControllerClass: CarPlayNavigationViewController.Type? = nil) { + self.styles = styles ?? [DayStyle(), NightStyle()] self.routingProvider = routingProvider self.eventsManager = eventsManager ?? .init(activeNavigationDataSource: nil, @@ -160,22 +164,39 @@ public class CarPlayManager: NSObject { selector: #selector(navigationCameraStateDidChange(_:)), name: .navigationCameraStateDidChange, object: carPlayMapViewController?.navigationMapView.navigationCamera) + os_log("CarPlayManager subscribed for notifications.", log: logger, type: .info) } func unsubscribeFromNotifications() { NotificationCenter.default.removeObserver(self, name: .navigationCameraStateDidChange, object: carPlayMapViewController?.navigationMapView.navigationCamera) + os_log("CarPlayManager suspended notifications.", log: logger, type: .info) + } + + @available(iOS 15.0, *) + func getLogEntries() throws -> [OSLogEntryLog] { + let logStore = try OSLogStore(scope: .currentProcessIdentifier) + let oneHourAgo = logStore.position(date: Date().addingTimeInterval(-3600)) + let allEntries = try logStore.getEntries(at: oneHourAgo) + + return allEntries + .compactMap { $0 as? OSLogEntryLog } + .filter { $0.category == "CarPlay" } } + @objc func navigationCameraStateDidChange(_ notification: Notification) { guard let state = notification.userInfo?[NavigationCamera.NotificationUserInfoKey.state] as? NavigationCameraState else { return } switch state { case .idle: + os_log("Camera state: idle", log: logger, type: .info) carPlayMapViewController?.recenterButton.isHidden = false case .transitionToFollowing, .following: + os_log("Camera state: following", log: logger, type: .info) carPlayMapViewController?.recenterButton.isHidden = true case .transitionToOverview, .overview: + os_log("Camera state: overview", log: logger, type: .info) break } } @@ -333,6 +354,7 @@ extension CarPlayManager: CPApplicationDelegate { interfaceController.setRootTemplate(mapTemplate, animated: false) eventsManager.sendCarPlayConnectEvent() + os_log("CarInterfaceController did connect to window.", log: logger, type: .info) subscribeForNotifications() } @@ -351,6 +373,7 @@ extension CarPlayManager: CPApplicationDelegate { carWindow = nil eventsManager.sendCarPlayDisconnectEvent() + os_log("CarInterfaceController did disconnect from window.", log: logger, type: .info) idleTimerCancellable = nil @@ -362,6 +385,7 @@ extension CarPlayManager: CPApplicationDelegate { mapTemplate.mapDelegate = self let currentActivity: CarPlayActivity = .browsing + os_log("CarPlayActivity changed to browsing", log: logger, type: .debug) mapTemplate.userInfo = [ CarPlayManager.currentActivityKey: currentActivity ] @@ -392,7 +416,6 @@ extension CarPlayManager: CPApplicationDelegate { } else if let mapButtons = browsingMapButtons(for: mapTemplate) { mapTemplate.mapButtons = mapButtons } - return mapTemplate } @@ -407,7 +430,6 @@ extension CarPlayManager: CPApplicationDelegate { } else if let mapButtons = browsingMapButtons(for: mapTemplate) { mapTemplate.mapButtons = mapButtons } - mapTemplate.dismissPanningInterface(animated: false) } } @@ -447,9 +469,12 @@ extension CarPlayManager: CPInterfaceControllerDelegate { if let userInfo = template.userInfo as? Dictionary, let currentActivity = userInfo[CarPlayManager.currentActivityKey] as? CarPlayActivity { self.currentActivity = currentActivity + os_log("CarPlayActivity changed", log: logger, type: .debug) } else { self.currentActivity = nil + os_log("CarPlayActivity is nil", log: logger, type: .debug) } + os_log("CarPlayManagerDelegate: template will appear", log: logger, type: .debug) } public func templateDidAppear(_ template: CPTemplate, animated: Bool) { @@ -462,6 +487,7 @@ extension CarPlayManager: CPInterfaceControllerDelegate { let navigationMapView = carPlayMapViewController.navigationMapView navigationMapView.removeRoutes() navigationMapView.removeWaypoints() + os_log("CarPlayManagerDelegate: template did disappear", log: logger, type: .debug) } public func templateWillDisappear(_ template: CPTemplate, animated: Bool) { @@ -473,10 +499,12 @@ extension CarPlayManager: CPInterfaceControllerDelegate { interfaceController.templates.count == 1 else { return } navigationMapView?.navigationCamera.follow() + os_log("CarPlayManagerDelegate: template will disappear", log: logger, type: .debug) } public func templateDidDisappear(_ template: CPTemplate, animated: Bool) { delegate?.carPlayManager(self, templateDidDisappear: template, animated: animated) + os_log("CarPlayManagerDelegate: template did disappear", log: logger, type: .debug) } } @@ -561,6 +589,7 @@ extension CarPlayManager { switch result { case let .failure(error): + os_log("Failed to calculate routes.", log: logger, type: .error) guard let delegate = delegate, let alert = delegate.carPlayManager(self, didFailToFetchRouteBetween: routeOptions.waypoints, @@ -681,6 +710,7 @@ extension CarPlayManager: CPMapTemplateDelegate { mapTemplate.mapDelegate = self let currentActivity: CarPlayActivity = .navigating + os_log("CarPlayActivity changed to navigating", log: logger, type: .debug) mapTemplate.userInfo = [ CarPlayManager.currentActivityKey: currentActivity ] @@ -749,6 +779,7 @@ extension CarPlayManager: CPMapTemplateDelegate { navigationMapView.removeWaypoints() if let passiveLocationProvider = navigationMapView.mapView.location.locationProvider as? PassiveLocationProvider { passiveLocationProvider.locationManager.resumeTripSession() + os_log("PassiveLocationProvider trip session resumed.", log: logger, type: .info) } delegate?.carPlayManagerDidEndNavigation(self) } @@ -775,9 +806,11 @@ extension CarPlayManager: CPMapTemplateDelegate { if let carPlayNavigationViewController = carPlayNavigationViewController { currentActivity = .panningInNavigationMode traitCollection = carPlayNavigationViewController.traitCollection + os_log("CarPlayActivity changed to panning in navigation mode", log: logger, type: .debug) } else if let carPlayMapViewController = self.carPlayMapViewController { currentActivity = .panningInBrowsingMode traitCollection = carPlayMapViewController.traitCollection + os_log("CarPlayActivity changed to panning in browsing mode", log: logger, type: .debug) } else { assertionFailure("Panning interface is only supported for free-drive or active-guidance navigation.") return @@ -909,6 +942,7 @@ extension CarPlayManager: CarPlayNavigationViewControllerDelegate { interfaceController.dismissTemplate(animated: true) // Unset existing main map template (fixes an issue with the buttons) mainMapTemplate = nil + os_log("CarPlayManager did dismiss arrival UI.", log: logger, type: .info) // Then (re-)create and assign new map template let mapTemplate = previewMapTemplate() @@ -919,6 +953,7 @@ extension CarPlayManager: CarPlayNavigationViewControllerDelegate { if let passiveLocationProvider = navigationMapView?.mapView.location.locationProvider as? PassiveLocationProvider { passiveLocationProvider.locationManager.resumeTripSession() + os_log("PassiveLocationProvider trip session resumed.", log: logger, type: .info) } self.carPlayNavigationViewController = nil @@ -1003,6 +1038,7 @@ extension CarPlayManager { interfaceController.setRootTemplate(mapTemplate, animated: false) eventsManager.sendCarPlayConnectEvent() + os_log("CarPlayManager did connect InterfaceController.", log: logger, type: .info) subscribeForNotifications() } @@ -1023,6 +1059,7 @@ extension CarPlayManager { eventsManager.sendCarPlayDisconnectEvent() idleTimerCancellable = nil + os_log("CarPlayManager did disconnect InterfaceController.", log: logger, type: .info) unsubscribeFromNotifications() } diff --git a/Sources/MapboxNavigation/CarPlayMapViewController.swift b/Sources/MapboxNavigation/CarPlayMapViewController.swift index 9e19ff7c34b..a06db7d52fd 100644 --- a/Sources/MapboxNavigation/CarPlayMapViewController.swift +++ b/Sources/MapboxNavigation/CarPlayMapViewController.swift @@ -2,6 +2,7 @@ import Foundation @_spi(Restricted) import MapboxMaps import MapboxCoreNavigation import MapboxDirections +import os.log #if canImport(CarPlay) import CarPlay @@ -172,6 +173,7 @@ open class CarPlayMapViewController: UIViewController { private var safeTrailingSpeedLimitViewConstraint: NSLayoutConstraint! private var trailingSpeedLimitViewConstraint: NSLayoutConstraint! + private let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "CarPlayMapViewController") // MARK: Initialization Methods @@ -278,12 +280,14 @@ open class CarPlayMapViewController: UIViewController { selector: #selector(didUpdatePassiveLocation), name: .passiveLocationManagerDidUpdate, object: nil) + os_log("CarPlayMapViewController did subscribe to free drive notifications.", log: logger, type: .info) } func unsubscribeFromFreeDriveNotifications() { NotificationCenter.default.removeObserver(self, name: .passiveLocationManagerDidUpdate, object: nil) + os_log("CarPlayMapViewController did unsubscribe from free drive notifications.", log: logger, type: .info) } @objc func didUpdatePassiveLocation(_ notification: Notification) { diff --git a/Sources/MapboxNavigation/CarPlayNavigationViewController.swift b/Sources/MapboxNavigation/CarPlayNavigationViewController.swift index 5442a2972be..7d8b07731f8 100644 --- a/Sources/MapboxNavigation/CarPlayNavigationViewController.swift +++ b/Sources/MapboxNavigation/CarPlayNavigationViewController.swift @@ -2,6 +2,7 @@ import Foundation import MapboxDirections import MapboxCoreNavigation @_spi(Restricted) import MapboxMaps +import os.log #if canImport(CarPlay) import CarPlay @@ -94,6 +95,8 @@ open class CarPlayNavigationViewController: UIViewController, BuildingHighlighti private var safeTrailingCompassViewConstraint: NSLayoutConstraint! private var trailingCompassViewConstraint: NSLayoutConstraint! + + private let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "CarPlayNavigationViewController") func setupOrnaments() { let compassView = CarPlayCompassView() @@ -149,8 +152,10 @@ open class CarPlayNavigationViewController: UIViewController, BuildingHighlighti func updateTripEstimateStyle(_ userInterfaceStyle: UIUserInterfaceStyle) { switch traitCollection.userInterfaceStyle { case .dark: + os_log("TripEstimateStyle set to dark.", log: logger, type: .info) mapTemplate.tripEstimateStyle = .dark default: + os_log("TripEstimateStyle set to default/light.", log: logger, type: .info) mapTemplate.tripEstimateStyle = .light } } @@ -413,6 +418,7 @@ open class CarPlayNavigationViewController: UIViewController, BuildingHighlighti super.traitCollectionDidChange(previousTraitCollection) if previousTraitCollection?.userInterfaceStyle != traitCollection.userInterfaceStyle { + os_log("Trait collection changed.", log: logger, type: .info) updateTripEstimateStyle(traitCollection.userInterfaceStyle) updateManeuvers(navigationService.routeProgress) } @@ -516,6 +522,7 @@ open class CarPlayNavigationViewController: UIViewController, BuildingHighlighti selector: #selector(didUpdateRoadNameFromStatus), name: .currentRoadNameDidChange, object: nil) + os_log("CarPlayNavigationViewController subscribed for notifications.", log: logger, type: .info) } func suspendNotifications() { @@ -542,6 +549,7 @@ open class CarPlayNavigationViewController: UIViewController, BuildingHighlighti NotificationCenter.default.removeObserver(self, name: .currentRoadNameDidChange, object: nil) + os_log("CarPlayNavigationViewController suspended notifications.", log: logger, type: .info) } @objc func visualInstructionDidChange(_ notification: NSNotification) { @@ -648,6 +656,8 @@ open class CarPlayNavigationViewController: UIViewController, BuildingHighlighti let simulatedSpeedMultiplier = notification.userInfo?[MapboxNavigationService.NotificationUserInfoKey.simulatedSpeedMultiplierKey] as? Double else { return } + os_log("Simulation state did change.", log: logger, type: .info) + switch simulationState { case .willBeginSimulation: navigationMapView?.storeLocationProviderBeforeSimulation() diff --git a/Sources/MapboxNavigation/CarPlaySearchController+CPSearchTemplateDelegate.swift b/Sources/MapboxNavigation/CarPlaySearchController+CPSearchTemplateDelegate.swift index ab227c23122..5030764ea46 100644 --- a/Sources/MapboxNavigation/CarPlaySearchController+CPSearchTemplateDelegate.swift +++ b/Sources/MapboxNavigation/CarPlaySearchController+CPSearchTemplateDelegate.swift @@ -1,6 +1,7 @@ import Foundation import CarPlay import MapboxDirections +import os.log @available(iOS 12.0, *) extension CarPlaySearchController: CPSearchTemplateDelegate { @@ -21,6 +22,7 @@ extension CarPlaySearchController: CPSearchTemplateDelegate { let template = CPListTemplate(title: delegate?.recentSearchText, sections: [section]) template.delegate = self delegate?.pushTemplate(template, animated: true) + os_log("CarPlay search template search button pressed", log: logger, type: .debug) } public func searchTemplateButton(searchTemplate: CPSearchTemplate, @@ -76,6 +78,7 @@ extension CarPlaySearchController: CPListTemplateDelegate { let destinationWaypoint = Waypoint(location: location) delegate?.popTemplate(animated: false) delegate?.previewRoutes(to: destinationWaypoint, completionHandler: completionHandler) + os_log("Search item selected from list", log: logger, type: .debug) return } } diff --git a/Sources/MapboxNavigation/CarPlaySearchController.swift b/Sources/MapboxNavigation/CarPlaySearchController.swift index 4e5f1031a4c..444d54b994f 100644 --- a/Sources/MapboxNavigation/CarPlaySearchController.swift +++ b/Sources/MapboxNavigation/CarPlaySearchController.swift @@ -1,4 +1,5 @@ import Foundation +import os.log /** `CarPlaySearchController` is the main object responsible for managing the search feature on CarPlay. @@ -14,4 +15,6 @@ public class CarPlaySearchController: NSObject { The `CarPlaySearchController` delegate. */ public weak var delegate: CarPlaySearchControllerDelegate? + + let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "CarPlaySearchController") } diff --git a/Sources/MapboxNavigation/MapTemplateProvider.swift b/Sources/MapboxNavigation/MapTemplateProvider.swift index 60fde627d7e..551c132e496 100644 --- a/Sources/MapboxNavigation/MapTemplateProvider.swift +++ b/Sources/MapboxNavigation/MapTemplateProvider.swift @@ -1,7 +1,9 @@ import CarPlay +import os.log @available(iOS 12.0, *) class MapTemplateProvider: NSObject { + private let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "MapTemplateProvider") weak var delegate: MapTemplateProviderDelegate? @@ -12,6 +14,7 @@ class MapTemplateProvider: NSObject { mapTemplate.mapDelegate = mapDelegate let currentActivity: CarPlayActivity = .previewing + os_log("CarPlayActivity changed to previewing", log: logger, type: .debug) if let leadingButtons = delegate?.mapTemplateProvider(self, mapTemplate: mapTemplate, diff --git a/Sources/MapboxNavigation/NavigationMapView+RoadNameLabeling.swift b/Sources/MapboxNavigation/NavigationMapView+RoadNameLabeling.swift index 4c4d29400ec..8cf35620839 100644 --- a/Sources/MapboxNavigation/NavigationMapView+RoadNameLabeling.swift +++ b/Sources/MapboxNavigation/NavigationMapView+RoadNameLabeling.swift @@ -1,6 +1,9 @@ import MapboxMaps import MapboxDirections import MapboxCoreNavigation +import os.log + +private let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "RoadNameLabeling") extension NavigationMapView { @@ -23,7 +26,7 @@ extension NavigationMapView { do { try mapView.mapboxMap.style.addSource(streetsSource, id: sourceIdentifier) } catch { - NSLog("Failed to add \(sourceIdentifier) with error: \(error.localizedDescription).") + os_log("Failed to add %s with error: %s.", log: logger, type: .error, sourceIdentifier as CVarArg, error.localizedDescription) } } @@ -82,7 +85,7 @@ extension NavigationMapView { try mapView.mapboxMap.style.addLayer(streetLabelLayer, layerPosition: layerPosition) } catch { - NSLog("Failed to add \(roadLabelStyleLayerIdentifier) with error: \(error.localizedDescription).") + os_log("Failed to add %s with error: %s.", log: logger, type: .error, roadLabelStyleLayerIdentifier as CVarArg, error.localizedDescription) } } @@ -164,7 +167,7 @@ extension NavigationMapView { wayNameView.containerView.isHidden = hideWayName case .failure: - NSLog("Failed to find visible features.") + os_log("Failed to find visible features.", log: logger, type: .error) } } }