Bring your apps to the big screen
A talk on porting your apps to tvOS
I'm going to talk to you about bringing your apps to the big screen. I'm actually not a Nacho Soto parody account, I'm a real person. As Ida said, I work on CocoaPods, I also work at Contentful where we build CMS as a service for web and mobile and also for the TV now. Oh yeah that slide is a little bit sad because I already handed all of those awesome coloring books out, so sorry. Who of you have got one of those Apple developer, Apple TV developer kits? A few. For those I'm probably not telling you too much new stuff but for everyone else I hope it's going to be interesting. I'm going to start with this quote which is actually from Steve Jobs' bio which said, "I'd like to create an integrated television set that is completely easy to use. It will have the simplest user interface you could imagine. I finally cracked it."
This quote is from ... It appeared the first time in an article in October 21 2011. It took almost 4 years until we finally got to see it in September. It takes a while to build something good. The future of TV is oh ... No it's apps. Actually you could say the future of TV is iOS. tvOS is so close to iOS that we even got API diffs between iOS and tvOS from Apple. There's a lot of frameworks there, we got AVFoundation, we got CoreData. We have even CoreText, we have a bunch of gaming frameworks, we have a bunch of media frameworks. We got UIKit which is cool but some things are missing. For example there's no WebKit which, at first, seems reasonable. We don't want web apps on the TV. But if you think about it, it's also annoying. If your app uses OAuth there's no way to simply bring up the web view where people can log in.
You have to do that via the phone or some other way. Also if you imagine somebody building a Twitter client for the TV, there are links in tweets right? What are you going to do with those? It's a bit annoying that WebKit isn't there. What's also not there, which surprised me, is Multipeer Connectivity because in the Apple keynote, they were talking about using iPhones as game controllers and stuff like this. I was thinking yes great, we'll use Multipeer Connectivity, it’ll be super easy, but no. First let's talk about how difficult it is to port existing apps. I looked at mostly gaming things actually so the first thing I say though is that you're going to probably have some CocoaPods in your apps that you want to port. It supports tvOS since 0.39.0 so you can already use it.
It's a new platform so that means pods need to be updated to support it. Actually it's not so many pods yet that support tvOS, that's the list that is on the public Specs repo we post, so far. If you have pods that you use which are not supported yet so the right way to do it is create forks and make pull requests to them. If you feel adventurous and want to build something quick, there is a CocoaPods plug-in, made by Orta, called CocoaPods-expert-difficulty which basically makes CocoaPods ignore the platform definition. You can use all pods but, of course, if the pods wouldn't work on the TV in the first place, it still doesn't work right? It might be a shortcut sometimes when you mainly use like non-UI pods or something like that.
Some things I try to port- one is a SpriteKit example that I did like, I think 2 years ago or something when SpriteKit originally came out, as a tutorial. That was actually super easy to port, I just created a new target and that was it. Like add the files and nothing more. Depending on the game, you might have to add different controls because, of course, there is no touchscreen. Porting SpriteKit things, also Metal, is very easy. Then I thought okay what other game can I find that is a little bit older and maybe more difficult? I looked around GitHub and found that Doom Classic is actually open source right? I tried to get that to work on the TV. At first code changes was actually pretty fine. You have some things that ... Like basically everything that is deprecated in UIKit is not available on the TV.
For example UIAlertView had to be replaced with UIAlertController. UISlider is not there, some other things are like different but that was not so much. Then all the AudioSession APIs aren't available because they don't make sense on the TV, so I took those out. Then something that happened because Doom uses C++, so tvOS basically enforces a newer C++ compiler so I had to change some things with that. It was like create all the targets and then it was compiling. But then I came to the nibs. Doom has like 20 nibs or so for all the menus and stuff like that. Unfortunately the iOS nibs don't work for TV, you just get this error and yeah- at that point, I was annoyed and didn't continue anymore, the port, so I don't know if it actually works. If you feel like copying and pasting stuff between some nibs, you can check out the thing on GitHub.
Another big difference to iOS is the storage limitations for apps on the TV. The app itself, so the application bundle, is limited to 200MB. Then you almost have no persistent storage, you have like 500KB that you can store in NSUserDefaults but you cannot write any files. The documents directory doesn't even exist, you have only the caches directory and the temp directory. The thing to do when you have to store any data is- use iCloud. If your app is actually bigger than 200MB, you have to use on-demand resources. Another thing that is different, of course, we have no direct manipulation. We have this little thing here with this touchpad and we're basically moving a cursor around. How does this work in UIKit?
Basically Apple introduced a new concept which is called Focus and all kinds of APIs, where it makes sense, have things like the canBecomeFocused. That's actually defined on UIView so any UIView can be something that can be focused or not. You can check if a certain view can be focused and you can also check for the currently focused view, so only one view can have focus. Basically if you click the touchpad, you do whatever action happens on the focused view. The other thing you can do is to react to focus changes. There's this didUpdateFocusinContext method on UIView. You get 2 parameters, one is the context where you can check what's the next focus view and which is the previous focus view so basically to figure out if a certain view gets the focus or loses it. Then you get the UIFocusAnimationCoordinator that has just one method which is addCoordinatedAnimations.
That basically allows you to add animations which go along with the animations the system already provides so that it all looks nice.
We’re going to do a little demo and build a little app for the TV. Let's close this, create a new project, going to call it Swift Summit maybe and let's go to the storyboard. Let's just add some buttons here.
Yeah this time it works. Great, great job Xcode you work and let's run it. Let's click a little bit around so that it wakes up the remote. Yeah it’s compiling asset catalogs… I don't think there's anything in there, doesn't really feel like this is going to do anything. Let's try it again, yeah- of course. Now we can hopefully do things, oh yeah right. Do you have to click in here? No. Let's try the ... Right this works. Not sure why this (the remote) doesn't work, okay whatever. In theory we could ... You can see what I actually wanted to show you. You see the focus, one button is focused, one isn't and normally you can move the focus between them. Let's move on back to the slides.
Something maybe you would also want to do is to use a microphone or a Siri but unfortunately there's no API access to the microphone at the moment. It's a little bit sad. Another thing we have as an input method on the Apple TV is this thing, game controllers. They've been around a while, I think since I was 7, they're supported on iOS. Now the same game controllers, if you've got one and one of the extended ones ... So basically there were 2 different kinds on iOS. You got the standard ones, I think, so these were those where you clip in your iPhone or something like this and just have a
D-pad and a few buttons. Then there were the extended ones which are standalone, connect via Bluetooth and have some sticks and stuff like this. Those also work on the Apple TV.
The API for them is really simple. Basically you just listen for the GCControllerDidConnectNotification then the object of the notification will be a GCController object. Then you can check for different protocols- There’s micro gamepad, the standard gamepad and the extended gamepad. The micro gamepad makes the most sense because it's the easiest way then to also support the Siri remote because it's also a micro gamepad, which we will come to in a later slide. Then you can basically use, for example, the property dpad on this microPad instance, attach a valueChangedHandler and get x and y coordinates. Pretty simple. What is nice is that game controllers also work with UIKit components.
What that means is you can use it in the main menu of the Apple TV and you can also use UIKit to build menus for your game. As I said, the Siri remote is also a game controller. There's a new GCMicroGamepad profile and basically the touchpad is a dpad. You have 2 buttons, one is the touch surface itself and one is the play/pause. You also have motion in the Siri remote that you can access via GCMotion. Unfortunately it seems to be that the game controller part of the Siri remote doesn't work with the simulator. One thing is important when you support game controllers so there's this 2.27 rule in the app review guidelines which says, "If your app's core functionality doesn't work with the Siri remote, it will be rejected."
You have to make sure that there is some way to control your game also with the Siri remote which, I guess, will be pretty annoying in terms of the buttons. I mean we can have 2 axis by using motion and the touchpad but we only have 2 buttons. Whereas on this thing, we have 8 buttons that we can use. If you actually want to make a game that uses all these 8 buttons, I'm not sure how that's going to play out. On iOS it was always the case that those games just put a lot of buttons on the screen but that's not really possible with the Apple TV anymore. Another thing that I found interesting and didn't expect is that you can only connect 2 game controllers plus the Siri remote.
This is especially interesting because if you look at this controller, and this is also the one that Apple shows, it has these 4 LEDs in the middle which shows which controller it is. Why 4 when you can only have 2 of them right? Anyway let's do another quick demo, actually shorter on time than I thought but I guess for this we're just going to open the project that I already have instead of live coding it. Basically I made a little SpriteKit game, there's this new thing in Xcode 7 which is kind of an Interface Builder for SpriteKit which is actually pretty nice. You can even animate things here so you can set all kinds of properties on your SpriteKit nodes right in this thing. Then yeah even show it here and then I added some code to this GameScene.
Conclusion yeah, tvOS works really well I would say especially compared to watchOS. If you know UIKit, it's really easy to start.
The only thing you have to think about is interaction and yeah the thing down there (on the slide) was ... I pondered doing a demo where I show open radars on an Apple TV app but that was a bit too much for the talk. There's some links on the slides and thank you.
Q & A
Q1: Hi Boris. Thanks for the talk. I also went back to an old game project I had for SpriteKit and then tried to port it into ... Using tvOS. It was pretty easy if I just put all of the code into the tvOS target but I wanted to put it in a framework that I could share between an iOS target and then a tvOS target. Like you can do in WatchKit right? I couldn't get it to work. I got it to work for the iOS target looking at the dynamic framework but I couldn't get it to work for the tvOS. Do you have any insight into why that's happening or ...
Boris: I've only done it with CocoaPods so I would trial that, that worked for me. I didn't try it in Xcode itself, creating multiple frameworks.
Q2: Hey Boris! Similar to how Christina was talking about compiling watchOS apps, I'm curious what your thoughts are on what would make a compelling tvOS app in the current state?
Boris: I think the most important part is that you don't have too much input. You can do text input in theory but it's really annoying with the remote. As I said, there's no microphone support. I think that's the main thing to think about, how can you do it in a way ... Like if you usually would have search in your app, how can you do it with categories or whatever so it's easier to navigate without hitting text input.
Q3: My question is about your thoughts on possible fragmentation in the developer community in the upcoming years. So far the different paradigms between OS 10 and iOS, obviously other than just being different platforms, there are a considerable number of differences in their frameworks. watchOS comes as part of having a phone but tvOS is such a different platform and the apps are so different in terms of the paradigm they bring with. How do you see the developer community evolving into maybe different camps in the upcoming years?
Boris: I would actually say that tvOS is much closer to iOS than watchOS. Even though the watchOS app is embedded in an iOS app and that stuff, the stuff you have to do to make it work is very different right? You don't have UIKit, you don't have a lot of frameworks. Whereas the TV is more or less iOS. I mean you have the different interaction paradigm but I think that's much easier to handle than having a completely different app. I don't really see that happening, I think it's very possible to work ... Like to share 90% of the code between a TV and an iOS app.
Q4: Hi I'm wondering if you've experimented with TVML at all and what ... I mean is it basically for creating the kind of app that was on the previous Apple TV or what kind of app is it?
Boris: I think that's the idea. I didn't play around with it much but it seems to be that this was also the way the previous apps worked. It's mostly for this ... Basically for video playing apps because it makes it easier to update stuff from the server. Everything comes from the server.