Skip to content

MapView never renders in CarPlay dashboard/instrument-cluster scenes — parentScene resolves nil for non-CPWindow CarPlay windows #2430

Description

@SafeNavJHB

Environment

  • MapboxMaps 11.18.3 (also present in current main)
  • iOS 18.x, CarPlay navigation app (com.apple.developer.carplay-maps), real head unit

Summary
A MapView placed in the CarPlay dashboard scene (CPTemplateApplicationDashboardScene, iOS ≥ 13.4) or instrument-cluster scene never draws a single frame — the Metal view stays transparent/black while sibling UIKit views in the same window render normally. The head-unit (CPTemplateApplicationScene) map is unaffected.

Root cause (traced in SDK source)
MapView only runs its display link while shouldRunDisplayLink(for: window?.parentScene) is true, and updateFromDisplayLink re-pauses on every frame when it is false (Sources/MapboxMaps/Foundation/MapView.swift).

UIWindow.parentScene (Sources/MapboxMaps/Foundation/Extensions/UIWindow+ParentScene.swift) resolves:

switch self {
case let carPlayWindow as CPWindow:
    return carPlayWindow.templateApplicationScene   // head unit — works
default:
    return windowScene                              // typed UIWindowScene?
}

The dashboard window handed to CPTemplateApplicationDashboardSceneDelegate.templateApplicationDashboardScene(_:didConnect:to:) is a plain UIWindow (not a CPWindow) attached to a scene that is not a UIWindowScene, so windowScene is nil → parentScene is nil → shouldRunDisplayLink(nil) returns false → the display link never starts, and the scene-activation notification path can't rescue it because the per-frame check re-pauses immediately.

Notably, the UIScene.allWindows helper in the same file already knows about both scene types:

if let carPlayDashboardScene = self as? CPTemplateApplicationDashboardScene {
    return [carPlayDashboardScene.dashboardWindow]
}

— only parentScene misses the reverse mapping.

Suggested fix
In the default: branch, fall back to scanning connected scenes with the existing helper when windowScene is nil:

default:
    if let scene = windowScene { return scene }
    return UIApplication.shared.connectedScenes.first { $0.allWindows.contains(self) }

We are running exactly this as a local pod patch and the dashboard map renders correctly with it. (If per-frame cost is a concern, the result could be cached per window — the per-frame updateFromDisplayLink check calls parentScene on every tick.)

Repro sketch

  1. CarPlay nav app with a dashboard scene declared (CPSupportsDashboardNavigationScene).
  2. In the dashboard scene delegate, add any MapView to the provided window's root view controller.
  3. Attach a dashboard-capable head unit (the simulator cannot display the dashboard scene; a real car or the standalone CarPlay Simulator app is required).
  4. Result: UIKit siblings render; the map never paints. Breakpoint in updateFromDisplayLink confirms window?.parentScene == nil → immediate pause.

Metadata

Metadata

Assignees

No one assigned

    Labels

    auto-triagedAutomatically triaged by AIbug 🪲Something is broken!

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions