Core Location

The Core Location framework contains the classes that enable applications to determine the device’s geographical location. No matter what type of iOS device is being used, the Core Location code you write does not change.

The classes in the Core Location framework are all prefixed with CL. In fact, every framework in Cocoa Touch has its own prefix – UIKit classes are prefixed with UI, Foundation classes with NS, etc. Prefixing class names is a convention that prevents namespace collisions. For example, pretend that both Foundation and Core Location have classes called Object. If you wrote an application that used both frameworks, any instantiation of an Object would leave the compiler in a quandary – which Object does this code refer to? Note that prefixes aren’t just for frameworks. Objective-C programmers typically include prefixes of two or three letters in the names of classes they create for the same reason.

In addition to adding the Core Location framework to your target, you also have to import the framework’s header file into files that need to know about Core Location classes. Every framework has a header file that imports the header file of every class in that framework. This file is always the name of the framework suffixed with .h.

Open WhereamiAppDelegate.h and import the Core Location header file at the top. Also, add an instance variable to hold a pointer to an instance of CLLocationManager – one of the classes in the Core Location framework.

#​i​m​p​o​r​t​ ​<​U​I​K​i​t​/​U​I​K​i​t​.​h​>​
#​i​m​p​o​r​t​ ​<​C​o​r​e​L​o​c​a​t​i​o​n​/​C​o​r​e​L​o​c​a​t​i​o​n​.​h​>​

@​i​n​t​e​r​f​a​c​e​ ​W​h​e​r​e​a​m​i​A​p​p​D​e​l​e​g​a​t​e​ ​:​ ​N​S​O​b​j​e​c​t​ ​<​U​I​A​p​p​l​i​c​a​t​i​o​n​D​e​l​e​g​a​t​e​>​
{​
 ​ ​ ​ ​C​L​L​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​*​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​;​
}​
@​p​r​o​p​e​r​t​y​ ​(​n​o​n​a​t​o​m​i​c​,​ ​r​e​t​a​i​n​)​ ​I​B​O​u​t​l​e​t​ ​U​I​W​i​n​d​o​w​ ​*​w​i​n​d​o​w​;​
@​e​n​d​

CLLocationManager is the class that interfaces with the location hardware of the device. An instance of CLLocationManager has a number of properties that specify its behavior. We’re going to set two of them: distanceFilter and desiredAccuracy.

The distanceFilter property determines how far the device must move in meters before CLLocationManager will tell your application that the location has changed. The desiredAccuracy property tells the location manager how accurate the location-finding should be. This is important because there is a tradeoff between the accuracy of the location and the amount of battery life and time required to determine the location. Moreover, the accuracy ultimately depends on the type of device the user has, the availability of cellular towers and satellites, and the availability of known wireless access points.

Once its properties are set, the CLLocationManager is told to start working. It then does its thing while the rest of the application continues with other tasks – like accepting user input or updating the interface.

Open WhereamiAppDelegate.m, and in the application:​didFinishLaunchingWithOptions: method, instantiate a CLLocationManager to track the device’s location. For this application, you will set its properties to request the most accurate location data as often as possible.

