Since winning the lottery for a next-generation AppleTV development kit, I’ve been doing some experimenting with apps with both TVOS and Swift and with TVML and TVJS. TVML is an HTML-like markup language Apple provides that you can use to instantiate media browser-style components, and you can use TVJS, a Javascript implementation with some AppleTV-exclusive APIs, to manipulate it.
Better yet, you can use ClojureScript to generate your TVJS! Or at least if you shave a few yaks first. Here are the critical sticking points I had, and how to get over them.
First, the TVML document model. When a TVML-built app launches, its
first order of business is to download a Javascript file that will
execute in the TVML document context (see Apple’s documentation for
starting up a TVML app
here).
What you have is a NavigationDocument
in the global JS context as
navigationDocument
, which is just a container for actual TVML
documents you will push onto the stack for the user to see.
So given that, you’ll need to use ClojureScript to download a TVML
file, turn it into a Document
, and the push it onto the stack. (I’m
using cljs-ajax
here for
GET
):
That’s fairly clear I think: You have a server running that will
provide index.tvml
, you fetch it, parse it, and push it onto the
navigationDocument
stack. What took me a while was figuring out
exactly what parsing that document should look like: You can’t push a
string of TVML onto the stack, and there’s no new Document()
in
TVJS. (And incidentally, the debugging option is just using the Safari
developer console attached to the AppleTV Simulator, which isn’t the
greatest). Here’s what you actually need:
Fairly simple, but not well-documented.
For the record, stock Reagent was my initial plan for handling state and behavior on a ClojureScript-on-TVOS app, but that’s not currently an option. There’s a very alpha implementation of React for TVOS, but it seems like it might be a while until that’s a viable option. I’ll just be using stock ClojureScript for the time being.