A Example iOS 10 Location Application

From Techotopia
Revision as of 04:39, 10 November 2016 by Neil (Talk | contribs) (Designing the User Interface)

Jump to: navigation, search

PreviousTable of ContentsNext
Getting Location Information using the iOS 10 Core Location FrameworkWorking with Maps on iOS 10 with MapKit and the MKMapView Class


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


Having covered the basics of location management in iOS 10 applications in the previous chapter it is now time to put theory into practice and work step-by-step through an example application. The objective of this chapter is to create a simple iOS application that tracks the latitude, longitude and altitude of an iOS device. In addition, the level of location accuracy will be reported, together with the distance between a selected location and the current location of the device.


Contents


Creating the Example iOS 10 Location Project

The first step, as always, is to launch the Xcode environment and start a new project to contain the location application. Once Xcode is running, select the File -> New -> Project… menu option and configure a new iOS project named Location using the Single View Application template with the language set to Swift and the Devices menu set to Universal.

Designing the User Interface

The user interface for this example location app is going to consist of a number of labels and a button that will be connected to an action method. Initiate the user interface design process by selecting the Main.storyboard file. Once the view has loaded into the Interface Builder editing environment, create a user interface that resembles as closely as possible the view illustrated in Figure 78 1.

In the case of the five labels in the right-hand column which will display location and accuracy data, make sure that the labels are stretched to the right until the blue margin guideline appears. The data will be displayed to multiple levels of decimal points requiring space beyond the default size of the label.

Select the label object to the right of the “Current Latitude” label in the view canvas, display the Assistant Editor panel and verify that the editor is displaying the contents of the ViewController.swift file. Ctrl-click on the same Label object and drag to a position just below the class declaration line in the Assistant Editor. Release the line and in the resulting connection dialog establish an outlet connection named latitude. Repeat these steps for the remaining labels, connecting them to properties named longitude, horizontalAccuracy, altitude, verticalAccuracy and distance respectively.


Xcode 8 ios 10 location ui.png

Figure 78-1


The final step of the user interface design process is to connect the button object to an action method. Ctrl-click on the button object and drag the line to the area immediately beneath the viewDidLoad method in the Assistant Editor panel. Release the line and, within the resulting connection dialog, establish an Action method on the Touch Up Inside event configured to call a method named resetDistance.

Close the Assistant Editor and add a variable to the ViewController class in which to store the start location coordinates and the location manager object. Now is also an opportune time to import the CoreLocation framework and to declare the class as implementing the CLLocationManagerDelegate protocol:

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var latitude: UILabel!
    @IBOutlet weak var longitude: UILabel!
    @IBOutlet weak var horizontalAccuracy: UILabel!
    @IBOutlet weak var altitude: UILabel!
    @IBOutlet weak var verticalAccuracy: UILabel!
    @IBOutlet weak var distance: UILabel!

    var locationManager: CLLocationManager = CLLocationManager()
    var startLocation: CLLocation!
.
.
}

Configuring the CLLocationManager Object

The next task is to configure the instance of the CLLocationManager class and to make sure that the application requests permission from the user to track the current location of the device. Since this needs to occur when the view loads, an ideal location is in the view controller’s viewDidLoad method in the ViewController.swift file:

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.delegate = self
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
    startLocation = nil
 }

The above code changes configure the CLLocationManager object instance to use the “best accuracy” setting. The code then declares the view controller instance as the application delegate for the location manager object. The application then requests permission from the user for the application to track location information while the application is in the foreground prior to starting location updating via a call to the startUpdatingLocation method. Since location tracking has just begun at this point, the startLocation variable is also set to nil.

Setting up the Usage Description Key

