陳小嬰
Parenting 數位研發
11 min readOct 28, 2021

--

CarPlay Audio APP開發紀錄_1

開發指南、權限申請、Framework串接

開發指南

CarPlay app guidelines

  1. CarPlay app 必須設計為提供使用者單一特定功能
  2. 訊息中不得包含提示用戶操作iPhone執行任務,若需要登入,可提示用戶於安全時採取行動
  3. 所有使用流程都可以在不與iPhone交互的情況下使用
  4. 所有使用流程都必須在針對在駕駛情況時使用的功能設計,不應包含與主要功能無關的任務(ex 不相關的設定、維修等功能)
  5. 不應包含遊戲和社交網路
  6. 不應在CarPlay螢幕上顯示簡訊、訊息、文本或電子郵件內容
  7. 將模板用於預期目的,並使用指定模板套入資訊(ex 使用列表模板顯示提供選擇、使用播放模板顯示專輯封面)
  8. 所有語音交互必須使用SiriKit處理,CarPlay 導航除外

音頻APP附加規範:

1. 禁止於CarPlay螢幕顯示歌詞

2.禁止朗讀文本(ex 網址閱讀、email閱讀)

通訊APP、電動汽車、導航、停車、速食點餐有各自的規範,請自行查看 CarPlay App Programming Guide

Human Interface Guidelines

  1. 始終提供內容,即便因網路接收不佳而造成數據不可使用,也要提供佔位符或緩存以便系統可以生成介面
  2. 系統允許最深為5層模板(速食訂餐限2層),但建議三層為限
  3. 使用 tab來簡化頁面層級
  4. 優先顯示最相關的內容(ex音樂APP優先顯示最近加入列表的,並放在第一個)
  5. 一鍵式播放(隨機播放、繼續播放)能增加便利性
  6. 某些情況於行駛或超過特定速度時可能會截斷內容列表,當模式為active時,考慮顯示精選的基本訊息和選項
  7. 提供簡潔的標題和描述
  8. 出現在導航結構中的圖片(ex專輯圖片)有助於改善外觀及一目了然當前位置
  9. 不要在CarPlay上執行設定步驟,也不要鼓勵使用者於中途拿起手機設定
  10. 應於開始播放和結束播放時更新Now Playing頁面的訊息
  11. 不要重新定義播放控件的意義
  12. 中斷時在適當的時機恢復播放
  13. 僅在必要時向使用者在CarPlay上顯示錯誤,而不是在iPhone顯示或者指示使用者拿起iPhone,顯示狀態消息優於在提示框顯示錯誤
  14. 載入狀態要標示清楚,使用佔位符標記即將顯示的內容,最好是提前載入即將使用的內容
  15. 音樂APP使用平面導航和分層導航,快速的達到目標頁面,最少點擊、滑動和頁面
  16. 保留上次使用的狀態,以便從中斷的地方繼續,避免自動恢復音頻播放,除非它是您的應用程序的主要功能並且是用戶所期望的
  17. 為每個畫面提供路徑,路徑必須合乎邏輯、可預測且易於遵循
  18. 導航欄可顯示當前在結構中的位置,返回鍵則返回上一層頁面
  19. 僅當內容準備好播放時才轉換到Now Playing頁面
  20. 由於緩沖和網絡條件,用戶選擇音頻後可能需要幾秒鐘時間才能開始播放。用戶的選擇保持highlighted顯示,並顯示一個旋轉的活動指示器,直到您的應用程序通知系統音頻已準備好播放。
  21. 音頻和顯示訊息可分開加載
  22. 避免自動開始播放。除非您的應用程序的目的是播放單個音頻源,或者您的應用程序正在恢復先前中斷的音頻,否則在用戶啟動它之前不應開始播放。
  23. 在多種照明條件下預覽您的應用程序以查看顏色的顯示方式,並且使用足夠的色彩對比度
  24. 避免在CarPlay上顯示action sheets,這會破壞用戶體驗且增加使用複雜性
  25. 不要禁用或刪除Tab Item,而是在頁面中解釋為何內容無法使用

模板

Alerts、Lists、 Tab bar為通用模版,依照APP權限不同,可使用不同的特定功能模板。

If you attempt to use a template not supported by your entitlement, an exception will occur at runtime.

audio app 只能使用Alert、Grid、List、Now Playing、Tab bar模板,使用其他的模板會在運行時出現異常錯誤。

  • 提示框(Alerts)
  • 網格(Grid)
  • 列表(List)
  • 播放頁面(Now Playing)

