Developing a tvOS app - Weathervane

In our first article about the new Apple TV, we reviewed the new device as well as tvOS and briefly discussed the fact that there are two ways to create an app — the traditional way or by using TVML to create a client-server app. We wanted to try both, so we created a simple weather forecast app. The data was downloaded from, and we used the system’s location services to determine the location. In this article, we will take you through the development process.

Banner with apple tv and weather app

Traditional Development

The whole process is similar to app development for iOS. You can use most of the standard API, Interface Builder and storyboards, as well as CocoaPods. The only thing you need to check is if the Pod supports tvOS.

The important thing to remember is that your interaction with the remote control is completely different than the touchscreen on your phone. Therefore, you have to carefully work with the focus engine and create a layout that is easy to navigate. Apple TV’s “Human interface guidelines” is a must read before you start developing new layouts on tvOS.


When you are beginning with TVML development, it is best to briefly go through Apple’s documentation — programming guide, TVML reference and TVJS reference. You might also find inspiration by looking at Apple’s sample app.

This architecture is client-server. When you start it, it loads javascripts from the server, which you specify and runs it locally on Apple TV. All you need to do in Xcode is to provide access to the local services you eventually need (we needed CLLocationManager) and send it to your JavaScript.

TVMLKit also provides a complete XMLHttpRequest object that can be used to request resources from the network. Every page in a client-server app is built on a TVML template (there is now 18 of them — see below).

screenshot of alertTemplate settings

TVML templates define which elements can be used and in what order. Each template is designed to display information in a specific way. For example, loadingTemplate shows a spinner and a quick description of what is happening, while ratingTemplate shows the rating for a product. Each template page occupies the entire TV screen.

You control the flow of a client-server app through a JavaScript file that is called by your binary app.


Xcode project and local code

Creating a project is common for both traditional and TVML development. Just go to Xcode/new project and select tvOS Application.

Screenshot of Xcode settings

If you want to use pure TVML, you can delete Main.storyboard and ViewController.swift from your project. We created a TVMP app, which uses TVML files to display the UI instead of a storyboard. We then opened Info.plist and removed the Main.storyboard file base name key. You can use your local server (e.g. Python) for development.

Next, we needed to change the code in appDelegate. We needed to provide a path to the server where our JavaScript lies. The most important part is TVApplicationControllerContext. This object is responsible for downloading the root JS file from the server.

In this object, you can also store launch options for JavaScript, which provides you with a way to send data to the JS code. Once the app is launched, however, you cannot send additional data.

TVApplicationController starts loading JavaScript and whole UI starts as well.

The basic code can look like this:

screenshot of the code

This is all we needed to do in Xcode. We only needed to put in the location and set up temperature units (ºF to ºC). All the main functionality was done in JavaScript.

Server side

The folder structure we used was based on Apple’s example app, which we linked to above.

The js folder contains scripts for controlling the app: application is the main entry point, while Presenter is a wrapping class for handling screen presentation functionality (similar to push, presentViewController, etc.) and ResourceLoader is a class which manages loading resources. In templates, you can implement Apple templates like Alert, Page, etc. Images for the main layout we used can be found in resources.

Screenshot of resources

There is App.onLaunch = function(options) function in application. This is actually the main entry point. All the code you put into TVApplicationControllerContext in AppDelegate.swift is accessible here. If you would like to add more JS classes to your project, you can do it like this:

var javascriptFiles = [

Since you have to evaluate every single file that is in this array, you can use your new class later in your code. When your JS app is starting, your code might look like this:

Screenshot of the code when JS app is starting

The code basically fills the main template with data downloaded by an async request and then the main template can be rendered.


You have to respect the app’s design. When you are creating an app using TVML and TVJS, you have to stick with Apple’s guidelines, and your designer should always take that into consideration.

The difference between a traditional app and a TVML app is that the TVML XML template is transformed into UIKit objects. You have to look at the templates you want to use, as only certain elements can be in the hierarchy underneath other elements. The same rule applies to the styles. You will have to find out which CSS style you can use on certain elements.

Also, when designing a native tvOS app, it is important to remember that some TVs crop margins on all sides of the screen, so all user interface elements must have space between them and the edges.

App Store

The App Store submission process is pretty much the same as for any ordinary iOS app. The only change is the new Apple icon intertwined with a parallax effect. Apple provides a very good tutorial about how to create this icon in .lsr format. You can find the tutorial here. You can also create layered icons in Xcode Assets. When you’re uploading a TVML app, the final package will be very small since the main code lies on the server.


We’re going to share a repository on github with you. You can check the code of our TVML app. Go through the commits and see how the code was assembled. It’s a very easy app, which is good for understanding the basics. We’ll update the link here soon.


We all know that Apple changed its guidelines a while ago, allowing you to display content which is not generated locally. This was good news for all React Native lovers.

TVML is a powerful tool. Imagine you already have a functional website like a photo gallery or a restaurant menu. Instead of duplicating the whole functionality into an native app, you can easily make a TV app without much effort. And as a plus, the core functionality lies on the server, so you have access to it 24/7. When you really need something extra, like login flow for example, you can open native view controllers from JavaScript (since it runs locally).

During the traditional development process, you can essentially create anything from 3D games to a restaurant menu. But you’ll spend more time on the development process.

We have to make a decision: Do we create a quick app with limited functionality and a predefined layout, or do we spend more time on the development process to create a fully customized app? Apple allows us to use both traditional or TVML development to create tvOS apps. However for iOS apps, we are still limited to the traditional Apple development process (though we can use React Native, which is similar to TVML). Perhaps one day Apple will allow us to choose which development process to use across all its platforms.

Join our Hackathon

Interested in developing apps for Apple TV, Android TV or Chromecast? Join the STRV Hackathon in Brno on Saturday, 5 March!

Register here >

Join our Hackathon in Brno

Share Article
Daniel Ondruj

Daniel Ondruj

Lead Mobile Engineer at STRV. Developing applications for iOS and leading complex long term projects. Communicating primarily with US customers, coordinating graphic design, API design and testing.

You might also like...