I am new to CarPlay development. I am working on an app that has four tabs. The first tab has a POI template. I make an API call, once the data is received, I need to refresh the POI template to display the data received. Below is a sample code. Please guide me on this. Right now I am pushing a new template once data is obtained which is not the right behaviour
func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) {
self.interfaceController = interfaceController
let tabs = CPTabBarTemplate(templates: [firstTab(), secondTab(), thirdTab(), fourthTab()])
interfaceController.setRootTemplate(tabs,
animated: true,
completion: nil)
}
func firstTab() -> CPTemplate {
// Placeholder template while data is loading
let placeholderPOI = CPPointOfInterest(location: MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0))),
title: "Loading...",
subtitle: "",
summary: "Data is currently loading",
detailTitle: "",
detailSubtitle: "",
detailSummary: "",
pinImage: nil)
let placeholderTemplate = CPPointOfInterestTemplate(title: "EV Stations", pointsOfInterest: [placeholderPOI], selectedIndex: 0)
// Asynchronously update the template once data is loaded
Task {
await loadAndUpdateTimeConsumingData(for: placeholderTemplate)
}
return placeholderTemplate
}
func loadAndUpdateTimeConsumingData(for template: CPPointOfInterestTemplate) async {
do {
// Simulate a 1-minute delay
try await Task.sleep(nanoseconds: 60 * 1_000_000_000)
// Mock data
let stations = [Station1(name: "Station 1", city: "City A", address: "123 Lane", coordinates: (latitude: 12.3456, longitude: 76.7890))]
let pointsOfInterest = stations.map { station -> CPPointOfInterest in
let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: station.coordinates.latitude, longitude: station.coordinates.longitude)))
return CPPointOfInterest(location: mapItem,
title: station.name,
subtitle: station.city,
summary: station.address,
detailTitle: "",
detailSubtitle: "",
detailSummary: "",
pinImage: nil)
}
// Update the template
let poiTemplate = CPPointOfInterestTemplate(title: "EV Stations", pointsOfInterest: pointsOfInterest, selectedIndex: 0)
await MainActor.run {
self.interfaceController?.pushTemplate(poiTemplate, animated: true, completion: nil)
}
} catch {
}
}
Post
Replies
Boosts
Views
Activity
In Carplay, is it possible to update the navigation title and also add right tab bar items? Couldn't find these details in the documentation. Please suggest
I have a SwiftUI app, and Apple has approved the Carplay entitlement. The entitlement integration is done successfully, however when I try to launch the carplay app I get the below error
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Application does not implement CarPlay template application lifecycle methods in its scene delegate.'
Info.plist:
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
UISceneConfigurations
CPTemplateApplicationSceneSessionRoleApplication
UISceneConfigurationName
Default Configuration
UISceneDelegateClassName
$(PRODUCT_MODULE_NAME).CarPlaySceneDelegate
In AppDelegate I have the below
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
if connectingSceneSession.role == .carTemplateApplication {
let sceneConfiguration = UISceneConfiguration(name: "CarPlay Scene", sessionRole: connectingSceneSession.role)
sceneConfiguration.delegateClass = CarPlaySceneDelegate.self
return sceneConfiguration
}
// Configuration for other types of scenes
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
Why am I getting the exception? Kindly suggest
Following is a row item within a section of CPListTemplate,
CPListItem(text: "Station 1", detailText: "Details\nforStation 1")
In the above, is it possible to display data in three lines? I have seen couple of CarPlay apps that do it within a list. However, I am not sure how this can be done. Kindly suggest some ideas
Currently I have the below,
I want to achieve the below, three lines with a row
I have a list of items/cells where each item has many elements within it including a button. On tap of a cell, it navigates to screen say ViewA. And on tap of button within the cell, it goes to ViewB. However, on tap of the cell, instead of navigating to ViewA, it randomly navigates to ViewB even though the nav link isActive is disabled. Please suggest!
ViewA - List view
`List {
ForEach(testData, id: \.self) { index in
ZStack {
NavigationLink("", destination:ViewA()).opacity(0)
ViewAListItem()
}.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
.background(.clear)
}
}`
In another file,
struct ViewAListItem: View {
@State var test: Bool = false
/// some other code
///
///
///
Button(action: {
test = true
}) {
Text("Testing")
}.background(
NavigationLink("", destination: ViewB(), isActive: $test).opacity(0)
)
}
Here even though the button is not tapped, variable test is true and navigating to ViewB on tap of cell which should launch ViewAListItem instead. Any issue with this?