CarPlay-Demo: Nivellierung auf dem Fahrzeugdisplay

Eigene Build-Konfiguration "CarPlay" samt Schema, damit der Versuchsbau neben
der TestFlight-App stehen kann: eigener Name, eigene Bundle-ID, persoenliches
Team, manuelles Signing. Debug und Release bleiben unberuehrt.

Wichtig dabei: Die Signing-Einstellungen stehen ausschliesslich in den
Target-Konfigurationen. Steht CODE_SIGN_STYLE auf Projektebene, schreibt der
naechste xcodebuild-Lauf alle uebrigen Konfigurationen auf Manual um und loescht
ihr Team – der TestFlight-Build waere damit hin.

Der CarPlay-Code haengt an `CARPLAY_DEMO` und existiert im regulaeren Build
nicht. Die Szene zeichnet in das gelieferte CPWindow; das CPMapTemplate darueber
bleibt leer, weil es auf dem Stellplatz nichts zu tippen gibt. Die Anzeige
sperrt sich oberhalb von 5 km/h selbst – erzwungen, nicht zugesagt.

Die Groessen sind auf die 400x240 Punkte ausgelegt, die CarPlay liefert, nicht
auf die 800x480 Pixel. In Pixeln gedachte Schriftgroessen sind auf dem
Fahrzeugdisplay doppelt zu gross und schneiden den Text ab.

Bekannt: Unter iOS 26.5 stuerzt Apples CarPlayTemplateUIHost beim Aufbau der
Navigationsleiste ab (`_updateShareButtonVisibility` fragt seinen
destinationSharingDelegate nach `vehicleSupportsDestinationSharing`, den dieser
nicht kennt). Beides ist privates API und von der App aus nicht erreichbar;
unter iOS 18 laeuft es. Szene und Root-Template werden vorher in beiden
Faellen akzeptiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
fototeddy
2026-09-10 18:35:33 +02:00
co-authored by Claude Opus 5
parent b1ffbe324a
commit ae12d8ede4
10 changed files with 715 additions and 0 deletions
@@ -0,0 +1,40 @@
import SwiftUI
/// Zeigt die CarPlay-Ansicht im iPhone-Simulator, in den Maßen, die CarPlay
/// tatsächlich liefert (400 × 240 Punkte, also 800 × 480 Pixel).
///
/// Nur zum Beurteilen des Layouts, solange der CarPlay-Simulator selbst nicht
/// zur Verfügung steht. Ohne `CARPLAY_DEMO_PREVIEW` in der Umgebung passiert
/// nichts, und ohne das `CARPLAY_DEMO`-Flag existiert der Code gar nicht.
extension View {
@ViewBuilder
func carPlayPreviewOverlay() -> some View {
#if CARPLAY_DEMO
if ProcessInfo.processInfo.environment["CARPLAY_DEMO_PREVIEW"] != nil {
CarPlayPreviewHost()
} else {
self
}
#else
self
#endif
}
}
#if CARPLAY_DEMO
struct CarPlayPreviewHost: View {
var body: some View {
// Ohne Beiwerk und exakt zentriert: so laesst sich der Screenshot
// verlustfrei auf den CarPlay-Bereich zuschneiden.
VStack {
CarPlayLevelScreen()
.environment(CarPlayLevelSource.shared)
.frame(width: 400, height: 240)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.black)
.ignoresSafeArea()
.onAppear { CarPlayLevelSource.shared.start() }
}
}
#endif