添加 CarPlay 用户界面

Posted

技术标签:

【中文标题】添加 CarPlay 用户界面【英文标题】:Adding a CarPlay UI 【发布时间】:2017-12-31 06:22:34 【问题描述】:

我正在开发 CarPlay 支持的当前 iPhone 音频应用。我已经获得了 Apple 的批准并获得了开发授权,并观看了视频“为 CarPlay 启用您的应用程序”(https://developer.apple.com/videos/play/wwdc2017/719/)。视频中有一段 Swift 代码演示了如何添加 CarPlay UI:

func updateCarWindow()  
  
    guard let screen = UIScreen.screens.first(where: 
     $0.traitCollection.userInterfaceIdiom == .carPlay )  
    else  
      
        // CarPlay is not connected  
        self.carWindow = nil;  
        return  
      

    // CarPlay is connected  
    let carWindow = UIWindow(frame: screen.bounds)  
    carWindow.screen = screen  
    carWindow.makeKeyAndVisible()  
    carWindow.rootViewController = CarViewController(nibName: nil, bundle: nil)  
    self.carWindow = carWindow

我将其重写为 Objective-C 版本,如下所示:

- (void) updateCarWindow  
  
    NSArray *screenArray = [UIScreen screens];  

    for (UIScreen *screen in screenArray)  
            
        if (screen.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomCarPlay)  // CarPlay is connected.
          
            // Get the screen's bounds so that you can create a window of the correct size.  
            CGRect screenBounds = screen.bounds;  

            UIWindow *tempCarWindow = [[UIWindow alloc] initWithFrame:screenBounds];  
            self.carWindow.screen = screen;  
            [self.carWindow makeKeyAndVisible];  

            // Set the initial UI for the window.  
            UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];  
            UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"VC"];  

            self.carWindow.rootViewController = rootViewController;  
            self.carWindow = tempCarWindow;  

            // Show the window.  
            self.carWindow.hidden = NO; 

            return; 
          
     

    // CarPlay is not connected.
    self.carWindow = nil; 
  

但是我发现 UIScreen 的属性“screens”总是返回 1 个元素(主屏幕),无论是在真实设备还是模拟器上进行测试。因此,当我的应用程序在模拟器或带有 CarPlay 系统的真车上运行时,应用程序只是空白并显示“无法连接到“我的应用程序名称””(见下图)。我的 ViewController 虽然有一个简单的 UILabel。

我的问题是:我应该怎么做才能让 CarPlay 连接我的应用程序?也就是说,我应该如何获得具有 UIUserInterfaceIdiomCarPlay 习语的屏幕,而不仅仅是主屏幕?提前非常感谢。

【问题讨论】:

对这篇文章和我的实验的一些更新: 1. CarPlay 音频应用程序不能使用上面 updateCarWindow 方法中显示的基于 UIScreen 的方法。 2.如果我的AppDelegate符合MPPlayableContentDataSource和MPPlayableContentDelegate,并且如果我在AppDelegate.m中实现了数据源和委托方法,那么我可以看到我的CarPlay UI。 【参考方案1】:

CarPlay 音频应用由MPPlayableContentManager 控制。您需要实现 MPPlayableContentDelegate 和 MPPlayableContentDatasource 协议才能连接 CarPlay。用户界面由 CarPlay 控制 - 您需要做的就是为其提供选项卡+表格(数据源)的数据并响应可播放项目(委托)。

【讨论】:

感谢您的 cmets,Billy。 CarPlay 音频应用程序不能使用 WWDC 2017 视频中显示的基于 UIScreen 的方法。这就是我的 CarPlay 应用看不到任何 UI 的原因。 还有一个问题:要构建 CarPlay UI,我应该在作为 NSObject 子类的类中使用 MPPlayableContentManager API(MPPlayableContentDataSource 和 MPPlayableContentDelegate),然后在方法 -application 中实例化并初始化该 NSObject 子类:didFinishLaunchingWithOptions: 的 AppDelegate.m。它是否正确?再次感谢。 是的——你可以在任何地方初始化这个类。如果您希望所有用户都可以使用 CarPlay,那么 application:didFinishLaunchingWithOptions 是一个不错的选择。确保您的 NSObject 子类也是 MPPlayableContentDataSourceMPPlayableContentDelegate 的子类。 Billy,您的意思是 NSObject 子类符合 MPPlayableContentDataSource 和 MPPlayableContentDelegate 协议,还是子类 MPPlayableContentDataSource 和 MPPlayableContentDelegate ?谢谢。 谢谢,比利。我创建了一个符合 MPPlayableContentDataSource 和 MPPlayableContentDelegate 的 NSObject 子类 (CarPlayDemo)。我在 CarPlayDemo.m 的 -init 方法中分配了 MPPlayableContentManager 的 dataSource 和 delegate 属性,并在 CarPlayDemo.m 中实现了 MPPlayableContentDataSource 所需的方法 -numberOfChildItemsAtIndexPath: 和 -contentItemAtIndexPath: (但我还没有实现 MPPlayableContentDelegat 方法)。但是我发现 MPPlayableContentDataSource 方法从未被调用过。有什么想法吗?再次感谢。【参考方案2】:

自定义 UI 仅适用于 CarPlay 导航应用。对于音频应用,MediaPlayer 框架包含使用 CarPlay 所需的所有 API。

【讨论】:

嗨@DrMicketLaurer 我有自己的导航应用程序,它使用GLKitView(使用OpenGL ES)来绘制我的应用程序并在那里显示转弯导航。我可以把它放在地图模板中吗? @iori24 是的,这是允许的。当/如果您获得 CarPlay 地图开发的权利,您可以这样做。

以上是关于添加 CarPlay 用户界面的主要内容,如果未能解决你的问题,请参考以下文章

carplay语音控制高德地图没有反应

在 iOS Carplay 中延迟加载数据

如何为现有 iOS 应用添加 CarPlay 支持? [复制]

苹果CarPlay,从“小甜甜”变成了“牛夫人”

将 CarPlay 模拟器添加到我的 React Native 应用程序

应用程序未安装在真正的 CarPlay 设备上