-​ ​(​B​O​O​L​)​a​p​p​l​i​c​a​t​i​o​n​:​(​U​I​A​p​p​l​i​c​a​t​i​o​n​ ​*​)​a​p​p​l​i​c​a​t​i​o​n​
 ​ ​ ​ ​d​i​d​F​i​n​i​s​h​L​a​u​n​c​h​i​n​g​W​i​t​h​O​p​t​i​o​n​s​:​(​N​S​D​i​c​t​i​o​n​a​r​y​ ​*​)​l​a​u​n​c​h​O​p​t​i​o​n​s​
{​
 ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​l​o​c​a​t​i​o​n​ ​m​a​n​a​g​e​r​ ​o​b​j​e​c​t​
 ​ ​ ​ ​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​=​ ​[​[​C​L​L​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​/​/​ ​W​e​ ​w​a​n​t​ ​a​l​l​ ​r​e​s​u​l​t​s​ ​f​r​o​m​ ​t​h​e​ ​l​o​c​a​t​i​o​n​ ​m​a​n​a​g​e​r​
 ​ ​ ​ ​[​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​s​e​t​D​i​s​t​a​n​c​e​F​i​l​t​e​r​:​k​C​L​D​i​s​t​a​n​c​e​F​i​l​t​e​r​N​o​n​e​]​;​

 ​ ​ ​ ​/​/​ ​A​n​d​ ​w​e​ ​w​a​n​t​ ​i​t​ ​t​o​ ​b​e​ ​a​s​ ​a​c​c​u​r​a​t​e​ ​a​s​ ​p​o​s​s​i​b​l​e​
 ​ ​ ​ ​/​/​ ​r​e​g​a​r​d​l​e​s​s​ ​o​f​ ​h​o​w​ ​m​u​c​h​ ​t​i​m​e​/​p​o​w​e​r​ ​i​t​ ​t​a​k​e​s​
 ​ ​ ​ ​[​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​s​e​t​D​e​s​i​r​e​d​A​c​c​u​r​a​c​y​:​k​C​L​L​o​c​a​t​i​o​n​A​c​c​u​r​a​c​y​B​e​s​t​]​;​

 ​ ​ ​ ​/​/​ ​T​e​l​l​ ​o​u​r​ ​m​a​n​a​g​e​r​ ​t​o​ ​s​t​a​r​t​ ​l​o​o​k​i​n​g​ ​f​o​r​ ​i​t​s​ ​l​o​c​a​t​i​o​n​ ​i​m​m​e​d​i​a​t​e​l​y​
 ​ ​ ​ ​[​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​s​t​a​r​t​U​p​d​a​t​i​n​g​L​o​c​a​t​i​o​n​]​;​

 ​ ​ ​ ​/​/​ ​T​h​i​s​ ​l​i​n​e​ ​m​a​y​ ​s​a​y​ ​s​e​l​f​.​w​i​n​d​o​w​,​ ​d​o​n​'​t​ ​w​o​r​r​y​ ​a​b​o​u​t​ ​t​h​a​t​
 ​ ​ ​ ​[​[​s​e​l​f​ ​w​i​n​d​o​w​]​ ​m​a​k​e​K​e​y​A​n​d​V​i​s​i​b​l​e​]​;​
 ​ ​ ​ ​r​e​t​u​r​n​ ​Y​E​S​;​
}​

Receiving updates from CLLocationManager

If you build and run this code right now, the location manager will get your current location, but you won’t see this information anywhere. Your application has to retrieve the location from the location manager. You might guess that there is a property on CLLocationManager called currentLocation that we can access to retrieve the location. It’s a good guess, but there isn’t. You could try polling the location manager to get the location, but the amount of time it takes to determine the current location is too variable for polling to be efficient.

The best solution is for the location manager to take matters into its own hands. Whenever it finds the current location, it sends the message locationManager:​didUpdateToLocation:​fromLocation:. Who is sent this message? The location manager’s delegate – and we get to decide who that is.

Every CLLocationManager has a delegate property, and we can set this property to point to the object that should receive the location found message. For Whereami, this object is the WhereamiAppDelegate (Figure 4.3).

Figure 4.3  Whereami object diagram

Whereami object diagram

In WhereamiAppDelegate.m, update the application:​didFinishLaunchingWithOptions: method to set the delegate property of the location manager to be the instance of WhereamiAppDelegate.

-​ ​(​B​O​O​L​)​a​p​p​l​i​c​a​t​i​o​n​:​(​U​I​A​p​p​l​i​c​a​t​i​o​n​ ​*​)​a​p​p​l​i​c​a​t​i​o​n​
 ​ ​ ​ ​d​i​d​F​i​n​i​s​h​L​a​u​n​c​h​i​n​g​W​i​t​h​O​p​t​i​o​n​s​:​(​N​S​D​i​c​t​i​o​n​a​r​y​ ​*​)​l​a​u​n​c​h​O​p​t​i​o​n​s​
{​
 ​ ​ ​ ​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​=​ ​[​[​C​L​L​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​a​l​l​o​c​]​ ​i​n​i​t​]​;​

 ​ ​ ​ ​/​/​ ​T​h​e​r​e​ ​w​i​l​l​ ​b​e​ ​a​ ​w​a​r​n​i​n​g​ ​f​r​o​m​ ​t​h​i​s​ ​l​i​n​e​ ​o​f​ ​c​o​d​e​;​ ​i​g​n​o​r​e​ ​i​t​ ​f​o​r​ ​n​o​w​
 ​ ​ ​ ​[​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​s​e​t​D​e​l​e​g​a​t​e​:​s​e​l​f​]​;​

 ​ ​ ​ ​[​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​s​e​t​D​i​s​t​a​n​c​e​F​i​l​t​e​r​:​k​C​L​D​i​s​t​a​n​c​e​F​i​l​t​e​r​N​o​n​e​]​;​

One of the arguments of the locationManager:​didUpdateToLocation:​fromLocation: message is an instance of a class named CLLocation. When a CLLocationManager has enough data to produce a new location, it creates an instance of CLLocation, which contains the latitude and longitude of the device (Figure 4.4). It also contains the accuracy of its reading and, depending on the device, the elevation above sea level.

Figure 4.4  A CLLocation object

A CLLocation object

Because the CLLocationManager sends locationManager:​didUpdateToLocation:​fromLocation: to the instance of WhereamiAppDelegate, you implement this method in WhereamiAppDelegate.m. (Be very careful that there are no typos or capitalization errors, or it won’t be called. The selector of the message the location manager sends must exactly match the selector of the method implemented.)

-​ ​(​v​o​i​d​)​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​:​(​C​L​L​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​*​)​m​a​n​a​g​e​r​
 ​ ​ ​ ​d​i​d​U​p​d​a​t​e​T​o​L​o​c​a​t​i​o​n​:​(​C​L​L​o​c​a​t​i​o​n​ ​*​)​n​e​w​L​o​c​a​t​i​o​n​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​f​r​o​m​L​o​c​a​t​i​o​n​:​(​C​L​L​o​c​a​t​i​o​n​ ​*​)​o​l​d​L​o​c​a​t​i​o​n​
{​
 ​ ​ ​ ​N​S​L​o​g​(​@​"​%​@​"​,​ ​n​e​w​L​o​c​a​t​i​o​n​)​;​
}​

You also need to know if the CLLocationManager fails to find its location and why. If it fails, CLLocationManager sends a different message to its delegate – locationManager:didFailWithError:. In WhereamiAppDelegate.m, implement this method.

-​ ​(​v​o​i​d​)​l​o​c​a​t​i​o​n​M​a​n​a​g​e​r​:​(​C​L​L​o​c​a​t​i​o​n​M​a​n​a​g​e​r​ ​*​)​m​a​n​a​g​e​r​
 ​ ​ ​ ​ ​ ​ ​d​i​d​F​a​i​l​W​i​t​h​E​r​r​o​r​:​(​N​S​E​r​r​o​r​ ​*​)​e​r​r​o​r​
{​
 ​ ​ ​ ​N​S​L​o​g​(​@​"​C​o​u​l​d​ ​n​o​t​ ​f​i​n​d​ ​l​o​c​a​t​i​o​n​:​ ​%​@​"​,​ ​e​r​r​o​r​)​;​
}​

Build and run the application. You can choose whether to build to the simulator or to a device by selecting the appropriate item from the Scheme pop-up button next to the Run and Stop buttons. After giving permission for the application to use location services and waiting a few seconds while the location is found, your console should display the description of the location object, which looks something like this:

<​+​3​7​.​3​3​1​6​8​9​0​0​,​ ​-​1​2​2​.​0​3​0​7​3​1​0​0​>​ ​+​/​-​ ​1​0​0​.​0​0​m​ ​(​s​p​e​e​d​ ​-​1​.​0​0​ ​m​p​s​ ​/​ ​c​o​u​r​s​e​ ​-​1​.​0​0​)​

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.86.245