Functioning Successfully - Introducing Actions - Swift For Dummies (2015)

Swift For Dummies (2015)

Part II. Introducing Actions

Chapter 9. Functioning Successfully

In This Chapter

arrow Looking at functions

arrow Adding functions for location support

arrow Creating an action function

In Swift, functions and types play a larger role than they do in some other object-oriented languages. The whole idea of objects containing both data and functionality (or, in Swift terms, properties and methods) is central.

It makes for a neat package.

Named types share important characteristics with objects. One of the most important shared characteristics is that all named types can contain functions: Yes, you can place functions in structures and enumerations as well as in classes. (In classes, however, functions are generally referred to as methods.)

icon tip That last point is very important. This chapter is about functions wherever they reside — in classes, enumerations, structures, or even inside other functions or at a global level of your app. When in classes, functions are referred to as methods, but they’re still functions underneath. Keep this in mind as you read this chapter.

In ’ Chapter 4, you set up Locatapp to use as a running example in this book. In this chapter (and in many that follow), you build on Locatapp. If you haven’t created it, you have three choices:

· Download it from the Chapter 4 files at this book’s companion website, as described in the Introduction.

· Work through Chapter 4 to create it.

· Use the summary that follows to create it. This is a shorter version of the steps in Chapter 4. It can serve as a review as well as a guideline for creating new apps once you’ve read the in-depth instructions in Chapter 4.

Setting the Stage for the Social Media Location App

This book focuses on Swift, but other components are important for app development in iOS and OS X, including Xcode (the integrated development environment — IDE) and Objective-C, as well as the Cocoa and Cocoa Touch frameworks.

Although Swift is the future of development for Cocoa and Cocoa Touch, many frameworks are still written in Objective-C. The interface between Objective-C and Swift works both ways, so you can easily interact with Objective-C frameworks. In fact, the interaction is so simple, you can do this without even knowing much about Objective-C.

In this section, you work with the project that is the main example in this book. These steps guide you through the creation of the project itself. Accordingly, not all of these steps are Swift-related, strictly speaking, but they help you create a project so you can write and rewrite your Swift code. Just follow these steps, and you’ll be on your way.

Introducing Locatapp

In Part I, “Getting Started with Swift,” I provided an overview of Xcode and showed you how to put a project together. In Chapter 4, I described the app that serves as an example in this book — a social media location app. It uses Cocoa Touch and its frameworks to let you display a user’s location and store it in a Core Data store. Part of the beauty of this app is that it does a lot without much work on your part. It has an interface to social media, such as Facebook and Twitter, as well as other communication tools like messages and email. It also has a fully-functioning database, although the example app uses only the basics.

How can a database be part of “only the basics”?

Some people wonder how a database can find a place in an app that uses “only the basics.” The fact of the matter is that data management is emphatically one of the basics of modern app development. There are a number of ways of managing app data: you can store it using tools such as key-value coding (KVC), which is built into the Cocoa and Cocoa Touch frameworks. You can store the app’s data for each user on the local device, or in iCloud (or both). In addition to structuring data using KVC, you can use Core Data, the persistent store that's built into Cocoa and Cocoa Touch. It uses the SQLite library for its actual storage (optionally XML as well on Macs), and it's an object-oriented relational database system that provides more complex data storage than does KVC.

Other apps use data stored in places such as Amazon Web Services (AWS) and other cloud services. This is a good solution for data that needs to be shared between iOS or OS X apps and other apps and systems.

The amount and type of data storage that’s needed depends on the app. For some games and lifestyle apps (such as HealthKit apps), it’s sufficient to store game scores for each game and environmental or personal readings of items such as blood pressure and precipitation. Often, KVC is a good tool for this type and amount of data, and it's easy to share it with other Cocoa and Cocoa Touch apps. On the other hand, data such as the details of each move in a multi-person game may need more flexible and larger storage features that a persistent store like Core Data can provide or that a relational database accessible to other apps and systems can provide.

Finally, you can write out some data in your own format in a scratchpad that you create in your app's sandbox. That type of idiosyncratic data storage is probably the most widely used across the range of apps today, but the problems this type of storage creates are legion. They range from security to reliability to maintainability and back to security again.

With an understanding of this app — a mobile location-aware app that is integrated with social media — you’re well on your way to building a wide variety of apps. In this chapter, you explore functions (called “methods” when they’re in classes). In previous chapters, you learn the basics of Swift actions with the data (and collections of data) and flow control that you can use to build an app. Starting with this chapter, you put those basics together into an app.

