import CarPlay import UIKit /** * CarPlay scene delegate for KRYZ Go! * * Shows a CPListTemplate with the KRYZ Live Stream item. Tapping it triggers * playback via AppDelegate.invokePlay(), then presents CPNowPlayingTemplate. * * CarPlay enforces its own design system for safety — colors cannot be customised. * The app icon (which carries the KRYZ brand orange) is used as item artwork to * provide visual continuity with the phone app. * * Note: the com.apple.developer.carplay-audio entitlement must be enabled in the * Apple Developer Portal and added to the target in Xcode Signing & Capabilities. */ @available(iOS 14.0, *) class CarPlaySceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate { private var carPlayInterfaceController: CPInterfaceController? private var listTemplate: CPListTemplate? // MARK: - CPTemplateApplicationSceneDelegate func templateApplicationScene( _ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController ) { carPlayInterfaceController = interfaceController interfaceController.setRootTemplate(makeListTemplate(), animated: false, completion: nil) } func templateApplicationScene( _ templateApplicationScene: CPTemplateApplicationScene, didDisconnectInterfaceController interfaceController: CPInterfaceController ) { carPlayInterfaceController = nil listTemplate = nil appDelegate?.invokeStop() } // MARK: - Template construction private func makeListTemplate() -> CPListTemplate { let artwork = CPListItem.maximumImageSize let icon = UIImage(named: "AppIcon")? .withRenderingMode(.alwaysOriginal) let item = CPListItem( text: "KRYZ Live Stream", detailText: "KRYZ Radio", image: icon ) item.handler = { [weak self] _, completion in self?.handleStreamItemTapped() completion() } let section = CPListSection(items: [item]) let template = CPListTemplate(title: "KRYZ Go!", sections: [section]) template.tabTitle = "KRYZ Go!" template.tabImage = icon listTemplate = template // Silence unused-variable warning _ = artwork return template } // MARK: - Playback private func handleStreamItemTapped() { appDelegate?.invokePlay() carPlayInterfaceController?.pushTemplate( CPNowPlayingTemplate.shared, animated: true, completion: nil ) } // MARK: - Helpers private var appDelegate: AppDelegate? { UIApplication.shared.delegate as? AppDelegate } }