AppleTV/tvOSでゲーム以外のアプリを開発をするときの勘所

レアジョブ唯一のアプリエンジニアの羽田です。
まだレアジョブではAppleTVアプリとかはやっていないんですが、前職や趣味でいくつかAppleTV開発に参画させていただいた経験から、**ユーティリティ系などを作るときの勘所があるので今後開発される方**の参考になればと思っています。

ご指摘などあれば編集リクエストなどを送っていただければ幸いです。

**＊この時作ったアプリがApple Best 2016 AppleTVに選ばれました！！**
![SS_1.png](https://qiita-image-store.s3.amazonaws.com/0/31237/7a6f1f20-7273-2dcf-6907-0a020157ed46.png)


# 1. 【作る前に】そもそも本当にやる必要があるのかどうか

AppleTVが販売されて半年以上経とうとしていますが、正直あまりまだ復旧しているとは言い難いです。
[Apple tv tech talk](https://developer.apple.com/videos/techtalks-apple-tv/)に参加した時も販売台数とか聞きに行ってみたら、「んふふ、内緒！」みたいな感じで濁されましたし。
販売台数などは公開されていませんが、アプリのランキング上位のDAUなどを見てもまだまだこれからだと思っています。**またいろいろな制約や、要求される体験のちがいがあり、これを認識していないとアプリを作るハードルが一気に上がります。**

## 1_A. 要求される体験との親和性

[Apple tv interface guideline](https://developer.apple.com/tvos/human-interface-guidelines/)によれば、AppleTVでは**shared experience**という体験を提供することが推奨されています。

> Create a **shared experience**. People often enjoy TV in a communal environment. Consider how your app can appeal to a group, as well as what happens if the user is a different person each time your app is launched.

これが何かというと、iOSやMacOSのアプリケーションは一人で使うのに対してtvOSのアプリケーションは**複数人で大きな画面を見ながら触れることが前提**になっています。

そのため、今リモコンを持っている人がどこに注目しているのか、それを実現するためにFocus engineというのが搭載されていたり、その他にも様々な仕組みが組み込まれています。

この体験と、これから作ろうと思っているものがマッチしているのか。これを検討してください。
例えば自分のみしか見る必要のない個人のライフログを観覧するアプリや、タスク管理アプリなどはiOSのほうが便利ですよね。SiriRemoteは正直そこまで操作性が高いとは言えません、文字列入力も大変です。**あまりアクティブに操作する様なアプリケーションは向いていない**と思われます。
AppleTVの体験とマッチしないものをわざわざ作るのは間違っています。

## 1_B. ブラウザがない問題

ご存知の通り、webブラウザがなくすべてAPI経由での開発になります。
そこで問題になってくるのが、**webへ流入させたりが難しいので、既存のアプリやwebとは異なるエコシステムになってしまうことが多々ある**ことです。

これは結構大きな問題で、動画サービスなどであれば自社コンテンツの動画を見るという体験をまずさせることができれば、そのポテンシャルはとても大きいのですが、ECやCGMのようなものはいかにサービス成長のためにAppleTVのコンテンツを使うか結構頭をしぼらないと出てきません。

また一方でそもそものユーザーの母数も少ないので、見込める結果についても期待値計算が難しいと思います。


## 1_C. 思ったより多い機能制限
iOSではあったような魅力的なセンサー類や、先述の通りブラウザがありません。
これにより、できることはより限られます。

また後述しますがtvOS用の言語であるTVMLやTVJSを使った場合さらに多くの制限が生まれるので、
まず**アイデアがそもそも実装可能か？**というのを[公式リファレンス](https://developer.apple.com/jp/documentation/General/Conceptual/AppleTV_PG/AboutAppleTV/AboutAppleTV.html)を見て確認してください。

**＊作る前に**
ここまで考えて「やっぱうちのサービスはAppleTV対応したほうがいい！」「このアイデアはAppleTVに向いている！」と思ったのであれば続きをどうぞ


# 2.【デザイン】大画面とリモコン操作

AppleTVでは画面とインターフェースが離れているので、リモコンと音声でこれを操作する仕組みがあります。

![appletv_siri_remote_hand_primary-100625783-large.png](https://qiita-image-store.s3.amazonaws.com/0/31237/f25b8e39-41ae-db46-860b-a6d6ed95acd6.png)

これによってモバイルやPCとはまた異なるデザイン思想が必要になります。

## 2_A.大画面
開発者としては嬉しいことに、tvOSは1Deviceだけなので複数デバイス対応や横幅対応などは必要ありません。
ただユーザーはテレビを見るので、シミュレーターで見ているよりももっと大画面で見ることが期待されます。

また**アプリと異なり、画面とユーザーの距離が大きく離れています**、スマホであれば見づらければ画面を近づければいいですがテレビだとそうもいかないですよね。

[視聴距離の計算](https://www.toshiba.co.jp/regza/detail/howto/size_01.html)の例を見ると、**一般的な画面と人の距離はテレビの高さの1.5倍から3倍**で、大きく離れます。そのため文字の最小サイズやコンテンツサイズなど、思っているより大きなものが求められます。

**大きいコンテンツが必要だということは、表示される画像の画質**なども関わってきます。CGMの場合ユーザーが投稿する画像の画質が高いとは限らないので実際作ってみると残念な感じになることも・・・


## 2_B.リモコン操作

ユーザーは大画面の中の要素選択のためにリモコンをスワイプし、目的の要素にたどり着いたらクリックをしてやっと選択ができます。スマホの様にすぐ目的の要素をクリックすることができません。

そこでシームレスなアプリ体験のためにはコンテンツの連続性を考えなければいけません。

![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/31237/537d3a00-c9f5-7057-faf7-c240fddb5c55.png)

ユーザーがコンテンツにたどり着くまでのフローで混乱させない様な要素設計が必要になります。
この**どの要素をフォーカスしているときに、どの方向にスワイプすると、フォーカスがどのように移動するか？みたいのはデフォルトで動く以外にも実装して指定することも可能**です。エンジニアと相談してみてください。


## 3_C.画像リソース
![スクリーンショット 2016-05-17 9.10.32.png](https://qiita-image-store.s3.amazonaws.com/0/31237/2446b9cc-27eb-4524-7127-2bb291901c0b.png)
アプリiconに関して異なる仕様で用意する必要があります。

[Icons and Images](https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/)を確認してみてください。

画像サイズは@1xで大丈夫。
> All images on Apple TV are @1x resolution.

![スクリーンショット 2016-05-17 9.11.15.png](https://qiita-image-store.s3.amazonaws.com/0/31237/72b2fa8d-ebe1-a393-5ede-1f07b710a84d.png)
また**画像はフォーカスされることによって見え方が変わる**ことがあり、そのときに違和感のない様なデザインが必要になります。


# 3. 【開発】構成と設計と実装

AppleTVでは開発に使える選択肢がいくつかあります、実装言語や構成。
そこについて述べます。

## 3_A. 構成

スタンドローンなアプリケーションか、webのようなクライアントサーバ構成で作ることができます。
これらを比較してみましょう。

| | スタンドアローンアプリケーション | クライアントサーバ構成 |
|:-----------|------------:|:------------:|
| 開発言語       |        swift/ObjC |    TVML,TVJS     |
| デバッグ       |        楽 |    面倒     |
| リリース       |        審査必要 |    ネイティブに関わる変更・申請時のみ     |
| クライアント       |        なし |    サーバが必要     |

### 開発言語

TVML,TVJS・・・何言ってんだと思いますが、あるんです。
HTML,JSのtvOS版ですね。
[TVML tutorial](https://www.raywenderlich.com/114886/beginning-tvos-development-with-tvml-tutorial)をみるとクライアントサーバ構成でTVMLを使って開発するやり方が載っています。

### デバッグ
HTMLやJSとは結構違うし、Console.logとかでログを出せるんですが、[tvOSのデバッグでTVJSのconsole.logを見る方法](http://qiita.com/jumbOS5/items/2d557c60c69924e76ee9)にも書いた様にSafariでログ見ないといけなくてきつい。

### リリース・クライアント
サーバにクライアントのTVML,TVJSを置いて管理するのでアプリケーションの更新はサーバ側で行います。
ここは審査を待たずにリリースできるのでいいところかもしれません・・・と思ってましたが、**結局webっぽい管理コスト（デプロイの仕組み、バージョニング、ログ管理、etc...）が必要になってきます。そのくせwebとは違う**ものなので、既存の便利な仕組みが使えません。

一方で当然メリットもあって、**Templateがとても便利**なことです。これはレイアウトを組むだけでなく、FocusEngineの仕組みや、アニメーション、フォーカス時にタイトルのラベルも一緒に拡大されるなどの細かいデザインの嬉しいものがいろいろ機能してくれるので本当にすぐアプリは作れます。
<img width="959" alt="スクリーンショット 2016-05-17 11.08.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/31237/0a9ce3d6-038c-6263-e1f3-f2057c6a9321.png">


## 3_B. 設計・開発
設計に関してはデザインや開発前に考慮することで検討していた様なことが問題なければこれまでと変わりません。
気をつけるべきなのは開発ですね。

### ライブラリ
<img width="541" alt="スクリーンショット 2016-05-17 9.33.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/31237/6681f02e-8b82-9b12-78c4-b04a00849b8e.png">
cocoapodsでは対応していないライブラリも多くあります。AFNetworkingやSDWebImageのようなモダンで誰もが使っていそうなライブラリは結構対応しています。

### UIImageView
![スクリーンショット_2016-05-17_9_35_24.png](https://qiita-image-store.s3.amazonaws.com/0/31237/eb866565-ee16-8637-e92a-622ba94d1675.png)
画像をCollectionViewやTableViewの要素とするときに選択できる様にここのチェックをonにしなければいけません。実際に**フォーカスは当たっていてもその視覚効果をつけるために必要なプロパティ**になります。

### UITableView/UICollectionView
[Mastering the tvOS Focus Engine](http://nerds.airbnb.com/tvos-focus-engine/)をみると詳しく書いてあります、フォーカス管理のためのDelegateメソッドが追加されていて、これを使ってフォーカス管理をします。

フォーカスが次に当たるindexpathは以下の様にとれます。

```
func collectionView(collectionView: UICollectionView, shouldUpdateFocusInContext context: UICollectionViewFocusUpdateContext) -> Bool {
        let selectedRow = context.nextFocusedIndexPath?.row
}
```

## 3_C.API
これに関しては既存のものをうまく使えばいいんですがね・・・
静的なjsonとかでもいいなってなれば、無料でホスティングできるサービスとかいっぱいあるのでぜひ使ってみてください。個人的にはAzureのフリープランを使うといいと思います。
githubと連携もできるし、すぐデプロイやオートスケールが使えます。以下の設定ファイルをルートにおけばデプロイがちょろっとできます。

```
<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>
  </system.webServer>
</configuration>
```

## 3_D.審査
<img width="499" alt="スクリーンショット 2016-05-17 9.50.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/31237/bbf92be6-bfac-33c1-e34b-0f56c0132a69.png">

24時間で通るっぽいです

＊20160601_次のバージョンの申請は24時間で通りませんでした！たまたまだった・・・


# まとめ
今回開発に参加した以下のアプリでも上記の様なことを考えて実装をしました。
[“テレビを窓に変える”、Apple TV向けに風景動画を配信する「LandSkip」](http://av.watch.impress.co.jp/docs/news/20160516_757569.html)

サービスとの親和性もありますが、新デバイスに対応することは多くの知見やモチベーションなどを生むのでエンジニアやデザイナーが**クリエイターシップを持って開発を主導し、自社サービスの新たな価値提案をできるといいと思います。**