There are a few points to bring up before we launch into the code. The first is the pretty obvious fact that the name “Social Media Location App” is a bit of a mouthful. From here on, I’ll call it Locatapp.

Creating the Locatapp project

The Locatapp project is created from the built-in Master-Detail Application template in Xcode. The steps to do this are the same as they always are with building an Xcode project from a template: In summary, you create a new project from the Master-Detail Application template, save it to disk, and — this part is very important — run it as a test. If the unchanged template doesn’t work properly, resolve the problems. Remember: Waiting for magic to happen is not a viable strategy.

icon tip If you have problems, use the resources you have as a registered developer, including access to the developer discussions on developer.apple.com. Searching on the web also works, but be sure that the results you find are for Swift and for the current version of Xcode that you’re using. Outdated analyses and recommendations can cost you a lot of wasted time. Also, if you are a member of one of Apple’s paid developer programs, remember that you are permitted two technical support incidents each year for each program. (This makes a total of four if you’re both an iOS and OS X developer.) Using a tech-support incident to get yourself up and running can be a good investment. Another useful resource is Meetup — use it to find a local group.

The following steps create the Locatapp project from the Master-Detail Application in Xcode:

1. Choose File ⇒ New ⇒ Project to open the dialog box shown in Figure 9-1.

2. Select Application from the iOS group at the top left of the dialog.

3. Select Master-Detail Application in the main section of the dialog.

4. Click Next.

5. Provide the product name and the other data, as shown in Figure 9-2.

Depending on your preferences and your past use of Xcode, some of the data such as the organization name and identifier may be filled in for you already. You can change the filled-in data if you want (and the changed organization name and identifier will be used automatically for your next project as well). The bundle identifier is created for you automatically as you enter the product name.

6. Verify that the language is set to Swift.

The Universal devices option (both iPhone and iPad rather than only one or the other) is used in this book, along with Core Data if it's available (Core Data is not available for all of the project templates). If you have experience with Xcode and prefer other options, however, feel free to use them.

7. Click Next.

8. Choose a location for your new project and click Create.

Whether to use the Source Control checkbox to create a Git repository is something you can decide for yourself. The simplest rule of thumb is: If you don’t know what Git is, don’t use it. (Even so, at some point you should learn about source control because it makes your life as a developer easier.)

9. Review your project summary as shown in Figure 9-3.

Remember that the layout of the Xcode workspace window may change depending on your preferences. Using that project navigator at the left, choose the project itself and check out the files (shown in Figure 9-3) and the settings in the editor. At this point, having Team set to None (the default) is OK. An error because of the missing team may be shown, but that error can be ignored for now.

10. Build and run the project.

You see the iOS Simulator with your app running in it. The simulator uses whatever device you have chosen at the top-left of the workspace window. You see the launch image (the leftmost screen in Figure 9-4) and then an empty list of objects (the second screen in Figure 9-4).

11. Click + in the upper-right to add an entry (the third screen in Figure 9-4).

12. Select the entry. You now see it on the detail view (the last screen in Figure 9-4).

image

Figure 9-1: Choosing the Master-Detail Application template.

image

Figure 9-2: Entering the project name and choosing options.

image

Figure 9-3: Reviewing the project settings.

image

Figure 9-4: Running the app.

Modifying the template

The default template lets you add events with the +; each one is annotated with a timestamp. For Locatapp, you use the same basic structure, but instead of creating entries with a timestamp, you will create entries that automatically pick up your location. The master view that lets you add entries and that displays the list of entries will now show the locations. When you click on a single item in that list, instead of showing the timestamp in a a full-screen view (as in the last screen in Figure 9-4 in Step 12 above), you’ll see it on a map.

This app lets you work with MapKit and Core Location. Together with the table view controller built into the template, you’re well on your way to building a customized and useful app.

As the name of the template suggests, this architecture relies on a master view and a detail view. It’s a very common structure. Here’s a bit more information about these views:

· Master view: This is the view shown in the middle two screens in Figure 9-4. It’s a list of the items that have been created in the app. This list is implemented with a custom class called MasterViewController that is located in MasterViewController.swift in the template.MasterViewController is a subclass of UITableViewController.

· Detail view: When you select an item from the master view list, you see its details in the detail view (shown in the last screen in Figure 9-4). This is done with a custom class in the template called DetailViewController; it is a subclass of UIViewController, and is implemented inDetailViewController.swift.

