How to port from iOS to tvOS?

I've looked all over and found several comments about how easy this is. I'm embarassed to say it but apparently I need a "dummies" guide because it's not at all obvious to me how to get started.


I've developed an iOS app that controls some HomeKit devices automatically. Once the user has entered their preferences, there is no ongoing need for interaction with the app (until the user changes their mind). There are limitations of that approach in iOS because:

1) An iPhone app cannot control HomeKit devices while the app is in the background, and

2) A hub such as AppleTV or iPad is required to enable remote control when the user is outside his home network.


Can an AppleTV app control Homekit devices from the background? If so, then extending my app to run on an appleTV hub makes good sense.

Here's what I'd love to do: I want my HomeKit controller app to run on an AppleTV hub so that it can operate autonomously, but have the iPhone app be the user's primary interface to the app on the hub. So preferences and settings changed in the iPhone app get mirrored to the hub app, which actually does the control. I want to use the phone interface I've already spent so much time developing. There's no reason for the AppleTV version to have much of an interface at all, except to turn it on/off, and perhaps to log into the Cloud to enable the transfer of preferences.


Does this strategy make sense? Are there examples somewhere that I could follow to get started on my first AppleTV app?


[edit] I should add that I've added AppleTV as a target in my iOS project. Without making any other changes, my app builds and installs to the AppleTV in Simulator. The debugger attaches. But there's no other indication that it's running. Nothing gets printed to the console and nothing appears on the screen.

Replies

OK, well I've finally had an AHA! moment. When you add a new target for the AppleTV, some new folders appear in the project files. I didn't notice that before and I've never added a target before so I had no idea.


Inside the new target's folder is a new AppleTV storyboard, viewcontroller, and app delegate. To add a resource such as an image from my iOS app to the AppleTV app, I select it in the Project Navigator (left hand side file navigator), then use the File Inspector (right hand side) to assign it to the new target.


My blank screen was because I had an empty storyboard with no code. Now I see that I can add buttons, pictures, whatever to the blank storyboard. Now I just have to figure out how to tie this all together.

  • No such AH HA! moment from me. I cannot find any new storyboard, view controller or app delegate. I have under my Target's supported destinations = iPad iOS and tvOS, with no apparent new items as already stated.

    Need some help here.

Add a Comment

Yup, you're on the right track. You should be able to share a lot of the same code between the projects, and if you can't you'll find this is helpful...


#if os(iOS)
  //code here will be ignored on the Apple TV
#endif


#if os(tvOS)
  //code here will be ignored on iOS
#endif


I use userInterfaceIdiom often too. For example...


if (UIDevice.current.userInterfaceIdiom != .tv){
//device is iPad or iPhone
}

Yup, I've gotten my iOS app up and running on the AppleTV simulator!


One trick that helped a LOT was learning that, while you cannot copy and paste in IB from an iOS storyboard to a tvOS storyboard, you can copy-and-paste the underlying XML code. This allowed for quickly recreating all the interface elements (buttons, textfields, labels, graphics and so on) into the tvOS storyboard. Basically, everything you have added to a view is a subview. You copy the entire subview section of the XML, paste it into the XML of the new tvOS storyboard and away you go.

The results are **** ugly and the constraints are all wrong, but at least you get all the right elements with the right names and so on, so that you can easily re-connect them all to the code in the new viewcontroller. I chose to use the veiwcontoller that was newly created for the tvOS target, but moved a lot of my iOS code into there. As much as I hate duplicating code, I felt this was easier than trying to have one set of code capable of running both OSes. The tvOS doesn't support switches or pickers, and my iOS app uses a lot of those. It was easier to just chop them all out of the tvOS viewcontroller.


So far so good. I'm thrilled to see that my app can run in the background of tvOS and still do background web fetches and, I hope, adjust HomeKit devices. I can also use the userDefualts system, which is crucial for my app.


My biggest remaining challenge is to figure out how to pass the user defaults from my iOS app to its sibling on tvOS. I wonder if I could somehow use the same preferences file on iCloud for both apps?

Well now I feel silly. I don't know what search terms I was using but they faliled to find what I needed, which is the

NSUbiquitousKeyValueStore.
It's designed for exactly what I described.


I'm having issues getting it running in Simulator. The AppleTV in Simulator can't seem to control my HomeKit devices and I question whether it's actually connecting to the iCloud keystore. Should the keyStore work in Simulator? Changes I make on my iPhone app don't seem to trigger a notification arriving to the AppleTV in Simulator.

Wow, good find! Didn't now about NSUbiquitousKeyValueStore either. Thanks.

Hmmm... It seems like the changes I make on my iPhone are not seen by the AppleTV in Simulator. I can trigger a synch in the Simulator and it reads all the keys just find, but what it finds does not reflect any changes I made from the iPhone. They're either using two different files or the Simulator isn't really connected to iCloud.


Does anyone know if synching with a real iPhone should work in Simulator?

Did you confirm your process via Apple's simulator testing/debug docs?


Testing iCloud

If you are building an app that uses iCloud, you can test iCloud syncing from within Simulator before testing on physical devices. This can also assist you in testing iCloud syncing across many devices if you have a limited number of devices to test on.

To simulate iCloud syncing, first sign in to Simulator using an Apple ID. It is strongly encouraged that you create and use a separate Apple ID specifically for testing iCloud in Simulator.


To sign in to Simulator with your Apple ID

  1. Launch Simulator with a simulated device running iOS 7.1 or later.
  2. From the Home screen, open Settings and select iCloud.
  3. Enter your Apple ID and password, and click Sign In.


After signing in with your Apple ID, you can then test your iCloud syncing. To test to see whether your app is syncing properly with iCloud, choose Debug > Trigger iCloud sync.


Two-Factor Authentication: Two-factor authentication requires a simulator running iOS 9.0 or later. To test iCloud on earlier versions of iOS, create a separate account that does not use two-factor authentication.