Swift中如何为CarPlay从URL加载图片替代Base64?
核心思路
原代码是同步加载Base64图片,换成URL异步加载后,无法在创建CPGridButton时直接拿到图片,所以要先创建带占位图的按钮,再异步加载图片并更新按钮的图片资源。
修改后的完整代码
private func updateGridTemplate() { guard let interfaceController = self.interfaceController else { return } var gridButtons = [CPGridButton]() for notification in storedNotifications { guard let configs = notification.incidenceConfigurations else { continue } for config in configs { // 先创建带占位图的按钮,保证UI先显示 let placeholderImage = UIImage(named: "Icon") ?? UIImage() let button = CPGridButton(titleVariants: [config.phrase ?? "Title"], image: placeholderImage, handler: { _ in self.showOptions(item: config) }) gridButtons.append(button) // 异步加载网络图片,替换占位图 guard let imageUrlString = config.icon, let url = URL(string: imageUrlString) else { continue } // 调用你已实现的异步加载方法,这里是示例实现 loadImage(from: url) { [weak self] loadedImage in guard let self = self, let image = loadedImage else { return } // CarPlay UI操作必须在主线程执行 DispatchQueue.main.async { button.image = image } } } } let leadingButton = CPBarButton(type: .text) { barButton in self.viewModel.makePhoneCall() } leadingButton.title = "CALL ME" if trailingButton == nil { trailingButton = CPBarButton(type: .text) { barbutton in print("") } } updateTrailingButtonTitle() let gridTemplate = CPGridTemplate(title: "MY APP", gridButtons: gridButtons) gridTemplate.trailingNavigationBarButtons = [trailingButton!] gridTemplate.leadingNavigationBarButtons = [leadingButton] interfaceController.setRootTemplate(gridTemplate, animated: true) } // 异步图片加载方法示例(如果还没实现可以直接用这个) private func loadImage(from url: URL, completion: @escaping (UIImage?) -> Void) { URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, error == nil else { completion(nil) return } let image = UIImage(data: data) completion(image) }.resume() }
关键注意点
- 占位图优先:先给按钮设置占位图,避免CarPlay界面出现空白,提升用户体验
- 主线程更新UI:CarPlay的所有UI操作必须在主线程执行,所以图片加载完成后一定要切换到主线程更新按钮的
image属性 - 避免循环引用:用
[weak self]捕获列表,防止闭包持有导致内存泄漏 - 缓存优化:如果需要频繁加载相同图片,建议添加缓存逻辑(比如用
NSCache),减少重复网络请求,提升性能
内容的提问来源于stack exchange,提问作者lacaveira
相关产品推荐
相关产品推荐

