Reader small image

You're reading from  Building Apple Watch Projects

Product typeBook
Published inFeb 2016
Reading LevelIntermediate
PublisherPackt
ISBN-139781785887369
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Stuart Grimshaw
Stuart Grimshaw
author image
Stuart Grimshaw

Stuart Grimshaw has programmed for Apple computers since the days before OS X and has been involved with developing for the Apple Watch since its release. Born in the UK and having lived in Germany and the Netherlands, he is currently a Senior iOS developer in London, England, United Kingdom. He has around 10 years of end-to-end development of projects experience in, iOS, iPadOS, watchOS (Apple Watch), tvOS (AppleTV), and macOS. He is passionate about the potential of the Apple Watch and Apple TV, as well as Apple's Swift programming language, and is a keen proponent of beach coding.
Read more about Stuart Grimshaw

Right arrow

Chapter 7. Plot Buddy – All about Location

Naturally, one of the most important features of mobile devices is their ability to find their own location, whether using GPS sensors or cell data tower locations, or whatever. The Apple Watch is quite capable of capturing location data, either using the iPhone's GPS or when the iPhone is not present, translating its accelerometer data into location data. A pretty neat trick, from a development perspective, and one which enables the user to leave the phone where it is and take off with just the watch.

In developing this app, we will look at several new aspects of programming with the WatchKit framework, as well as a couple of techniques that apply equally to watchOS and iOS development. They include the following topics:

  • Property Lists

  • Core Location framework

  • Protocols

  • Adding an init method

  • Forcing named arguments

Planning the app


Although we will be using some pretty advance programming for this app, the actual use scenario is quite straightforward and our user story will be simply structured.

Mission Statement

Plot Buddy will enable the user to store any number of locations directly from the watch; while moving around, say, a plot of land, or a regular jogging route, or any number of situations in which a list of related location data would be useful. When the user is finished, it will be possible to send the data to the paired iPhone (once it is in range), from where it could be used in any number of ways.

User Story

After launching the app, the user will be offered a single active button with the title Start Plotting, which will allow him to start plotting locations.

Once plotting has started, a second button, titled Add Current Coordinates, will become active which will trigger the addition of the current location's geo-coordinates to a list that is maintained by the app. The location coordinates...

Setting up the project


So the actual flow of our user experience is very simple and is linear in nature—the user collects data, stores, and sends it to the iPhone, there are no branches in the user's behavior.

Requirements

We will need to make use of the following frameworks provided by WatchKit:

  • Core Location

  • Watch Connectivity

We have seen in previous chapters how to leverage Watch Connectivity and we will see shortly the few simple steps we need to take, in order to access core location.

As far as custom structures are concerned, we need to create the following classes:

  • Shared constants, to facilitate data exchange between the watch and the phone

  • A Watch Connectivity manager, as we have created in previous projects

  • A location manager to fetch and store location data and make it available to the interface controllers

  • The main user interface and its associated WKInterfaceController class

  • An interface and its WKInterfaceController, to present the plotted data in table form

  • The table row controller,...

Data structure


Firstly, we define a typealias for the data structure added to both the watch and the phone targets, that will hold the location data, by following these steps:

Shared constants

In the downloaded project, create a new Swift file, name it SharedConstants.swift, being sure to select both targets, Plot Buddy and Plot Buddy WatchKit Extension, as illustrated here:

Select this file in the project navigator and replace the import statement with the following code:

Import WatchKit

typealias LocationSet = [CLLocation] //1

let ApplicationContextDataKey = "Data" //2
  1. Our LocationSet data structure is nothing more than an array of CLLocation objects, which is the type returned by our calls to the Core Location framework.

  2. For the sake of safety, we define a String constant for use as the Key to the data object passed from watch to phone in the ApplicationContext.

Getting location data


Now we get to play with some new stuff.

Apple's Core Location framework provides a wealth of functionality around tracking a user's location. Although we will only scratch the surface in this app, you will see that a CLLocation object contains a set of data about the user's geo-coordinates and time-zone, speed of motion, and a time-stamp.

If we wish to access location data, we need to ask permission of the user before we can get a response to our requests to the operating system. And to do this we must first inform the system of our app's need to do so. We do this by adding an entry into the iPhone's Info.plist file.

Modifying the iPhone's Info.plist

