Hello, I am build a CarPlay Audio Extension for our App. Users can listen to their Audio Playlist that they made in our App.
Loading remote images for CPListItem causes a problem. The images are always very small not filling out the full reserved space. If I put them as an asset in the app, the images are fully scaled. Anyone who ran into that problem and can help me out? Thank you. Cheers, Simon
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).