The concept of master and detail views and their controllers is very common. They can be named anything you want, but frequently the naming conventions used here (master and detail) are used.

In the template, the detail view controller manages a view (an instance of class UIView) that contains a UILabel object (shown with the timestamp in the last screen in Figure 9-4). This view hierarchy is implemented in Main.storyboard.

icon tip A storyboard or xib file is the standard way of designing view hierarchies. Storyboards are the more modern way of doing so. Main.storyboard is built into the template. You draw your interface on a canvas in the storyboard. Although a few examples of storyboards appear in this book, storyboarding itself (as are all details of the Cocoa and Cocoa Touch frameworks) is beyond the scope of this book.

The following list gives you a high-level overview of the modifications to the Master-Detail Application template that you make at this point. Don’t worry: The following sections provide the step-by-step details for you:

1. Change the detail view controller so that it manages an instance of MKMapView rather than an instance of UIView with an instance of UILabel within it.

2. Remove references to the UILabel instance to avoid an error (referencing an object that’s not there).

3. Adjust the map to show the user’s location.

4. Make necessary changes to the data model so that instead of a timestamp, a location with latitude and longitude is stored.

5. Modify the master view controller so that the + creates a new entity with the user’s current location rather than the current timestamp.

Adding a MKMapView view and removing the UIView and UILabel views

Here are the steps to replace the UIView with a MKMapView in the detail view controller:

1. Select Main.storyboard from the project navigator, as shown in Figure 9-5.

2. If necessary, choose Editor ⇒ Show Document Outline to reveal the document outline at the left. (That is, at the left of the editor; the project navigator is shown at the far left of the workspace window with the utilities area at the right.)

The editor’s main section is the canvas with the graphical representation of the user interface and the optional document outline at the left.

3. Open Detail Scene, and Detail view controller within it.

4. Select View within Detail as shown in Figure 9-5.

You may need to do some rearranging of the window. Figure 9-5 shows the utilities area at the right.

5. With View selected, delete it with the Delete key.

If it was opened, its subviews, layout guides, and constraints (shown in Figure 9-5) will also be deleted.

6. Check that the document outline looks like the one in Figure 9-6.

7. Find MapKit View in the lower-right of Library, as shown in Figure 9-7.

8. Drag a MapKit view into the document outline. Place it inside View and above Detail, as shown in Figure 9-8.

You can also drag it directly onto the canvas. Just make certain it winds up in the proper place in the document outline.

image

Figure 9-5: Opening the storyboard.

image

Figure 9-6: Removing the UIView (named View).

image

Figure 9-7: Locating MapKit View in the Library.

image

Figure 9-8: Adding a MapKit view.

Removing reference to the UILabel view and adding a reference to the UIMapView view

If you try to run the app now, it will fail. In fact, depending on the sequence in which you work, you may not even be able to build the app. That’s because there are still remnants of the template there. Specifically, there’s a detail item that you select from the list in the table view in the master view controller. It no longer exists, but the code is still there.

The following list shows you the steps to remove the old UILabel view code and to do a few other miscellaneous cleanups. Performing cleanups like these is good practice for working with this and other templates — it’s the kind of cleanup that you often have to do as you modify and repurpose them:

1. Start by opening DetailViewController.swift.

That’s where most of the changes will be made.

2. Change the import statements at the top of the file to add the MapKit framework.

import UIKit
import MapKit //add this line

3. Open the storyboard and DetailViewController.swift in the Assistant editor.

4. Control-drag from the map view to the property at the top of DetailViewController.swift as shown at the right in Figure 9-9.

5. Name the new connection mapView.

Names of properties start with lowercase letters and use “camelCase” (internal caps for each word). This is a convention, not a syntax requirement.

Double-check the other settings, as shown in Figure 9-9.

6. Click Connect to create the connection and the property declaration, as shown in Figure 9-10.

7. Delete a line.

The line should be somewhere around line number 14 or 15, if you have line numbers turned on in Text Editing tab in Xcode Preferences. This is the line to delete:

@IBOutlet var detailDescriptionLabel: UILabel!

8. Delete the body of the configureView function.

It’s a few lines below the area where you worked in Step 7. This is the code you will delete.

if let detail: AnyObject = self.detailItem {
if let label =
self.detailDescriptionLabel {
label.text
detail.valueForKey("timeStamp")!.description
}
}

The function should now look like this:

func configureView() {
// Update the user interface for the detail item
}

9. Run the app.

You should be able to add a timestamp on the master view controller with +. Click the timestamp you just added and you should see a map, as shown in Figure 9-11.

