-
Notifications
You must be signed in to change notification settings - Fork 317
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
Logging functionality for CarPlay #3653
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a factory for loggers? So that we don't duplicate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or we can go with a simpler way: creating an internal constant for the log subsystem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could use something like |
||
|
||
/** | ||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be good to go through all methods in |
||
} | ||
} | ||
|
||
|
@@ -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] { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it for debugging? If so, don't forget to remove this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for retrieving log entries if you want to see them printed to a file instead of looking at the log via the Console. This functionality is only available via iOS 15. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there are several build errors because of |
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that |
||
|
||
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<String, Any>, | ||
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() | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ import Foundation | |
@_spi(Restricted) import MapboxMaps | ||
import MapboxCoreNavigation | ||
import MapboxDirections | ||
import os.log | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be useful to have logging information when |
||
|
||
#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) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
import MapboxMaps | ||
import MapboxDirections | ||
import MapboxCoreNavigation | ||
import os.log | ||
|
||
private let logger: OSLog = .init(subsystem: "com.mapbox.navigation", category: "RoadNameLabeling") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we use private global constants in other classes too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We needed one here since you can't create stored properties in extensions. For consistency, we should either move constants to be global or use a manager for these OSLog constants |
||
|
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes. I will try this. Thank you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need casting to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cast was needed since os_log uses |
||
} | ||
} | ||
|
||
|
@@ -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) | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to add logging for
CPTemplate
lifecycle callbacks inCarPlayManagerDelegate
:carPlayManager(_:templateWillAppear:animated:)
carPlayManager(_:templateDidAppear:animated:)
carPlayManager(_:templateWillDisappear:animated:)
carPlayManager(_:templateDidDisappear:animated:)