Beginning tvOS Development with TVML Tutorial

Learn how to create your first tvOS app for the Apple TV in this TVML tutorial for complete beginners! By Kelvin Lau.

Leave a rating/review
Save for later
Note from Ray: Congratulations, you did it! By helping to spread the word about the iOS 9 Feast, you unlocked the second tutorial of the feast. This is a brand new tutorial – we hope you enjoy!

Last Wednesday Apple announced the new Apple-TV – along with what we’ve all been dreaming of, the ability to write our own apps for it!

I and the rest of the Tutorial Team have been digging into the tvOS SDK to prepare some great tvOS tutorials for you. To get you started, Chris Wagner wrote a post giving a broad overview of tvOS, and I’ve been working on this tutorial, designed to be your first steps in tvOS development.

In this tutorial, you’ll make your first tvOS app using TVML – Apple’s Television Markup Language. Believe it or not, you’ll use JavaScript to manage your app’s logic, and create TVML templates to present your UI.

By the end of the tutorial, you should have a basic grasp of managing tvOS apps using TVML and TVJS. Let’s get started!

Note: This tutorial requires Xcode 8 or later – you can download it here. It’s also recommended to have some basic Javascript knowledge, although you can still follow along with the tutorial even if you are new to Javascript as everything is step-by-step.

Choose Your Adventure

Apple has provided developers two ways to develop tvOS apps:

  1. TVML Apps: The first uses an entirely new process utilizing TVML, TVJS and TVMLKit. I’ll explain what these abbreviations mean and how this works in a moment.
  2. Custom Apps: The second uses familiar iOS frameworks and concepts you know and love like Storyboards, UIKit, and Auto Layout.

Both ways are a completely valid way to make apps; it depends what you’re trying to do.

In this tutorial, your goal is to create this simple tvOS that streams RWDevCon conference videos:


Although you could create this app using either method, it is much easier to do so as a TVML app, so that is what you will be doing in this tutorial. To learn why, let me tell you a little bit more about how this works! :]

What is TVML?

As mentioned, the first method of making apps is via TVML, TVJS, and TVMLKit. If these abbreviations sound foreign to you, don’t fret because they should. Here’s what they are:

  • TVML is a form of XML and stands for “Television Markup Language”.
  • TVJS is set of JavaScript APIs which provide you with the means to display apps created with TVML.
  • TVMLKit is the glue between TVML, JavaScript, and your native tvOS application.

If you’re a native iOS developer the thought of these might make you wince a little bit. But keep an open mind, there is some great power to all of this.

Here’s a very typical use-case for apps on Apple TV. Consider the following: you have content on a server and you want to display that content to users. Your content is organized in a predictable manner and navigating it should be intuitive and familiar. You want your tvOS app to feel at home with other apps. You’re not interested in pushing the envelope on cutting edge user experiences and designs.

TVML architecture

This is exactly the situation we have in this tutorial. We already have a RWDevCon website that hosts the conference videos, so it would be quite easy to host some TVML templates there. We don’t have crazy requirements for the UI, so we can easily make use of some of Apple’s pre-made templates.

TVML templates

In short:

  • Make a TVML App if you primarily provide menus of content, especially if you already have a server set up.
  • Make a Custom App if you’re aiming to provide a fully immersive experience in your app, where your users will be spending more time interacting with your interface than passively watching or listening to content.

Now that you have a high-level understanding of how TVML works and why you’re using it in this tutorial, the best way to understand it further is to try it out yourself. Let’s start coding!

Getting Started

First make sure you have Xcode 7.1 or later installed and open on your machine.

Then go to File\New\Project and select the tvOS\Application\Single View Application template, and click Next:

Selecting the tvOS template in Xcode

For the Product Name enter RWDevCon, for the Language select Swift, make sure both checkboxes are unchecked, and click Next:


Choose a directory to save your project and click Save. Xcode will create a empty project for you with a Storyboard (which you would use if you were creating a tvOS Custom App).

However, you won’t need that because you are are making a TVMP app, which uses TVML files to display the UI rather than a Storyboard. So delete Main.storyboard and ViewController.swift from your project and select Move to Trash.

Next, head into the Info.plist and remove the Main storyboard file base name key. Finally add a new value App Transport Security Settings(case sensitive), and as its child, add Allow Arbitrary Loads, and set that value to YES.

Setting app transport security settings in Info.plist

Note: Adding this key to your Info.plist is necessary because as of iOS 9, your app will prevent linking to non-HTTPS servers to encourage best practices. In this tutorial, you’ll be testing against a local server without HTTPS enabled, so you’ll disable the default behavior.

Loading your TVML

The life cycle of the tvOS app starts with the app delegate. Here, you will set up the TVApplicationController to pass control and the application context to the main JavaScript files.

Open AppDelegate.swift and do the following:

  • Delete all the methods
  • Import TVMLKit
  • Have your app delegate conform to TVApplicationControllerDelegate

At this point your file should look like the following:

import UIKit
import TVMLKit

class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate {

  var window: UIWindow?


Next, add the following variables to the class:

var appController: TVApplicationController?
static let TVBaseURL = "http://localhost:9001/"
static let TVBootURL = "\(AppDelegate.TVBaseURL)js/application.js"

TVApplicationController is a class in TVMLKit that handles communicating with your server. TVBaseURL and TVBootURL contains the paths for your server and JavaScript code, which you will be running on your localhost later.

Next add the following method to the class:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
  window = UIWindow(frame: UIScreen.main.bounds)

  // 1
  let appControllerContext = TVApplicationControllerContext()

  // 2
  guard let javaScriptURL = URL(string: AppDelegate.TVBootURL) else { fatalError("unable to create NSURL") }
  appControllerContext.javaScriptApplicationURL = javaScriptURL
  appControllerContext.launchOptions["BASEURL"] = AppDelegate.TVBaseURL

  // 3
  appController = TVApplicationController(context: appControllerContext, window: window, delegate: self)
  return true

This code is relatively straight forward:

  1. Here you create a TVApplicationControllerContext, which you will use to initialize your TVApplicationController. Think of this as a simple object you fill with information such as the URL of your server.
  2. You fill the context with two bits of information: the path to your main Javascript file, and the root directory of your server.
  3. This starts up the TVApplicationController with the context you configured. At this point, Apple’s code takes over – it will pull down your root Javascript file and begin executing it.

And with that, it’s time to take a break from Xcode. Next, you’re going to write JavaScript!


Over 300 content creators. Join our team.