Posts

Post marked as solved
2 Replies
0 Views
We have actually contacted Developer Technical Support for this and while the response wasn't exactly what we needed it pointed us in the right direction to come up with something that works for us. Note that there are still scaling issues when ALL items within a section have no detail text (but that's another issue). Here is what we use: extension CPListItem { convenience init(text: String?, detailText: String?, remoteImageUrl: URL?, placeholder: UIImage?, accessoryImage: UIImage? = nil, accessoryType: CPListItemAccessoryType = .none, imageOperation: RemoteImageOperation? = nil) { self.init(text: text, detailText: detailText, image: placeholder, accessoryImage: accessoryImage, accessoryType: accessoryType) setImageUrl(remoteImageUrl) } func setImageUrl(_ url: URL?) { guard let imageUrl = url else { return } Current.downloadImage(imageUrl) { image in guard let cropped = image?.cpCropSquareImage, let resized = cropped.resized(to: CPListItem.maximumImageSize), let carPlayImage = resized.carPlayImage else { return } DispatchQueue.main.async { [weak self] in self?.setImage(carPlayImage) } } } } extension UIImage { var carPlayImage: UIImage? { guard let traits = Current.interfaceController?.carTraitCollection else { return nil } let imageAsset = UIImageAsset() imageAsset.register(self, with: traits) return imageAsset.image(with: traits) } var cpCropSquareImage: UIImage { /* basic image cropping ... */ } func resized(to newSize: CGSize) -> UIImage? { /* basic image resizing ... */ } } The basic idea is to put the image in a UIImageAsset and take it out again which magically makes things work. Other than that we also crop it to a square and resize it to the maximum allowed image size. Our Current is like a dependency container where download is just a function to access our image cache/downloader and the interfaceController is the one we get when connecting the CarPlay scene (this is important for the native scale of the CarPlay display instead of the connected iOS device's display scale).
Post not yet marked as solved
1 Replies
0 Views
You can already access the development guidelines here: https://developer.apple.com/carplay/documentation/CarPlay-App-Programming-Guide.pdf After you have been accepted you get an email with that link and tell you to watch the WWDC20 video “Accelerate Your App with CarPlay”. They don't provide any sample code. This was for a CarPlay Audio entitlement so it may be possible that you get sample code if you're building an Automaker App.
Post not yet marked as solved
5 Replies
0 Views
I have taken a look at CarPlaySupport.framework with Hopper to check when this exception is thrown (calls to clientPushedIllegalTemplateOfClass). It is called from _templateIsValidForCurrentEntitlement which check whether the template is valid at all for the current entitlement (it is) and then there is this aforementioned check if the top view controller is a CPSNowPlayingViewController the template to be pushed has to be a CPListTemplate. Can you check again, that there are no calls to pushTemplate containing anything but list templates?
Post not yet marked as solved
5 Replies
0 Views
Hm, the crash mentions the grid template being pushed but maybe it is because you try to set the template as the root template (instead of embedding it in a tab template)? Tab and list templates might be the only allowed root templates. Another problem might be that you exceed the number of allowed templates in the navigation stack (afaik 5 for audio apps), so it just happens to be a grid template that's pushed on a "full" stack.
Post not yet marked as solved
12 Replies
0 Views
Using custom entitlements works by specifying separate entitlements files for the CODESIGNENTITLEMENTS key. I use xcconfig files for this: CODE_SIGN_ENTITLEMENTS = $(SRCROOT)/Config/MyApp.entitlements CODE_SIGN_ENTITLEMENTS = $(SRCROOT)/Config/MyApp_Mac.entitlements Of course, you can also do this in the build settings directly by specifying a platform conditional (Any macOS SDK)