tvOS Tutorial: Using TVML Templates
In this tvOS tutorial, you’ll learn how to use TVML templates and templating engines to make great-looking user interfaces. By Chris Belanger.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
tvOS Tutorial: Using TVML Templates
35 mins
- Getting Started
- Loading Scripts
- TVML Templates
- The Product Template
- Data Injection
- Reading JSON From the App Bundle
- Injecting Data Into the Document String
- Resolving Image URLs
- Using the Mustache.js Templates
- Template Sections
- Filling out the TVML Template
- Adding Shelves
- Handling Text Overflow
- Event Handling
- Viewer Ratings
- Collecting Ratings
- Where to Go From Here?
In this tutorial, you’ll learn how to use the plethora of TVML templates that Apple has provided to make some stunning interfaces. You’ll use these templates to build a comprehensive screen for RWDevCon 2015 videos, which will include a wide range of information about the video and display it in an appealing and recognizable manner.
Getting Started
You can download the starter project for this tutorial here.
The sample app for this tutorial is wenderTV; it lets you browse and watch raywenderlich.com video content on your Apple TV, so you can enjoy a vast quantity of knowledge – and bad jokes – from the comfort of your sofa. Right now, wenderTV is quite empty.
wenderTV includes a lot of resources you’ll use during this tutorial; we’ve also reorganized some of the code to make it easier to understand.
Build and run the wenderTV starter project from Xcode; you’ll notice the screen is completely blank. This is because there aren’t any TVML documents in wenderTV yet. Before you can turn your attention to creating some TVML documents, you have a little housekeeping to do.
Loading Scripts
The project for wenderTV already has ResourceLoaderJS
split out into its own file, so you need to discover how to import it into main.js.
TVJS provides the evaluateScripts()
function which takes an array of URLs of JavaScript files and a callback. The function reads each URL in turn, attempts to parse it and adds any contained functions and object definitions to the context’s global object. Finally, it invokes the supplied callback with a Boolean denoting success or failure.
The AppDelegate
contains code that provides the JavaScript application with a list of URLs to the required JavaScript files as part of the launch options object. Open main.js and add the following code to the App.onLaunch()
function:
// 1:
evaluateScripts(options.initialJSDependencies,
function(success){
if (success) {
// 2:
resourceLoader =
new ResourceLoaderJS(NativeResourceLoader.create());
var initialDoc = loadInitialDocument(resourceLoader);
navigationDocument.pushDocument(initialDoc);
} else {
// 3:
var alert = _createAlert("Evaluate Scripts Error",
"Error attempting to evaluate the external JS files.");
navigationDocument.presentModal(alert);
throw ("Playback Example: unable to evaluate scripts.");
}
});
Taking this new function body step-by-step:
-
The
options
object is prepared in Swift and then passed to the JavaScript app in the app delegate, while theinitialJSDependencies
property is an array of URLs for the different JavaScript files that need to be loaded as the app starts.evaluateScript()
performs this action and then invokes the callback indicating whether it was successful. -
If the JavaScript sources evaluated successfully, create a
ResourceLoaderJS
object before using it to load the initial document and then pushing this TVML document onto the navigation stack.loadInitialDocument()
is currently a stub method you’ll populate in a bit. -
If the JavaScript files failed to load, there is nothing more that the app can do. Therefore it uses
_createAlert()
, defined at the bottom of main.js to build and present an alert document and then throw an error.
Add the following to loadInitialDocument()
:
return resourceLoader.getDocument("video.tvml");
This uses the resource loader to get the TVML file from the app’s resource bundle and return it as a DOM object.
Next up, you’ll need to create the file your app is trying to load: video.tvml.
Head into Xcode, and right-click on the layouts group in the project navigator. Select New File…:
Navigate to tvOS\Other\Empty and hit Next. Name the file video.tvml and ensure that the wenderTV target is checked:
Open the new file in either your favorite XML editor (or Xcode, if you insist) and add the following lines:
<?xml version="1.0" encoding="UTF-8" ?>
<document>
<productTemplate>
</productTemplate>
</document>
This defines a simple TVML document using a new type of template: productTemplate
.
Build and run the app to see how things look so far:
Hmm. The screen is still blank. Although you’ve created the file and provided the template, you haven’t provided any content. You’ll fix that shortly, but first you need to cover a bit of background on TVML templates.
TVML Templates
A TVML document is just an XML (eXtentible Markup Language) document with a specific schema defined by Apple. If you’ve used HTML in the past, XML will look familiar. HTML isn’t actually XML (despite some failed efforts with XHTML), but the syntax and structure is fairly similar.
Since TVML documents are XML they should start with the following line:
<?xml version="1.0" encoding="UTF-8" ?>
This is known as the XML prologue; it notes this file is an XML document and which character encoding it uses.
The TVML document has a root
element, which is a single element at the top level of the document and the parent (or ancestor) of all other elements. The
element has a single direct descendant, which can be one of 18 possible template tags.
A template tag specifies the top-level layout tvOS should use to render the document on screen. In addition to specifying the appearance onscreen, template tags also convey some semantic information about the content they contain. Templates might look similar, but have entirely different purposes.
TVML templates can be divided into the following categories:
- Informational: Shows a small amount of information to the user, and optionally requests input from the user. It’s not designed for browsable content. Includes alertTemplate and loadingTemplate.
- Data Entry: The user experience of entering data on TVs is pretty horrendous, and Apple TV is no different. However, there are a few templates for requesting data from the user, including searchTemplate and ratingTemplate.
- Single Item: Displays information or content about a single product or item, such as a film or episode in a TV series. Includes productTemplate, oneupTemplate, compilationTemplate and showcaseTemplate.
- Collections: Displays a collection of products, such as a TV series, a genre of films or tracks on an album. Includes stackTemplate, listTemplate and productBundle.
- Other: Includes menuBarTemplate, which hosts a set of other templates, and divTemplate, which is a completely clean slate upon which you draw.