The above code changes included a method call to request permission from the user to track location information when the application is running in the foreground. This method call must be accompanied by a usage description string which needs to be added to the project’s Info.plist file and assigned to the NSLocationWhenInUseUsageDescription key. Within the project navigator panel, load the Info.plist file into the editor. The key-value pair needs to be added to the Information Property List dictionary. Select this entry in the list and click on the + button to add a new entry to the dictionary and, from the resulting menu, select the Privacy – Location When in Use Usage Description item. Once the key has been added, double-click in the corresponding value column and enter the following text so that the entry matches that of Figure 78-2:

The application uses this information to show you your location


Xcode 8 ios 10 location usage key.png

Figure 78-2


Implementing the Action Method

The button object in the user interface is connected to the resetDistance action method so the next task is to implement that action. All this method needs to do is set the startlocation variable to nil:

@IBAction func resetDistance(_ sender: AnyObject) {
    startLocation = nil
} 

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Implementing the Application Delegate Methods

When the location manager detects a location change, it calls the didUpdateLocations delegate method. Since the view controller was declared as the delegate for the location manager in the viewDidLoad method, it is necessary to now implement this method in the ViewController.swift file:

func locationManager(_ manager: CLLocationManager,
                didUpdateLocations locations: [CLLocation])
{
    let latestLocation: CLLocation = locations[locations.count - 1]

    latitude.text = String(format: "%.4f",
                         latestLocation.coordinate.latitude)
    longitude.text = String(format: "%.4f",
                         latestLocation.coordinate.longitude)
    horizontalAccuracy.text = String(format: "%.4f",
                         latestLocation.horizontalAccuracy)
    altitude.text = String(format: "%.4f",
                         latestLocation.altitude)
    verticalAccuracy.text = String(format: "%.4f",
                         latestLocation.verticalAccuracy)

    if startLocation == nil {
        startLocation = latestLocation
    }

    let distanceBetween: CLLocationDistance =
                latestLocation.distance(from: startLocation)

    distance.text = String(format: "%.2f", distanceBetween)
} 

When the delegate method is called it is passed an array of location objects containing the latest updates, with the last item in the array representing the most recent location information. To begin with, the delegate method extracts the last location object from the array and works through the data contained in the object. In each case, it creates a string containing the extracted value and displays it on the corresponding user interface label.

If this is the first time that the method has been called either since the application was launched or the user last pressed the Reset Distance button, the startLocation variable is set to the current location. The distance(from:) method of the location object is then called, passing through the startLocation object as an argument in order to calculate the distance between the two points. The result is then displayed on the distance label in the user interface.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

The didFailWithError delegate method is called when an error is encountered by the location manager instance. This method should also, therefore, be implemented:

func locationManager(_ manager: CLLocationManager,
         didFailWithError error: Error) {

}

The action taken within this method is largely up to the application developer. The method, might, for example, simply display an alert to notify the user of the error.

Building and Running the Location Application

Click on the run button located in the Xcode project window toolbar. Once the application has compiled and linked it will launch into the iOS Simulator. Before location information can be gathered, the user is prompted to grant permission as outlined in Figure 78-3:


Ios 8 location usage request.png

Figure 78 3


Once permission is granted, the application will begin tracking location information. By default, the iOS Simulator may be configured to have no current location causing the labels to remain unchanged. In order to simulate a location, select the iOS Simulator Debug -> Location menu option and select either one of the pre-defined locations or journeys (such as City Bicycle Ride), or Custom Location… to enter a specific latitude and longitude. The following figure shows the application running in the iOS Simulator after the Apple location has been selected from the menu:


An Example iOS 10 Location based application running

Figure 78-4


To experience the full functionality of the application it will be necessary to install it on a physical iOS device. Once the application is running on the device, location data will update as you change location. One final point to note is that the distance data relates to the distance between two points, not the distance travelled. For example, if the device accompanies the user on a 10 mile trip that returns to the start location the distance will be displayed as 0 (since the start and end points are the same).


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
Getting Location Information using the iOS 10 Core Location FrameworkWorking with Maps on iOS 10 with MapKit and the MKMapView Class