The easiest way to do this is to Control-click the file in the project navigator and select Open As | Source Code from the contextual menu.

Note

Be careful, don't confuse this with the watch app's identically named Info.plist file!

Add the following entry to the XML text contained in the file, immediately after <dict>, on...

The Interface Controllers


With the PBLocationManager in place, we have done the heavy lifting of the app. The interface controllers are very slim in design and simple in implementation.

Create the InterfaceController class

Select the InterfaceController.swift file that was created as part of the Xcode template and replace all of the code in it (including the import statement) with the following:

Import WatchKit

class InterfaceController: WKInterfaceController, PBLocationManagerDelegate {

    var locationManager: PBLocationManager! //1

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        locationManager = PBLocationManager(delegate: self) //2
        locationManager.requestLocation() //3
    }

    func handleNewLocation(newLocation: CLLocation) { //3
        print(newLocation)
    }

    func handleLocationFailure(error: NSError) { //4
        print(error)
    }

}

What we are doing here is writing the bare minimum code necessary to test...

WatchConnectivity


We have done this so often now, we can almost do it blind.

Create a new Swift file, making sure that the WatchKit target is selected, and name it WatchConnectivity.swift. Replace the import statement with the following code, most of which you have seen before:

Import WatchConnectivity

class WatchConnectivityManager: NSObject, WCSessionDelegate {

    static let sharedManager = WatchConnectivityManager()

    private override init() {
        super.init()
        if WCSession.isSupported() {
            let session = WCSession.defaultSession()
            session.delegate = self
            session.activateSession()
        }
    }

    func sendDataToWatch(data: AnyObject) {
        guard let contextData = data as? LocationSet else {return}

        let dataArray = contextDataFrom(locationSet: contextData)
        let context = [kApplicationContextDataKey: dataArray]
do {
            try WCSession.defaultSession().updateApplicationContext(context)
            print("updateApplicationContext...

Final test


We now need to uncomment the code of the InterfaceController class's sendPlotsButtonTapped method, as shown here:

    @IBAction func sendPlotsButtonTapped() {
        WatchConnectivityManager.sharedManager.sendDataToWatch(
            locationManager.currentLocations)
    }

This enables us to send the data to the iPhone.

The app should now be fulfilling all of the specifications we set out at the beginning of this chapter. And you are hopefully now in the position to include Core Location code in any app that can make use of the data it returns, which is an increasingly large proportion of mobile apps in general.

Challenges for expansion


If you wish to hone your software skills by extending the core functionality of the Plot Buddy app, here are a couple of ideas to get you started:

  • The app uses only two of the CLLocation's properties, but it may be useful to the user to store more of the data returned, such as the time stamp, or the height above sea level. Use the print() command to inspect the data in the console and see if you can add more of it to the app.

  • At the moment, the app stores only one set of locations at a time and the user must send this data to the phone before recording a new set of locations, or lose it, as it is replaced by a fresh list of locations. With a few tweaks, it is possible to store an array of such location sets and send them all together to the paired iPhone.

  • The iPhone does no more than log to the console the arrival of ApplicationContext data. Depending on your level of confidence with iOS development, you may wish to display that data on the iPhone screen or package...

Summary


In this chapter you have learned to incorporate Core Location functionality into your app, which involved adding entries into the app's Info.plist file; you have written a custom protocol to facilitate communication between different custom classes and implemented the methods defined in that protocol. Moreover, you have implemented a class's init method for the first time—an essential technique in any Swift project—and we have seen how to make method calls more readable by forcing the explicit naming of arguments.

In the next chapter, we will see that there is more to finishing an app than getting the code to run!

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Building Apple Watch Projects
Published in: Feb 2016Publisher: PacktISBN-13: 9781785887369
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Stuart Grimshaw

Stuart Grimshaw has programmed for Apple computers since the days before OS X and has been involved with developing for the Apple Watch since its release. Born in the UK and having lived in Germany and the Netherlands, he is currently a Senior iOS developer in London, England, United Kingdom. He has around 10 years of end-to-end development of projects experience in, iOS, iPadOS, watchOS (Apple Watch), tvOS (AppleTV), and macOS. He is passionate about the potential of the Apple Watch and Apple TV, as well as Apple's Swift programming language, and is a keen proponent of beach coding.
Read more about Stuart Grimshaw