watchOS 4 Tutorial Part 1: Getting Started

In this watchOS 4 tutorial for complete beginners, you’ll learn how to create the user interface for a fictional airline called Air Aber. By Audrey Tam.

Leave a rating/review
Save for later
Update Note: This tutorial has been updated to Swift 4/watchOS 4 by Audrey Tam. The original tutorial was written by Mic Pringle.

In this watchOS 4 Tutorial, you’ll build a simple but fully functional watchOS 4 app. Specifically, you will work on a Watch app for a fictional airline called Air Aber.

In the process, you’ll learn:

  • How to add a watchOS 4 target to an iOS app.
  • How to share data across the two targets.
  • How to add a watchOS 4 interface controller to the Storyboard, and lay out the interface objects.
  • How to create the WKInterfaceController subclass, and wire everything up.

Let’s get started! ┗(°0°)┛

Getting Started

Start by downloading the starter project for this tutorial.

Open it in Xcode, and build and run. You should see a blank white screen:

There’s not much to this project as it stands: it includes a few helper files you’ll need, and not much else. You’ll address that now!

Adding the WatchKit App

Select File\New\Target…. In the dialog that appears, choose watchOS\Application\WatchKit App, then click Next:

In the following screen, set Product Name to Watch, make sure Language is set to Swift, and uncheck any checkboxes that are checked. Click Finish:

You’ll be asked if you want to activate the watch scheme, which you do, so make sure to choose Activate:

Activate watchOS 4 Scheme

Congratulations, you’ve just created your first Watch app! It really is that easy.

You’ll notice this action actually created two targets, not one, and two corresponding groups in the Project navigator. This is because the code of a Watch app actually runs as an extension bundled within the Watch app, in much the same way Today extensions on iOS work.

Expand the Watch and Watch Extension groups in the Project navigator, and you’ll see that the storyboard is in the Watch group, and the classes created by the target template are in the Watch Extension group:

Here’s the pattern you’ll follow moving forward: any code you add must reside within the Watch Extension group, and be added to the Watch Extension target, whereas any assets or storyboards must be added to the Watch group.

A Little Housekeeping

Before continuing, you need to remove a couple of things added by the target template that you’re going to replace.

Right-click on InterfaceController.swift in the Project navigator, and choose Delete. When prompted, choose Move to Trash to make sure the file is actually removed from the project:

Next, open Interface.storyboard, select the only interface controller in there, and hit the delete key. This should leave you with an empty storyboard, or as I prefer to think of it, a blank canvas.

Sharing Data and Code

The starter project includes a JSON file containing all the Air Aber flight details, and a model class that represents that data. This is exactly the kind of thing that you should share amongst targets, since it’s highly likely the iOS app and the Watch app will use the same model class and data – you do remember DRY, right?

Expand the Shared group in the Project navigator, and select Flights.json. Next, find the Target Membership section in the File inspector, and check Watch Extension:

The file is now included in both the AirAber and Watch Extension targets.

Repeat the process for the other file in the Shared group, Flight.swift.

And with that done, you can finally begin building the flight details interface!

Building the Interface

Open Watch\Interface.storyboard, and drag an interface controller from the Object Library onto the storyboard canvas. With the interface controller selected, open the Attributes inspector, and set Identifier to Flight, and check Is Initial Controller. Uncheck Activity Indicator On Load:

Here, you’ve set the identifier so you can refer to the interface controller in code. Checking Is Initial Controller simply informs WatchKit this is the interface controller you want to display when the Watch app first launches. This interface doesn’t download any data, so it doesn’t need to display the activity indicator.

In order to simplify this tutorial, you will build your layout only for the 42mm watch. For your own apps, you’ll want to verify that they work properly on all watch sizes. At the bottom left of the storyboard pane, ensure that it says View as: Apple Watch 42mm.

view as 42mm watch

Watch app layout is completely different from iOS layout. The first thing you’ll notice: you can’t move or resize UI objects by dragging them around in the interface controller. When you drag an object onto the controller, it slots in under the previous objects, and the screen fills up pretty fast. To organize objects side-by-side, you use groups, which are a lot like stack views in iOS and macOS.

So first, drag a group from the Object Library onto the interface controller:


Although it doesn’t look like much now, this group will eventually contain the Air Aber logo, flight number and route.

With the new group selected, head over to the Attributes inspector, and change Insets to Custom. Four text fields appear, where you can manually set the top, bottom, left and right insets of the group.

Change Top to 6:


This simply gives the layout group a little extra padding at the top.

Next, drag an image into the group. If your group shrank in response to changing the top inset (thanks Xcode!), drag the image into the document outline instead, making sure it’s a child of the group, rather than a sibling:


Now you need an image to display. Download this logo image and drag it into your Watch\Assets.xcassets. This creates a new image set called Logo, with the actual image in the 2x slot:

You want to tint this image to Air Aber’s corporate color, so select the image, then in the Attributes inspector, set Render As to Template Image.


Re-open Watch\Interface.storyboard, and select the image. Using the Attributes inspector, make the following changes:

  • Set Image to Logo – if it doesn’t appear in the dropdown, simply type it in.
  • Set Tint to #FA114F (you can type this in the Color RGB Sliders panel).
  • Set Width to Fixed, with a value of 40.
  • Set Height to Fixed, with a value of 40.

The Attributes inspector should now look like the following:


Don’t worry if you can’t see the logo: it turns out Xcode doesn’t tint template images at design time! Trust me, it’ll be a vibrant pink when you build and run!

Next, drag another group into the existing group, making sure it appears to the right of the image, and use the Attributes inspector to change its Layout to Vertical. Also, change Spacing to Custom\0 and Width to Size to Fit Content.

Next, drag two labels into the new group. Because you set layout to vertical, the labels appear one above the other:


Select the upper label, and use the Attributes inspector to set Text to Flight 123 and Text Color to #FA114F (instead of typing this into the RGB panel again, you can select the pink color from Recently Used Colors in the Color menu).

Next, select the lower label, and set its Text to MEL to SFO. Your interface controller should now look like the following:


This text is simply placeholder text that’ll be replaced when you hook the interface up to its controller class.

Next, drag another group onto the interface controller, but this time make sure it’s a sibling of the very first group you added. If you can’t get the group positioned at the correct place in the hierarchy, use the document outline instead.


With this new group selected, set its Layout to Vertical and Spacing to Custom\0.

Next, drag three labels into this new group:


Check in the document outline to make sure all three labels are inside the group, not siblings of the group!

Select the top label, and use the Attributes inspector to change its Text to AA123 Boards.

Next, select the middle label, and change its Text to 15:06. Next, change Text Color to #FA114F and Font to System, with a Style of Regular and a Size of 54. Finally, change Height to Fixed, with a value of 44.

Select the bottom label, and change its Text to On time and Text Color to #04DE71.

Your interface controller should now look like the following:


Now you only have to add one more group, before you create the outlets, and have this interface display some real data.

Drag a new group from the Object Library into the lower group, this time making sure it’s a child rather than a sibling, and that it’s positioned at the very bottom of the containing group. Next, add two labels to it. Your complete interface object hierarchy should now look like this:


Use the Attributes inspector to set Text to Gate 1A for the left label. For the right label, set Text to Seat 64A, and set Horizontal Alignment to Right.

The completed interface should now look like the following:


Congratulations, you’ve finished laying out your very first Watch app interface! Now it’s time to populate it with some real data, and get it up and running in the simulator.