KKCarPlayManager
2019 © KKBOX.
KKCarPlayManager 以简单、清晰和声明性方式实现 CarPlay 功能。
需求
- Xcode
- Swift 4.2 或以上
- iOS 8.0 或以上
安装
您可以通过 Swift 包管理器或 CocoaPods 安装此包。
CocoaPods
将 KKCarPlayManager
添加到您的 pod 文件中,然后运行 pod install
。
Swift 包管理器
只需将 https://github.com/KKBOX/KKCarPlayManager.git
添加到您的 Package.swift
文件中,或者,您可以通过在 Xcode 11 中选择 "文件" -> "Swift 包" -> "添加包依赖" 来添加此包。
示例
该项目有一个示例项目。前往Example
文件夹,运行pod install
,打开Example.xcworkspace
,构建并运行示例应用。
入门指南
苹果不允许CarPlay音频应用自定义用户界面。您不能在CarPlay上调用任何方法,而是让MPPlayableContentManager调用您,发现您的内容,并在结构化表格用户界面中列出它们。
KKCarPlayManager帮助您将内容构建成一个可被发现树。KKCarPlayManager已经为您实现了MPPlayableContentManager的数据源和代理,您需要做的就是给KKCarPlayManager提供一个根节点及其子节点。例如
// Import required modules.
import KKCarPlayManager
import MediaPlayer
import AVFoundation
// You should set at least one command of MPRemoteCommandCenter, otherwise
// MPPlayableContentManager won't call it data source and delegate.
MPRemoteCommandCenter.shared().playCommand.addTarget { event in
return .success
}
// Create a root node.
let rooNode = KKStaticContainerItem(identifier: "root", title: "Root", children: [
KKStaticContainerItem(identifier: "folder1", title: "Folder 1", children: [
PlayItem(identifier: "Song_1_1", title: "Song name", url: "song URL..."),
PlayItem(identifier: "Song_1_2", title: "Song name", url: "song URL..."),
]),
KKStaticContainerItem(identifier: "folder_2", title: "Folder 2", children: [
PlayItem(identifier: "Song_2_1", title: "Song name", url: "song URL..."),
PlayItem(identifier: "Song_2_2", title: "Song name", url: "song URL...")
]),
]
)
// Create your manager.
manager = KKCarPlayManager(rootNode: rooNode)
// Sets the data source and delegate of MPPlayableContentManager to the manager.
manager?.activate()
实际上,这些节点是KKBasicContentItem
的实例。它继承自MPContentItem
,您可以为您的需求子类化KKBasicContentItem
。
项目/节点
我们在KKBasicContentItem
中添加了三个方法。
KKBasicContentItem.children
:一个KKBasicContentItem
列表。KKBasicContentItem.loadChildren(callback:)
:请求项目加载其子项。KKBasicContentItem.play(callback:)
:播放项目。
有两种类型的项/节点,一种容器,另一种是可播放项。
容器
容器可以是播放列表或专辑列表。它有它的子项。当您在CarPlay屏幕上选择一个容器时,将调用KKBasicContentItem.loadChildren(callback:)
,CarPlay屏幕将进入下一级,以表格UI形式展示其子项。
如果您想从文件或从互联网加载数子项,子类化一个KKBasicContentItem,将isPlayable
设置为false,将isContainer
设置为true,在KKBasicContentItem.loadChildren(callback:)
中执行您的加载,并记得调用回调闭包。
KKCarPlayManager提供了一个内置容器项类型KKStaticContainerItem
。如果您有一个静态列表,可以直接使用这个类。
可播放项目
一个可播放项目可以是歌曲、有声书等。当选择一个可播放项目时,会调用KKBasicContentItem.play(callbackReward:)
方法,并开始播放。您应该在自己的应用中创建可播放项目的子类,因为我们很难知道您的播放器工作原理和为您创建类。
如果在播放过程中出现任何错误,请调用回调闭包并传递错误信息,否则可以传递nil
。
全功能CarPlay体验
当您想在自己的音频应用中启用CarPlay时,
- 您需要有一个有效的配置描述文件/权限,否则您的应用将不会出现在CarPlay屏幕上。请联系Apple。
- 您需要启用MPRemoteCommandCenter的部分命令,否则
MPPlayableContentManager
将不会调用其数据源和代理。 - 启用音频背景模式并设置AVAudioSession的当前类别为
.playback
,以启用背景播放。 - 根据上文所述,设置KKCarPlayManager。
- 一旦您的树发生改变,请调用
MPPlayableContentManager.shared().beginUpdates()
和MPPlayableContentManager.shared().endUpdates()
。 - 向MPNowPlayingInfoCenter提供正在播放的信息。
再来一件事
在Xcode 11中,您可以在导入KKCarPlayManagerExtensions
后使用类似于Swift UI的语法来构建节点。
let rooNode = KKStaticContainerItem(identifier: "root", title: "Root") {
KKStaticContainerItem(identifier: "folder1", title: "Folder 1") {
PlayItem(identifier: "Song_1_1", title: "Song name", url: "song URL...")
PlayItem(identifier: "Song_1_2", title: "Song name", url: "song URL...")
}
KKStaticContainerItem(identifier: "folder_2", title: "Folder 2") {
PlayItem(identifier: "Song_2_1", title: "Song name", url: "song URL...")
PlayItem(identifier: "Song_2_2", title: "Song name", url: "song URL...")
}
}
享受!