image

Figure 9-9: Adding the property for the map.

image

Figure 9-10: Connecting the outlet.

image

Figure 9-11: Running the app.

Showing the user’s location

To move ahead, you need to show the user’s current location on the map. That requires getting into the MapKit framework, but, as is the case with the use of many frameworks, you can use the framework without getting deep into it (at least to start).

If you reuse code that you’ve found to use a specific framework, remember to check its date. Frameworks (and now the languages) have evolved over time.

Conceptually, there are six steps to complete in order to get the user’s location. Although getting deeply into the MapKit framework isn’t necessary, knowing these basic steps is necessary if you’ll be using locations in your app. You’ll do this work in DetailViewController.swift because the detail view controller now contains the map view rather than the label view.

Here’s an overview of the steps:

1. Adopt protocols for Core Location and MapKit.

2. Add DetailView as delegates for Core Location and MKMapView so that you can use the frameworks and view.

3. Add a location manager so that you can interact with Core Location.

4. Add Core Location UI.

This includes arranging to ask the user’s permission to use the current location.

5. Use an option to show the user location on the map.

6. Set the location in the iOS Simulator. This is only for testing.

icon tip Adopting protocols and adding your class as a delegate to use them is a common Cocoa and Cocoa Touch scenario.

What follows are the steps to get this done. Note that although they are numbered, you don’t have to do them in sequence. Just know that as soon as you start on the steps, you will get syntax and compile errors. Don’t worry about them until you get to the end of the sequence when they should all be resolved.

1. In DetailView.swift, make certain that you import MapKit at the top of the file with this line of code:

import MapKit

2. Add MKMapViewDelegate and CLLocationManagerDelegate to your class declaration of DetailViewController.

The declaration should now read as follows:

