為邊緣開發獻上新知 — tvOS(上)

Toby Hsu
8 min readSep 23, 2019

--

今年的 iPlayground 很幸運的又投稿上了,就連續當了兩年的邊緣講者。🤣
因為投影片 PDF 很多都是影片的截圖,所以我想寫個文字稿來幫助大家了解我的投影片。

聽完這場 Session 你可能會有這種感覺

你可能在網路上有看過有人說我的 Session 很好笑⋯⋯😂
這說法是完全無誤的,因為我一開始的目標設定就是要讓大家在歡笑中可以很輕鬆、平易近人的吸收 tvOS 13 從 beta 到現在 GM 的各種心酸血淚。
畢竟,tvOS 這個平台本來接觸的人就不多,我如果講太 Hardcore 的內容,來聽的人恐怕一時都無法理解,何況在下午兩點的時段又是這麼的引人⋯⋯入睡。😴

因此,我就抱持著推廣 tvOS 的心態來開講了,如果因此你入坑買了一個 Apple TV,那我推薦你可以再買個 MFi 的搖桿可以一起玩 Arcade。😁

tvOS 13

Release Notes History

Release Notes Diff

其實每一版 tvOS Release Notes 我都有看,每次出新版本的時候我也有更新,然後檢查自己家跟常用的 App 有沒有被影響什麼。為什麼我要特別提 Release Notes History 呢?這段歷程其實是很「樸實無華且枯燥」的⋯⋯
因為它非常穩定的更新著 Beta 版號

Passing both ASAuthorizationAppleIDProvider and ASAuthorizationPasswordProvider to ASAuthorizationController is not currently supported on tvOS. (50897359)

但是這樣的歷程表達了非常重要的事情,就是直到了 GM 版我們都還無法在 tvOS 上開發 Sign In With Apple 的功能。還好 Apple 有個寬限期到 2020 年的四月,在這之前你的 App 都還是可以上版的,不過人生總是無法盡如人意⋯⋯如果你要上版的是個全新的 App 但好死不死有第三方登入的功能,你還是過不了 App Review Team 那關。💩💩💩

Content First Experience

為什麼今年 Apple 要提出 Content First Experience 呢?我認為是要解決 Focus 路徑的設計問題,它包括了遙控器的 Focus 移動以及使用者的 👀 注意力的考量,當然最終的目的都是為了提高使用者體驗。

Apple 為了達到這個目的而出了 Carousel Content 的 Top Shelf 跟 TVCollectionViewFullScreenLayoutTVCollectionViewFullScreenCell 來做到全螢幕的沈浸式體驗。

tvOS 12 的 Top Shelf

tvOS 12 & 13 的 Top Shelf 內容物的結構是不太一樣的,tvOS 12 的 Top Shelf Content 是可以有 Section 的概念(如上圖的 Most Popular 跟 Hot Pick),每個 Section 可以塞進不同數量的 Content Item。

tvOS 13 的 Top Shelf Content 就沒有 Section 了,取而代之的是全螢幕的內容顯示,並且提供了簡易的互動方式 playActiondisplayAction 讓使用者可以在還沒進到 App 之前就能做一些行為。除此之外,畫面上呈現的 metadata 也有助於使用者選擇內容,而 Content Item 的數量官方則是建議限制在 5 ~ 10 個就好,畢竟目前這排內容並沒有循環設計,你要從最後一個內容回到第一個,你必須一直滑一直滑⋯⋯😅

這邊提供一下實際使用的心得:
LoadTopShelfContent(completionHandler: @escaping (TVTopShelfContent?) -> Void) 這個 Function 是用來更新 Top Shelf Content ,文件上有寫說如果你想要觸發這個 Function ,可以直接呼叫 TVTopShelfContentProvider.topShelfContentDidChange() 這個 Static Function。而文件裡沒說的是:

  • 每 180 秒會觸發這個 Function 一次
  • 從 Apple TV 背景回到前景後會觸發一次
  • 在第一排的 App 上切換 Focus 目標時,每超過十秒才會觸發一次

如果你想要讓 tvOS 12 的 Top Shelf 跟 tvOS 13 並存你該怎麼做呢?官方回應是這樣子的:

For a single app to support a top shelf extension in both tvOS 12.X and below and tvOS 13 and above, then the app must have two extension.
One for tvOS 12.X and below using the “com.apple.tv-services” extension point.
one for tvOS 13 and above using the “com.apple.tv-top-shelf” extension point

對 tvOS 工程師有點困擾的是,目前第一次安裝 App 的時候 FullScreen Top Shelf 是可以正常顯示的,但是如果你改了點東西再按下安裝,你會發現 Top Shelf 恢復成舊版的樣式,目前唯一的解法是 移除你的 App 重新 Build Code 安裝一次

Pagination

FullScreen UI 其實在 tvOS 12.4.0 的 TV App就已經推出了,當時看到的我覺得非常的興奮,覺得這跟我對 Big Screen 的 UI Design 不謀而合,所以沒事我就會用這 App,沒想到滑一滑我就被 Ban 了,內容都 Bang 不見了啊~😂

好險大概 15 分鐘後重開 App 就可以正常使用了,大概每滑一頁就打了某個 API 吧,搞得好像我在 DDOS Apple。😰

Full Screen Layout

其實 TVCollectionViewFullScreenLayout 是一個 CollectionView 的 Layout,也就是 TV App 使用的 Layout。只要配合 TVCollectionViewFullScreenCell 就可以做到類似 TV App 的 UI。要注意的是⋯⋯

不要在 Storyboard 或 Xib 實作 TVCollectionViewFullScreenCell

因為你這樣做,UI 跟 Action 會跟你預期和 Smaple Code 看到的不一樣。🙄

用了 Storyboard or Xib
正確姿勢

另外一個小重點是,如果你放在背景的圖檔沒有足夠大的話,請記得設定塞到背景的 UIImageView Size,不然你就會發現你的圖怎麼都沒有好好顯示在全螢幕模式下。🤪

Multi-User Support

由於 Apple TV 被定位於家庭控制中樞,想當然家庭會有可能出現多使用者(複數個 Apple ID)的情境,基於這樣的情境 TVUserManager 就出現了。
每一個 App 可以有多個 TVAppProfileDescriptor 供每個 TVUserIdentifer 設定,所以透過這樣的組合你可以在 App 中針對不同的 Apple ID 做個人化的服務或推薦,這有點類似家庭方案中每個人可能有自己的片單的感覺。

可以透過 TVUserManager().presentProfilePreferencePanel 顯示選擇 Profile 的介面,以及在 NotificationCenter 註冊聆聽 selectedProfileDidChange 後即可得知帳號切換的事件。

官方 Sample Code

另外,目前這項功能不支援 Sandbox。🙃

你聽過 TV 可以旋轉嗎?

Customized Tab Bar

UITabBarController 多了一個 tabBarObservedScrollView ,可以設定 Tab Bar 要不要跟著某個 ScrollView 捲動,設定成 nil 就是固定在頂端了,使用時請注意 Safe AreacontentInsetAdjustmentBehavior 的設定。

UITabBar 則是多了左右兩側的 leadingAccessoryViewtrailingAccessoryView 可以放 UIView,所以終於可以放 logo 在 Tab Bar 囉!😁

為了方便閱讀,我就將文字稿分成上下兩集了。

為邊緣開發獻上新知 — tvOS(下)

--

--