JavaScript
Swift
tvOS
TVML
appleTV
More than 1 year has passed since last update.

はじめに

appleTVアプリの日本語HowTo記事がなかったので
jamesonquaveさんのサイトを参考に手を動かしてみました。
http://jamesonquave.com/blog/developing-tvos-apps-for-apple-tv-with-swift/

ViewControllerやStoryBoardを使わず、
javascript上でXML(TVML)を作成して画面に表示しています。
(なのであまりSwiftの要素はないです)

やること

  1. Xcode7.1betaでtvOSのSingleViewApplicationを作成
  2. AppDelegate.swiftを改修
  3. main.jsファイル追加
  4. main.jsにXMLを返すメソッド追加
  5. info.plistにApp Transport Security Settings追加
  6. ターミナルで「python -m SimpleHTTPServer 8000」と叩く

1. Xcode7.1betaでtvOSのSingleViewApplicationを作成

Banners and Alerts.png

2. AppDelegate.mを改修

TVMLKitをインポートします。
TVApplicationControllerを追加します。
TVApplicationControllerDelegateを追加します。

起動時のapplicationメソッドを改修します。
やっていることとしては、アプリ起動時にmain.jsファイルの
App.onLaunchメソッドが呼ばれるようになります。

AppDelegate.swift
import UIKit
import TVMLKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate {

    var window: UIWindow?

    var appController: TVApplicationController?

    func application(application: UIApplication, didFinishLaunchingWithOptions
                   launchOptions: [NSObject: AnyObject]?) -> Bool
    {
        self.window = UIWindow(frame:UIScreen.mainScreen().bounds)

        let appControllerContext = TVApplicationControllerContext()

        let jsFilePath = NSURL(string: "http://localhost:8000/main.js")
        let javascriptURL = jsFilePath!

        appControllerContext.javaScriptApplicationURL = javascriptURL
        if let options = launchOptions
        {
            for (kind, value) in options
            {
                if let kindStr = kind as? String
                {
                    appControllerContext.launchOptions[kindStr] = value
                }
            }
        }

        self.appController = TVApplicationController(context: appControllerContext, window: self.window, delegate: self)

        return true
    }

    // application以降のメソッドは変更しないので省略します。

}

3. main.jsファイル追加

プロジェクトフォルダを右クリック > NewFile > Other > Empty の順に選択して
空のファイルを作成し名前を main.js とします。
main.js内に処理を書いていきます。

4. main.jsにXMLを返すメソッド追加

アプリ起動時のApp.onLaunchで、XMLを作成してModal表示するメソッドを追加します。

main.js
function getDocument(url) {
    var templateXHR = new XMLHttpRequest();
    templateXHR.responseType = "document";
    templateXHR.addEventListener("load", function() {pushDoc(templateXHR.responseXML);}, false);
    templateXHR.open("GET", url, true);
    templateXHR.send();
    return templateXHR;
}

function pushDoc(document) {
    navigationDocument.pushDocument(document);
}

// 起動時に呼ばれる
App.onLaunch = function(options) {
    alert();
}

App.onExit = function() {
    console.log('App finished');
}

// XMLを生成してモーダル表示
function alert() {
    var alertXMLString =
    `<?xml version="1.0" encoding="UTF-8" ?>
    <document>
        <alertTemplate>
            // 表示する文言
            <title>Hello AppleTV!</title>
        </alertTemplate>
    </document>`
    var parser = new DOMParser();
    var alertDOMElement = parser.parseFromString(alertXMLString, "application/xml");
    navigationDocument.presentModal(alertDOMElement);
}

5. info.plistにApp Transport Security Settings追加

画面に文字を表示する準備はできましたが、
このままですとiOS9のATSがHTTP通信をブロックしているのでうまくいきません。

info.plistに下記のようにApp Transport Security Settingsを追加し、
Allow Arbitrary LoadsをYESにして回避します。
スクリーンショット 2015-09-12 18.05.21.png.png

6. ターミナルで「python -m SimpleHTTPServer 8000」と叩く

コマンドラインでプロジェクトフォルダのmain.jsがあるディレクトリまで移動します。
ターミナルで「python -m SimpleHTTPServer 8000」と叩きます。
※動作確認後は「control + c」で終了できます

1. Python.png

7. アプリ起動

色々勝手が違って戸惑いましたが、ようやく準備が整いました。
アプリを起動してみましょう!
Apple TV 1080p - Apple TV 1080p _ tvOS 9.0 (13T5347l).png

まとめ

StoryBoardにLabelを置いて値をセットするHelloWorldとは
また違った難しさ、面白さがあったのではないでしょうか。

jamesonquaveさんのサイトに、なぜその設定が必要なのか
簡単に書いてあるので興味のある人は読んでみてください。
http://jamesonquave.com/blog/developing-tvos-apps-for-apple-tv-with-swift/

次回はボタンを使ってModal遷移を説明します
[appleTVでpresentModal画面遷移 AC俺 13日目]
http://qiita.com/senseiswift/items/eccc7b48328484c25976

参考ソース

https://github.com/senseiswift/appleTVtutorial