Apple Watch

Apple Watch sales took off on first day of pre-order. Apple sold 1 million of Apple Watches in first pre-order day. It’s more than Android Wear devices were sold throughout all of 2014! Currently it’s hard to get one. You can purchase it on Apple store but you will have to wait few weeks for the delivery.

Simple App Concept

On Apple Watch you can present, different simple chunks of data. As for the ideas the sky is the limit. I came up with an idea to check some web service for information and display it on the Apple Watch. This tutorial will query the U. S. Geological Survey – Earthquake monitoring programme (http://earthquake.usgs.gov/) web API for recent earth quake activities. The application will be programmed in Swift (1.2) language.

Apple WatchKit

WatchKit is Apple’s framework that allows you to create apps for Apple Watches. It was released with Xcode 6.2.

First things first

Please download EarthWatcher base project. We will start at this point. This project contains simple app, that queries web API to get information about recent seismic activity. I have provided querying functionality as a framework, to simply use it when making the Apple Watch app.

When you open the project you should be able to see in project navigator such files structure:

AW_base_project_file_structure

The EarthWatcherKit is our simple framework that will query the U. S. Geological Survey Earthquakes web API, to get the information about recent activity. In the file EarthQuakeFetcher.swift you can find a simple method public class func fetchEarthQuakes(completion: EarthQuakeRequestCompletionBlock), which accepts as an argument a closure (callback) that returns with the result and a potential error information.

Let’s get started

After getting familiar with the basics of the starter project, we can move forward to create a simple Apple Watch application. To be honest, it’s not quite an application in terms of being independent app, but we will get to this.

Create new WatchKit application by navigating File > New > Target…

AW_base_project_add_newTarget

Select Apple Watch > WatchKit App

AW_base_project_add_AppleWatchApp

When choosing options for your new target, please make sure to unselect all checkboxes, like in the picture below

AW_base_project_add_AppleWatchApp_exludecheckbox

As you can see you cannot change the Product Name nor the Bundle Identifier. It’s because of the fact, that the target we are about to create will be a part of our main iOS application.

After you click Finish button, the Xcode will ask you if you want to create new building & debugging scheme for your project. Click Activate.

AW_base_project_add_AppleWatchApp_activate

When the creator ends you should be able to see in the Project Navigator sidebar files structure similar to the picture below

AW_base_project_file_structure_withAppleWatch

As you can see new groups were added: EarthWatcher WatchKit Extension & EarthWatcher WatchKit App

WatchKit Extension & App

Now it’s a good time for some explanations how those two groups of files are affecting our work. The WatchKit Extension is a part of our application that we should treat as our ViewController and the WatchKit App group like a View to display data. The extension part is executed on the main device side but the communication to  the views on the Apple Watch are managed by the iOS behind the scenes. You don’t have to worry about it. Ok, so now as we know how the communication with the views is performed, we can move to designing our interface.

WatchKit App – the view

Let me show you, how to create a simple view for our Apple Watch app. Our view will consist of something similar to UITableView and a UIButton. In WatchKit similar controls are called WKInterfaceTable and WKInterfaceButton. Those classes are called different, because they do a different job (organised in other way) and are performed in a very different way comparing to the standard UIView’s. 

Open the Interface.storyboard file in the EarthWatcher WatchKit App group.

AW_AppleWatch_firstScreen

This is an empty view. Let’s add a button by dragging Button control from the right sidebar to the Apple Watch main view

AW_AppleWatch_label

Ok, great. Now let’s customise it a little bit. Try to set a background colour and change the title to “REFRESH”. Please notice that in the Position options, you are able to select only Left, Centre, Right in the Horizontal and Top, Centre, Bottom in the Vertical positions. That’s because of the fact, that on Apple Watch interface every element has to be pinned to something. It may be aligned to the controls/elements that are already on the screen. or the top or bottom guideline. 

AW_AppleWatch_setButton

In a result you should get something like this:

AW_AppleWatch_buttonIB

Next thing what we want to add here is the WKInterfaceTable, to be able to present data about the earthquakes fetched from the web service. Drag a Table control to your Apple Watch interface screen just like the button.

AW_AppleWatch_InterfaceTableAdded

In the interface builder (storyboard) from the left hand sidebar select Table and expand the hierarchy tree until you see Group – select it. On the right sidebar, change it’s attributes a bit, to set a cell green colour and 4 pixels of radius for corners.

AW_AppleWatch_InterfaceTableAdjust

Let’s add a label to this cell, to show an earth quake note. Just like the last time, select the Label and drag it into the Group. It should look like in the picture below.

AW_AppleWatch_InterfaceTableIB_check

If it looks the same we can proceed to the next step – connect actions and outlets.

Connect Actions and Outlets

Let’s begin with connecting the action for the button. First thing import the EarthWatcherKit to your InterfaceController.swift file

import EarthWatcherKit

In the interface builder for the Interface.storyboard file, please select the button and show the assistant editor. Drag with ctrl from the button to the right hand side code editor to create new action.

AW_AppleWatch_IB_sourcecode

For this action type below code:

@IBActionfunc refreshButtonTapped() {
        EarthQuakeFether.fetchEarthQuakes { (result, error) -> () in
            self.parseTitles(result!)
    }
}

Do the same thing for the InterfaceTable outlet, so you should get something like this:

@IBOutlet var interfaceTable: WKInterfaceTable!

Let’s handle now displaying a text in our InterfaceTable. To do this, we need to assign a class for the InterfaceTableRow. In UITableView for the UITableViewCell we would need subclass the UITableViewCell to create a custom cell. In WatchKit, you can specify a class that is inheriting from NSObject and the work will be done.

Let’s create new swift file in the EarthWatcher WatchKit Extension and name it EarthQuakeRow.

Add to it such code:

import Foundation
import WatchKit
class EarthQuakeRow : NSObject {
}

Now let’s get back to the Interface Builder. From the view hierarchy on the left hand side select the Table Row Controller and on the Identity Inspector on the right hand side in the class field, type EarthQuakeRow and hit enter. It will automatically select a module for it. In the Attributes Inspector type in Identifier field EarthQuakeRow. Now select the InterfaceLabel element and link it to the outlet property in the class EarthQuakeRow. You should get outlet like in the picture below:

AW_AppleWatch_IB_sourcecode2

Apple Watch extension logic

Ok, let’s create some logic to fulfil the data after the Refresh button is tapped on Apple Watch. In the InterfaceController class add:

var objects : [String]? = [String]()

to store messages about earth quakes.

Now, let’s get into parsing the dictionaries received from the EarthWatchFetcher method (used in the refreshButtonTapped method). Create method:

func parseTitles(resultDictionary : NSDictionary) {
        let featuresArray = resultDictionary.objectForKey(„features”) as! NSArray
        for dictionary in featuresArray {
            var featuresDictionary = dictionary.objectForKey(„properties”) as! NSDictionary
            if let title = featuresDictionary.objectForKey(„title”) as? String {
                self.objects?.append(title)
            }
}

    //update the interfaceTable
    dispatch_async(dispatch_get_main_queue()) {
          self.updateTable()
  }

}

Firstly we get out the features array from the result dictionary. This array contains a set of dictionaries, one for each earthquake report. Then in simple for in loop we extract only the titles of each earthquake report that consists of magnitude of the earth quake and short description where was it’s epicentre – example: M 2.5 – 70km NNW of Talkeetna, Alaska.

After all the messages were captured by the for loop, we have to update our Interface Table to see the actual records on a Watch.

Let’s implement the updateTable method now. 

func updateTable() {
    interfaceTable.setNumberOfRows(objects?.count as Int!, withRowType: "EarthQuakeRow")

    for (index, title) in enumerate(objects!) {
        let row = interfaceTable.rowControllerAtIndex(index) as? EarthQuakeRow
        row?.earthQuakeLabel.setText(objects?[index])
    }
}

First thing we need to do is to set the number of rows (cells) that we want to display. All we do here is passing the number of rows based on number of fetched objects and set a type of the row (“EarthQuakeRow”).

Next thing is to update the rows with proper information. 

let row = interfaceTable.rowControllerAtIndex(index) as? EarthQuakeRow

is similar to a know method fromUITableView – dequeueReusableCellWithIdentifier. As we get a given row, now we have to set it’s label with the title string from the object array.

Run the app

Ok now we can build the project and run it on the device or simulator. In my case I will run the app on the simulator. In Xcode select EarthWatcher WatchKit App > iPhone 6 scheme.

AW_AppleWatch_schemebar

If Apple Watch screen won’t show automatically in the simulator, you can open it via clicking Hardware > External Displays > Apple Watch – 38/42mm.

These are the screens how the app looks like at the end:

AW_AppleWatchFinalScreenshot

AW_AppleWatchFinalScreenshot2

Here you can download a complete project, if you want to analyse already built project.

I hope you enjoyed this tutorial and you will have a bunch of ideas to create your own Apple Watch apps. Good luck in programming for the Apple Watch!

Thanks for reading!
Piotr Chojnowski