Now Playing模板顯示來自MPNowPlayingInfoCenter和MPNowPlayingSession的訊息,通過調用控制器中的pushTemplate(_:animated:completion:) 方法將Now Playing推至導航結構中。

啟用專輯作者和下一首按鈕時,需實踐CPNowPlayingTemplateObserver協議,並調用模板方法add(_:)將其註冊為觀察者。

  • 標籤列(Tab bar)

APP 實作

申請CarPlay授權

申請連結:https://developer.apple.com/contact/carplay

嗯….很好….第一關就被擋下……開發帳號持有人才能申請。

配置開發權限(entitlement)&環境建置

a. 在Apple Developer控制台 App ID 開啟 CarPlay app 功能

b. 重新產生一個 Provisioning Profile簽署至XCode專案中

c. 如果專案中還沒有Entitlements.plist,則新增一個

Entitlements

於Entitlements.plist中新增對應的權限,下方為播放音頻的權限:

<key>com.apple.developer.carplay-audio</key>
<true/>

其他key請看這裏

Starting with iOS 14, CarPlay audio apps may use the CarPlay framework to present a customized user interface. CarPlay audio apps that use the CarPlay framework must include the com.apple.developer.carplay-audio entitlement. CarPlay audio apps that use the Media Player framework must include the com.apple.developer.playable-content entitlement. If you want your CarPlay audio app to support iOS 13 and earlier, you must support the Media Player framework and include this entitlement. CarPlay apps that support the Media Player framework will continue to work on iOS 14.

CarPlay audio apps 版本限制iOS 14以上!OMG~

歐!還好可以用Media Player framework,再新增一個key就好。為了要相容,我是兩個都加。

<key>com.apple.developer.playable-content</key>
<true/>

d.關閉自動簽署功能(Automatically manage signing),在 Build
Settings下的 Code Signing Entitlements路徑設為剛剛建立的Entitlements.plist

引入CarPlay.framework

CarPlay audio app 可使用 CarPlay framework 或 Media Player framework。

Info.plist

Application Scene Manifest/Enable Multiple Windows 改為True

新增Scene,一個iPhone的、一個CarPlay的

設定APP Icon

CarPlay App icon 應與iPhone上顯示的App icon相似

顯示畫面

講了那麼多終於要來寫code拉~

import CarPlay

2. 實踐CPApplicationDelegate接口和設定根視圖

class MyCarPlaySceneDelegate: UIResponder, CPTemplateApplicationSceneDelegate {    var interfaceController: CPInterfaceController?    func templateApplicationScene(_ templateApplicationScene: CPTemplateApplicationScene, didConnect interfaceController: CPInterfaceController) {        self.interfaceController = interfaceController        let item = CPListItem(text: "My title", detailText: "My subtitle")        let section = CPListSection(items: [item])        let listTemplate = CPListTemplate(title: "Albums", sections: [section])        if #available(iOS 14.0, *) {            interfaceController.setRootTemplate(listTemplate, animated: true, completion: nil)        }    }}

用模擬器來看看(開CarPlay模擬器的方法在下方↓)

折騰了那~~~~麼久,看到這個畫面真的好感動啊!!!!就跟第一個”Hello word” 一樣。 QAQ

開模擬器

a.開啟任一XCode模擬器

b.導覽列的I/O → External Displays → CarPlay

While Simulator is useful during development, certain CarPlay features are not available in
Simulator and you should not rely on it as the sole method to develop your app.

無法在模擬器測試的項目:

  • iPhone鎖定時功能仍然要正常運作
  • 測試Siri正常運作
  • 測試音頻,播放音頻時停用audio session (ex 導航語音提示時會將收音機音量降低,語音提示播放完畢之後將音量升高)

意思就是只用模擬器開發不夠,去找一台CarPlay來測試吧!

在實機上運行

It is highly recommended to develop and test CarPlay apps using a car or aftermarket system that supports wireless CarPlay.

iPhone 接線Mac,藍芽連線CarPlay,好主意!

除了測試iPhone和CarPlay之間各種狀態的交互、實體播放按鈕(方向盤上的那個),阿對了!Apple 指南有提到,建議要在較差的網絡條件下進行測試,例如隧道或收訊訊號不好的地方。

弄到這裡就已經完成CarPlay的第一步:有概念、有畫面

剩下的實踐下集待續……

--

--

陳小嬰
Parenting 數位研發

喜愛動物又注重環保的iOS工程師就是我。Write the code change the world.