Introduction
At their annual September event for 2015, in addition to new iPhone and iPad models, Apple announced their long-awaited update to the Apple TV set-top box. This new, fourth generation Apple TV includes a powerful A8 processor, a Siri-enabled remote, a revamped user interface and, most importantly, a brand new platform for third party applications and games, which Apple has named tvOS.
In this tutorial, I am going to introduce you to tvOS development by creating a basic tvOS application. This tutorial requires that you are running Xcode 7.1 or later, which includes support for tvOS. I am also assuming that you are already familiar with iOS development.
1. Project Setup
Open up Xcode and create a new project. You'll immediately notice that the list of templates includes a section for tvOS applications. From the available templates, choose tvOS > Application > Single View Application.
Click Next and configure the project as shown below. I have opted for Swift as the project's language, but you can also use Objective-C to develop tvOS applications.
To finish setting up the project, tell Xcode where you'd like to save the project. The first thing you'll notice is that the project is structured almost identically to a regular iOS application. In the below screenshot, you can see that we have AppDelegate.swift, ViewController.swift, and Main.storyboard.
2. Building the Interface
The first major difference you will notice when working with tvOS is building the user interface of your app. When you open Main.storyboard, you will see a large, blank Apple TV screen. If you can't see the entire screen in the editor, then press Command-- to zoom out.
This screen is significantly larger because of the way tvOS apps are scaled. In modern iOS development, interface layout is handled by the use of points rather than pixels in order to make development easier on devices with Retina Displays.
For example, the iPhone 6 and iPhone 6s have a screen resolution of 1334x750, but only a screen size, in points, of 667x375. This means that all apps on the device run at a 2x scale. All of Apple's iOS devices that have a Retina Display run at a 2x scale, except for the iPhone 6 Plus and iPhone 6s Plus, which run at a 3x scale.
The new Apple TV, however, runs apps at a standard 1920x1080 resolution at a 1x scale. This means that, when building tvOS apps, the screen size, in points, that you must use when building your interface is also 1920x1080.
Now that you know how tvOS apps are scaled and displayed on the screen, we can start building our first interface. From the Object Library on the right, drag in a Button to the right hand side of your blank screen. With the button selected, at the bottom of your storyboard editor, click the Pin button and add the following constraints.
Next, drag in a Table View to the left of the button and add the following constraints. Also make sure that the Update Frames option down the bottom is set to All Frames in Container. Take a look at the below screenshot for clarification.
Select your table view, open the Size Inspector, and set the Row Height property to 88 as shown below.
Next, drag in a Table View Cell from the Object Library and add it to the table view. With the table view cell selected, open the Attributes Inspector and change the Style property to Subtitle.
Finally, press Control on your keyboard and drag from your table view to your view controller to set the view controller as the table view's data source and delegate. You can also do this using the Connections inspector on the right.
By building this tvOS interface, you will see that it is almost identical to building an iOS interface with the major difference being the significantly larger scale of items.
3. Understanding Focus
Let's now focus on some code. Open ViewController.swift and replace the implementation of the ViewController
class with the following.
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 3 } func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: nil) cell.textLabel?.text = "Item \(indexPath.row + 1)" cell.detailTextLabel?.text = "Subtitle \(indexPath.row + 1)" return cell } }
If you are familiar with iOS development, then the above implementation should look very familiar. You are now ready to run your very first tvOS application. Press Command-R or click the run button in the top left. Make sure that your test device is set to Apple TV 1080p.
Once the Apple TV Simulator has booted up and your application is launched, you should see the following screen:
Congratulations! You now have your very first tvOS app up and running. In order to control the app, you need to use the new Apple TV remote. To bring up the remote in the simulator, select Hardware > Show Apple TV Remote from the menu or press ⌘Command+Shift+R.
A small remote window should open up next to your simulator window. Play around with the remote by holding the Option button on your keyboard and moving your mouse cursor over the remote. You will see that, as you move your mouse cursor up and down, the selection in the table view changes.
Likewise, when you swipe to the right, the button on the right becomes selected.
In tvOS development, this is called changing the current focus item. Unlike iOS apps where users can tap anywhere on the screen at any given time, tvOS apps use a point-and-click style of interaction.
You do not need to do any extra work as a developer in order to have your interface elements be focusable in a logical order. The focus engine built into the UIKit framework on tvOS looks at the layout of your interface and handles all of the work in moving the focus from one item to another.
There are, however, many new methods and properties made available to you to programmatically control the way focus is handled within your app. Many of these are defined by the UIFocusEnvironment
protocol, which the UIViewController
, UIView
, UIWindow
, and UIPresentationController
classes automatically conform to. There are also multiple methods contained in the tvOS versions of the UITableViewDelegate
and UICollectionViewDelegate
protocols that can be used to control the focus within your app.
As an example, we are going to make the button on the right the default focus item. If you run the app now, you will see that the first item of the table is initially in focus. We are also going to disable the second item in the table view from being focusable. Add the following code snippet to the implementation of the ViewController
class:
override var preferredFocusedView: UIView? { return self.view.subviews[0] } func tableView(tableView: UITableView, canFocusRowAtIndexPath indexPath: NSIndexPath) -> Bool { if indexPath.row == 1 { return false } return true }
We first override the preferredFocusedView
property and return the first subview, which currently is the button on the right. The preferredFocusedView
property is read-only and can only be set by overriding its implementation as we have done. When the view controller is loaded, the focus engine will find the view returned by this property and automatically puts it in focus.
We have also implemented the tableView(_:canFocusRowAtIndexPath:)
method and return false
when the indexPath.row
is equal to 1. Otherwise we return true
. As you would expect, this delegate method determines whether or not a specific row can be in focus.
When you build and run your app again, you will see that the button on the right automatically receives focus at launch. If the button on the right doesn't automatically receive focus, then your app's view hierarchy may be slightly different, that is, the first subview of the view controller's view isn't equal to the button on the right.
You will also notice that when you try to navigate the rows of the table view, the middle row is skipped as dictated by the implementation of the tableView(_:canFocusRowAtIndexPath:)
method.
4. tvOS App Components and Limitations
While we won't be creating any images in this tutorial, it is important that you understand the different components that are required for tvOS apps as well as some of the limitations.
App Icons
Every tvOS app must provide two app icons:
- Large: 1280px x 768px
- Small: 400px x 240px
The main difference with iOS is that tvOS app icons can be composed of up to three layers. This is so that a parallax effect can be achieved on the home screen and anywhere else your app icon appears. If you want to see this effect for yourself, go to the Apple TV Simulator, press the Home button on the remote (the small TV icon). Focus the Settings app icon and hold the Option key while moving the mouse cursor around a little bit on the remote. You will see that the app icon responds to your movement and the different layers of the icon produce a nice effect.
Launch Image
Just like a regular iOS application, you must provide a static image to be displayed once your app has been opened and is loading. The main difference is that you only need to provide a single 1920px x 1080px image.
Top Shelf Images
If your app has been placed in the Top Shelf by a user, when focussed, you can display content right on the home screen of the Apple TV. There are three main types of content you can display:
- Static Image: This is just a 1920px x 720px image that you provide in your application bundle.
- Dynamic Content Layouts: This is where you display a series of images in an interface similar to a collection view. These images can be selected by your app at any time and do not have to be included in the application bundle. The three image sizes you can use are 404px x 608px, 608px x 608px, and 908px x 512px. Any combination of these three sizes can be used.
- Scrolling Banner: This is where you provide a set of wide aspect ratio images to display next to each other with one taking up the majority of the screen. This content type is similar to the home page of the iOS App Store. These images need to be 1940px x 624px in size.
Limitations
Despite the new Apple TV packing more storage than most iPhone devices with a minimum capacity of 32GB, there are some important limitations for tvOS applications. Firstly, apps can be no more than 200MB in size. Any content you need outside of this 200MB buffer will need to be downloaded using the On-Demand Resources API introduced with iOS 9 and now tvOS.
Another thing you also need to be aware of is that tvOS apps have no persistent local storage. This means that any data that you need to retain between app launches, such as game saves, photos and videos, will need to be stored in iCloud and retrieved when needed.
Conclusion
While we haven't written much code in this tutorial, I hope that it served as a good introduction to the tvOS platform. You now know the key similarities and differences between developing apps for iOS and tvOS as well as the limitations imposed on developers.
In future tutorials, we will be diving deeper into tvOS and discovering what is possible with tvOS and the new Apple TV.
As always, leave your comments and feedback in the comments below.