class DetailViewController: UIViewController,
MKMapViewDelegate,
CLLocationManagerDelegate {

3. Verify that you have the map view connected to a property with this line of code:

@IBOutlet var mapView: MKMapView!

I showed how to do this previously in the section, “Removing reference to the UILabel view and adding a reference to the UIMapView view,” earlier in this chapter. You should see a small circle with a dot in the middle in the gutter to the left of this line. If you click on it, you will see what the connection is, as shown in Figure 9-12.

4. Add a locationManager property to MasterViewController.swift and set it up.

Create an instance of CLLocationManager and set the property to that instance. There is more on classes, instances, and initialization like this in Chapters 12 and 15. While you're here, also add a variable lastLocation, which you will update periodically with the user's location so that you always have a recent location to use in storing the current location.

The property and its initialization can go with the existing properties shown at the top of the file so that section looks like this with the locationManager property added.

class MasterViewController: UITableViewController,
NSFetchedResultsControllerDelegate,
CLLocationManagerDelegate {

var detailViewController: DetailViewController? = nil
var managedObjectContext: NSManagedObjectContext? = nil

let locationManager = CLLocationManager()
var lastLocation: CLLocation! = nil

5. Start checking the user's location. Add code to the end of viewDidLoad in MasterViewController.swift to start finding the user's location. Note that this line of code will fail because it calls a function you haven't written yet, but you will write it shortly.

self.startSignificantChangeUpdates ()

6. Set up the UI for asking the user’s permission.

Select the Info tab in the project, as shown in Figure 9-13.

7. At the bottom of the properties list, select the last item and then click + to add a new property.

It will be named Application Category (the first from the pop-up menu).

8. Change the name of the new property to NSLocationWhenInUseUsageDescription, as shown in Figure 9-14.

Make certain that it is a string and add text such as “This will let you see your current location.” This will be shown to the user when permission is asked.

9. Run the app. As soon as it launches, adjust the iOS Simulator’s location as shown in Figure 9-15.

In the iOS Simulator, use Debug ⇒ Location to choose a location for the simulator to use. You only have to do this once: the iOS Simulator will remember the location until you wipe out its local data with IOS Simulator ⇒ Reset Content and Settings.

10. Quit the app and rerun it. If necessary, add a new timestamp and select it. If you already have one, select it. You should see the alert shown in Figure 9-16. Click Allow.

11. Check that your location is marked as shown in Figure 9-17.

Even on the iOS Simulator, it may take a few moments to obtain the location. (On a mobile device, it will take longer — just be patient.)

image

Figure 9-12: Checking the map connection.

image

Figure 9-13: Selecting the project’s Info tab.

image

Figure 9-14: Adding the new property.

image

Figure 9-15: Setting the simulator’s location.

image

Figure 9-16: Allowing access to location data.

image

Figure 9-17: Adding the new property.

Exploring the Functions in Locatapp

Now that you have an app that’s running, it’s time to explore it in some detail. Each of the chapters in the remainder of this book will focus on a different area so that you can explore and develop new functionality in this app and the apps that you’ll develop.

If you haven’t worked through the steps in this chapter, now is a good time to do so: you’ll need that source code to follow along with the rest of the book. Working through those steps helps to bring you up to speed not only with Swift but also with Xcode and a basic familiarity with the Cocoa and Cocoa Touch frameworks (although Cocoa Touch is the primary framework used in this book, it includes many Cocoa frameworks).

icon tip If you haven’t worked through the steps outlined so far in this chapter, you can download Locatapp as described in the Introduction. Make certain that you download the version from Chapter 9.

Understanding the Locatapp Architecture

There are three Swift files in the Master-Detail Application template (and, thus, in your Locatapp project so far). That makes it easy to look at the app architecture (and, as noted previously, most apps share a fairly similar architecture). The three files are:

· AppDelegate.swift: This contains the overall app code (refer to Chapter 4, “Looking at a Swift App” for more details.

· MasterDetailViewController.swift: This is the controller for the list of items in the app. Other app templates do not have this file, but they have different files at the second level (that is, below the app delegate).

· DetailViewController.swift: This is the detail view controller for a select item from the master detail view’s list. In this chapter, you have replaced the default UILabel view with a MKMapView view.

If you want to drill down into those three files, Xcode has a tool for you. In the jump bar above the editor area, you have a list of the functions for the current file, as shown in Figure 9-18. Exploring those functions provides an overview of the architecture.

image

Figure 9-18: Viewing the functions in an Xcode file.

Uncovering the Function Features

Armed with the high-level view represented in the three points shown previously in this section, you can look at the functions in each file. Doing so will let you explore the features of functions. In the sections that follow, you will find references to the file in which each function is declared.

In most of this book, you find text and step lists to help you create code. In this section, the process is inverted so that you have the code (primarily from the template) and you take a look at how it works. This combination of top-down and bottom-up views can help you to become more familiar with Swift.

Not every function is discussed. This section provides an overview of the structure and uses it to point out features of functions. You’ll find those features used repeatedly throughout the frameworks, the templates, and this book.

Basic function syntax — configureView()

File: DetailViewController.swift

The configureView function is as basic as you can get. Here’s what it looks like.

func configureView() {
// Update the user interface for the detail item
}

Swift functions (or methods when they’re in classes) start with the keyword func, followed by the function name. Parameters (if any) are placed inside parentheses. If there are no parameters, the parentheses are empty as is the case here.

The body of the function is placed within brackets. As is the case here, the body can be empty. This would happen either if you have a placeholder function that will be filled in later or, as is the case here, if you have deleted the body code from a template function that you may use later on.

icon tip The comment in the function body is technically optional, but when you come back to this function tomorrow or next year, you’ll be glad you used it. And if you are submitting samples of your work for a job, those comments may well make the difference between a paycheck and a career in some other field.

Overriding a function — viewDidLoad()

File: DetailViewController.swift

Like other object-oriented languages, you can override functions (methods) in Swift. Unlike some other object-oriented languages, you must specify an override. Omitting the modifier override is a compile error. This rule prevents accidental overrides due to typos.

Here is an example from DetailViewController.swift:

override func viewDidLoad () {

In addition to override, you can also designate a method as final. That means that the method cannot be overridden by a subclass. The syntax for a final method is:

final func myFinalMethod () {

This rule applies to methods, properties, and subscripts of a class, as follows:

· No modifier: The method, property, or subscript can be overridden.

· override: This is the override of a declaration in a superclass.

· final: You cannot override this in a subclass.

This rule prevents a number of problems that can occur when several people work together on code, or where there are several levels of inheritance so that it's easy to create a new method that accidentally overrides a higher-level method.

Calling the super function — viewDidLoad()

File: DetailViewController.swift

When a function overrides a function you can call the overridden function from within your override using syntax like this:

override func viewDidLoad () {
super.viewDidLoad ()

Often, calls to the super function are the first or last line of the override function.

Adding a parameter to a function — controllerWillChangeContent(_:)

File: MasterViewController.swift

If a function takes a parameter, it is provided along with its type inside the parentheses as shown in the following code segment. The parameter’s name is controller. In good programming style, the function’s name describes what it will do — a controller will change content. The controller in question is passed in as a parameter. The controller’s type is NSFetchedResultsController.

func controllerWillChangeContent (
controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}

The controller that is passed in is not used in the basic function. That’s not an error. Parameters need not be used. A function like this one is often provided for the specific purpose of being overridden. It gives you an entry point into a process so that if you want to change the behavior, you have a function ready to override for that purpose.

Using multiple parameters in a function — controller(_:didChangeSection:atIndex:forChangeType:)

File: MasterViewController.swift

If you need multiple parameters to be passed into a function, separate them with commas, as in the following:

func controller(
controller: NSFetchedResultsController,
didChangeSection sectionInfo:
NSFetchedResultsSectionInfo,
atIndex sectionIndex: Int,
forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex),
withRowAnimation: .Fade)

default:
return
}
}

Now that you have multiple parameters in a function, there are some additional points to notice. The first parameter is named controller, and it is of type NSFetchedResultsController. Because this is a protocol function that is implemented by a delegate, the first parameter is the object that has sent the message. (See more in Chapter 18.) For non-delegate functions, this sender parameter is missing. Next comes the name of the function (didChangeSection), and then three parameters (sectionInfo, sectionIndex, and type). The combination of sender (if present), function name, and parameters (if present) uniquely identifies a function with a class.

Using external names for parameters — controller(_:didChangeSection:atIndex:forChangeType:)

File: MasterViewController.swift

The code shown in the previous section also demonstrates the use of external names.

The second parameter has both an internal and external name sectionInfo and didChangeSection respectively). Inside the function, either can be used, but the external name is used when referenced from outside the function. The internal name is required in all cases in the declaration; if the external name is not provided, use an underscore (_) as a placeholder; the internal one is assumed. Thus, in the previous example, the first parameter’s internal and external names are both controller.

This internal/external naming syntax is used to improve readability for two audiences — the engineers originally writing the function who may prefer the internal name and the developer/users who use the function. It also improves interaction with the Objective-C code in the frameworks that use this style.

Returning a value from a function — numberOfSectionsInTableView(_:)

File: MasterViewController.swift

If a function returns a value, it’s placed after the main part of the declaration with ->:

override func tableView
( tableView: UITableView,
canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}

If you want to explore other elements of these functions, a good place to start is Chapter 10, which deals with expressions.

Adding Location Support

At this point, you have the code to show the user’s location on the map using the iOS Simulator. What you don’t have is the ability to access that location from your code. You’ll need to do that if you want to store the user’s location with the +. You’ll also need to addstartSignificantChangeUpdates (), which you referenced from viewDidLoad in MasterViewController.swift earlier in this chapter (in the section “Showing the user’s location”).

You can place that function together with two protocol methods at the end of the file with the code described in this section. First, it’s good practice to use the MARK directive to set off sections of code. These three functions support the CLLocationManagerDelegate protocol (it’s discussed further in Chapter 18).

Listing 9-1 shows the setup code you need to use to get the location manager up and running. This code was described in Chapter 4. As a review, this is the critical code that’s added to MasterViewController.swift there. (Remember to follow the steps to have the MapKit view show the user’s location.)

The functions in Listings 9-2 and 9-3 fulfill the promise you made to conform to the CLLocationManagerDelegate protocol (see Chapter 18 for more on protocols). Note that locationManager (_: didUpdateLocations:) in Listing 9-2 is where you take the location from thelocationManager and store it in self.lastLocation, which you declared earlier in this chapter at the very top of MasterViewController.swift. It's there waiting for you to use it when you add a new location with + .

Listing 9-1: startSignificantChangeUpdates

// MARK: - CLLocationManagerDelegate Protocol
func startSignificantChangeUpdates () {

if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.NotDetermined {
self.locationManager.requestWhenInUseAuthorization ()
}

if CLLocationManager.locationServicesEnabled() {
self.locationManager.delegate = self
self.locationManager.requestWhenInUseAuthorization ()

self.locationManager.distanceFilter = kCLDistanceFilterNone
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.startUpdatingLocation()

self.locationManager.
startMonitoringSignificantLocationChanges ();
}
}

Listing 9-2: locationManager (_: didUpdateLocations:)

func locationManager(manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!) {

self.lastLocation = manager.location
}

Listing 9-3: locationManager (_: didFailWithError:)

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
// need to add code to handle errors
}

You also need to update the data model to store the location that you’ve picked up in Listing 9-2. This is described in Chapter 4.