Your First tvOS App with Fire
The first time you start Fire, before opening or starting a new project, it will present you with the Welcome Screen, pictured below. You can also always open up the Welcome screen via the "Window|Welcome" menu command or by pressing ⇧⌘1.
In addition to logging in to your remobjects.com account, the Welcome Screen allows you to perform three tasks, two of which you will use now.
On the bottom left, you can choose your preferred Elements language. Fire supports writing code in Oxygene, C# and Swift. Picking an option here will select what language will show by default when you start new projects, or add new files to a multi-language project (Elements allows you to mix all fivwe languages in a project, if you like).
This tutorial will cover all languages. For code snippets, and for any screenshots that are language-specific, you can choose which language to see in the top right corner. Your choice will persist throughout the article and the website, though you can of course switch back and forth at any time.
After picking your default language (which you can always change later in Preferences), click the "Start a new Project" button to bring up the New Project Wizard sheet:
You will see that your preferred language is already pre-selected at the top right – although you can of course always choose a different language just for this one project.
On the top left you will select the platform for your new application. Since you're going to build an tvOS app for Apple TV, select Cocoa. This filters the third list down to show all Cocoa templates only. Drop down the big popup button in the middle and choose the "Single View App (tvOS)" project template, then click "OK".
Next, you will select where to save the new project you are creating:
This is pretty much a standard Mac OS X Save Dialog; you can ignore the two extra options at the bottom for now and just pick a location for your project, give it a name, and click "Create Project".
You might be interested to know that you can set the default location for new projects in Preferences. Setting that to the base folder where you keep all your work, for example, saves you from having to find the right folder each time you start a new project.
Once the project is created, Fire opens its main window, showing you a view of your project:
Let's have a look around this window, as there are a lot of things to see, and this windows is the main view of Fire where you will do most of your work.
The Fire Main Window
At the top, you will see the toolbar, and at the very top of that you see the name MyFirstApp.sln
. Now, MyFirstApp
is the name you gave your project, but what does .sln
mean? Elements works with projects inside of a Solution. You can think of a Solution as a container for one or more related projects. Fire will always open a solution, not a project – even if that solution might only contain a single project, like in this case.
In the toolbar itself are buttons to build and run the project, as well as a few popup buttons that let you select various things. We'll get to those later.
The left side of the Fire window is made up by what we call the Navigation Pane. This pane has various tabs at the top that allow you to quickly find your way around your project in various views. For now, we'll focus on the first view, which is active in the screenshot above, and is called the Project Tree.
You can hide and show the Navigation Pane by pressing ⌘0 at any time to let the main view (wich we'll look at next) fill the whole window. You can also bring up the Project Tree at any time by pressing ⌘1 (whether the Navigation Pane is hidden or showing a different tab).
The Project Tree
The Project Tree shows you a full view of everything in your project (or projects). Each project starts with the project node itself, which is larger, and selected in the screenshot above, as indicated by its blue background. Because it is selected, the main view on the right shows the project summary. As you select different nodes in the Project Tree the main view adjusts accordingly.
Each project has three top level nodes.
-
Settings gives you access to all the project settings and options for the project. Here you can control how the project is built and run, what exact compiler options are used, etc. The project settings are covered in great detail here.
-
References lists all the external frameworks and libraries your project uses. As you can see in the screenshot, the project already references all the most crucial libraries by default (we'll have a look at these later), and you can always add more by right-clicking the References node and choosing "Add Reference" from the context menu. You can also drag references in directly from the Finder, as well as, of course, remove unnecessary references. Please refer to the References topic for more in-depth coverage.
-
Files, finally, has the meat of your application. This is where all the files that make up your app are listed, including source files, images and other resources.
The Main View
Lastly, the main view fills the rest of the window (and if you hide the Navigation Pane, all of the window), and this is where you get your work done. With the project node selected, this view is a bit uninspiring, but when you select a source file, it will show you the code editor in that file, and it will show specific views for each file type.
When you hide the Navigation Pane, you can still navigate between the different files in your project via the Jump Bar at the top of the main view. Click on the "MyFirstApp" project name, and you can jump through the full folder and file hierarchy of your project, and more.
Your First tvOS Project
Let's have a look at what's in the project that was generated for you from the template. This is already a fully working app that you could build and launch now – it wouldn't do much, but all the basic code and infrastructure is there.
First of all, there are two source files, the AppDelegate
and a ViewController
, with file extensions matching your language. And there's a handful of non-code files in the Resources folder.
If you are already used to iOS development, then a lot of this will be very familiar to you already.
The Application Delegate
The AppDelegate
is a standard class that pretty much every iOS, tvOS and Mac app implements. You can think of it as a central communication point between the Cocoa (Touch) frameworks and your app, the go-to hub that Cocoa will call when something happens, such as your app launching, shutting down, or getting other external notifications.
There's a range of methods that the AppDelegate
can implement, and by default the template provides four of them to handle application launch, shutdown, suspension (when the app moves into the background) and resuming, respectively. For this template, they are all empty, because what gets your app off the ground and running happens elsewhere, as we'll see in a second.
If you wanted to add your own code to run when the app starts, you would add that to the implementation of the application:didFinishLaunchingWithOptions:
body:
method AppDelegate.application(application: UIApplication)
didFinishLaunchingWithOptions(launchOptions: NSDictionary): Boolean;
begin
result := true;
end;
public BOOL application(UIApplication application)
didFinishLaunchingWithOptions(NSDictionary launchOptions)
{
return true;
}
func application(_ application: UIApplication!,
didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
return true
}
As it stands, the method just returns true
to let Cocoa know that everything is A-OK and the app should start normally.
Another thing worth noticing on the AppDelegate class is the UIApplicationMain
Attribute that is attached to it. You might have noticed that your project has no main()
function, no entry point where execution will start when the app launches. The UIApplicationMain
attribute performs two tasks: (1) it generates this entry point for you, which saves a whole bunch of boilerplate code and (2) it lets Cocoa know that the AppDelegate
class (which could be called anything) will be the application's delegate class.
type
[UIApplicationMain, IBObject]
AppDelegate = class(IUIApplicationDelegate)
//...
end;
[UIApplicationMain, IBObject]
class AppDelegate : IUIApplicationDelegate
{
//...
}
@UIApplicationMain @IBObject public class AppDelegate : IUIApplicationDelegate {
//...
}
The View Controller
The second class, and where things become more interesting, is the ViewController
. Arbitrarily named so because it is the only view controller for your application (you started with the "Single View" app template, after all), this is where the actual logic for your application's view will be encoded.
It too is fairly empty at this stage, with two placeholder methods that get called when the view loads (viewDidLoad
) and when there is a shortage of memory (didReceiveMemoryWarning
), respectively. You'll fill this class up with real code in a short while. But first let's move on to the other files in the project.
The Resources
There are four resource files in the project, nested in the Resources
subfolder. This is pure convention, and you can distribute files within folders of your project as you please.
-
The
Assets.xcassets
file is an Xcode Asset Catalog – essentially a collection of images (and possibly other assets) in various sizes. Like most resource files, you can edit this file in Xcode (we'll see how in a few moments). By default, it only contains the application icon, in the various sizes to support iPhones and iPads at different resolutions. -
Main.storyboard
contains the real UI of your application that will show once it is launched. This file will also be designed in Xcode, and it will have connections to your code, so that it can interact with the application logic you will write. -
Finally,
Info.plist
is a small XML file that provides the operating system with important parameters about your application. The file provides some values that you can edit (such as the name of the Launch Screen and Main Storyboard above, or what types of devices your app will run on), and as part of building your application, Elements will expand it and add additional information to the file before packaging it into your final app. You can read more about this file here.
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>3</integer>
</array>
...
The Main Storyboard
As stated earlier, no startup code is necessary in the AppDelegate
method, because Cocoa already knows how to get your app up and running. And that is via the UIMainStoryboardFile
entry in the Info.plist
file. As you can see above, it points to Main
, which is the Main.storyboard
file in your project. Let's have a look.
Editing .storyboard
files is done in Xcode, using Apple's own designer for Mac and iOS.
For this step (and for many other aspects of developing for tvOS) Xcode needs to be installed on your system. Xcode is available for free on the Mac App Store, and downloading and running it once is enough for Fire to find it, but we cover this in more detail here in the Setup section.
When you select the .storyboard
file, the main view will populate with information about the storyboard, including its name, build action ("Storyboard"), and a helpful "Edit in Xcode" button:
Clicking this button will generate/update a small stub project that will open in Xcode and give you access to all the resources in your project. Instead of using the button, you can also either right-click a resource file and select "Edit in Xcode" from the menu, or right-click the project node and choose "Edit User Interface Files Xcode".
Xcode will come up and look something like this:
On the left, you see all your resource files represented – there's the Main storyboard and the Asset Catalog. Selecting an item will open it on the right, as is happening with the Main.storyboard
in the screenshot above. To make more room, let's hide the file list (⌘0 just like in Fire) and the Document Outline (via the small square button in the bottom left). Also, press ⌥⌘1 to show the Utility pane on the right instead:
The view for the screenshots is a bit constraint, but you should see the 1080p main view for your application, alongside an arrow pointing to it from the left, which indicates that this is the initial screen for your app that Cocoa will show when it loads your storyboard.
If you select the view controller by clicking its title bar and then select the third tab in the Utility View (⌥⌘3), you will see that its "Class" property is set to "ViewController". This is the ViewController
class in your code.
So let's go back to Fire and start adding some (very simple) functionality to this view controller. You can close Xcode, or leave it open and just switch back to Fire via ⌘Tab – it doesn't matter.
Back in Fire, select the ViewController
source file, and let's start adding some code. We're going to create a really simple app for now, just a button and a label. Clicking the button will update the label with a greeting message.
Let's start by adding a property, so that we can refer to the label from code:
public
[IBOutlet] property label: UILabel;
[IBOutlet] public UILabel label { get; set; }
@IBOutlet var label: UILabel
Note the IBOutlet
attribute attached to the property. This (alongside the IBObject
attribute that's already on the ViewController
class itself) lets the compiler and Xcode know that the property should be made available for connections in the UI designer (IB
is short for Interface Builder, the former name of Xcode's UI designer).
Next, let's add a method that can be called back when the user presses the button:
[IBAction]
method ViewController.sayHello(sender: id);
begin
label.text := 'Hello from Oxygene';
end;
[IBAction]
public void sayHello(id sender)
{
label.text = "Hello from C#";
}
@IBAction func sayHello(_ sender: Any?) {
label.text = "Hello from Swift"
}
Similar to the attribute above, here the IBAction
attribute is used to mark that the method should be available in the designer.
Note: If you are using Oxygene as a language, methods need to be declared in the interface section and implemented in the implementation section. You can just add the header to the interface and press ^C and Fire will automatically add the second counterpart for you, without you having to type the method header declaration twice.
Now all that's left is to design the user interface and hook it up to the code you just wrote. To do that, right-click the Main.storyboard
and choose "Edit in Xcode" again. This will bring Xcode back to the front and make sure the UI designer knows about the latest change you made to the code. (Tip: you can also just press ⌘S at any time to sync.)
Now drag a label and a button from the bottom-right class palette onto the View, and align them so that they look something like this:
(Tip: you can zoom the view by right-clicking or control-clicking into the empty white space of the designer and choosing a scale factor, if you cannot fit the whole view on your screen.)
Then select both controls via ⌘-clicking on each one in turn, press the first button in the bottom right, check "Horizontally Center in Container" and click "Add 2 Constraints". This configures Auto Layout, so that the controls will automatically be centered in the view, regardless of screen size. In a real app, you would want to set more constraints to fully control the layout, such as the spacing between the controls, but for this simple app, just centering them will do.
Finally, it's time to connect the controls to your code. There are two connections to be made in total – one from the property to the UITextField
and UILabel
, and one from the UIButton
back to the action.
For the first, click on the yellow view controller icon (which represents your ViewController
class) while holding down the Control (^) key, and drag onto the text field, as shown below:
When you let go, a small popup appears, listing all properties that match up for connecting. In this case, it will be the view
property (which links the base view for the controller, and you don't want to mess with that), and the label
one you defined earlier.
Click on "label" to make the connection.
Connecting the action works the same way, just in reverse. This time, Control-drag from the button back to the yellow view controller icon. Select "sayHello:" from the popup, and you're done.
And with that, the app is done. You can now close Xcode, go back to Fire, and run it.
Running Your App
You're now ready to run your app in the Simulator.
Earlier on we looked at the top toolbar in Fire. In the middle of the toolbar, you will find a popup button that is the device selector, which should by default be set to "tvOS Device". That is a placeholder that, when selected, tells Fire to build your application for a real, physical Apple TV device, and is available whether you have an actual Apple TV connected or not. However, because "tvOS Device" does not represent a real device, you cannot run your app on it.
If you open up the popup, you will see a menu with more options. For one, you will see the tvOS Simulator; for another, you will also see any real Apple TV devices you have connected to your Mac (such as "Apple TV 4" in the screenshot below), along with their device type and OS version.
For now just select the simulator. When done, you can hit the "Play" button in the toolbar, or press ⌘R.
Fire will now build your project and launch it in the simulator. You will notice that while the project is compiling, the Jump Bar turns blue and shows the progress of what is happening in the top right of the window. The application icon will also turn blue for the duration; this allows you to switch away from Fire while building a more complex/slow project, and still keep an eye on the progress via the Dock.
If there were any errors building the project, the Jump Bar and application icon would turn red, and you could press ⌥⌘M or use the Jump Bar to go to the first error message. But hopefully your first iOS project will build ok, and a few seconds later, the iOS Simulator should come to the front, running your app.
Press "Enter" to press the button (the Apple TV Simulator will not respond to mouse clicks, only cursor key and Enter. Or you can pair an Apple Remote control with your Mac and use that with the Simulator, as well), and the label will update, as per your code.
Running on your device should be just as easy, assuming you have your Apple developer account set up and registered with Xcode as discussed here. Simply select your real device from the device picker popup, hit ⌘R again, and you will see your app get deployed to and launch on your Apple TV.
You will see two warnings being emitted when building for a device. That is because your project has no Provisioning Profile and Developer Certificate selected yet. Fire will pick the default profile and certificate (assuming one is present), so that you can run your application without hassle, but the two warnings will remind you that, eventually, you will want to explicitly select the exact profile and certificate you want to use for this app.
To do so, simply select the "Settings" (⌘I) node on the Project Tree, which brings up the Project Settings Editor:
You can select both your Certificate and your Provisioning Profile from the list (once again, see here if your profiles or certificates don't show up as you expect them to).