Friday, October 14, 2011

Location Services : Getting Started

This series discusses the iPhone Location Services.  In this post, we set up Xcode so we can begin prototyping.

Introduction
One useful feature of mobile devices is their location-awareness.  Once an application knows your location, it can tailor its services to be more relevant.  Let's make HelloWorld location aware.

The Location Awareness Programming Guide provides a good starting point for learning about the Core Location framework.  In addition to region- and heading-monitoring, the framework offers a couple of ways to get a user's current location:
  • Standard location service
    • Configurable accuracy
    • Power sensitive
    • GPS hardware enabled
    • Configurable notification intervals
  • Significant-change location service
    • Low accuracy
    • Low power 
    • Cell radio only
    • Notifications only for significant changes 
Its not clear yet which we want for HelloWorld.  Let's dive in and see how they work, and what they offer.

Prototyping Target
When prototyping, it is essential that we iterate quickly and independently of the application.  We don't want any unrelated code or dependencies getting in the way.  That way, we can focus our attention on the task at hand and keep variables from being introduced.  

Often the best strategy to accomplish this is to encapsulate the prototype logic in its own class and then execute that code directly, bypassing any other application code.   So we can still iterate rapidly, we shall create a separate "sandbox" target in Xcode that is independent of HelloWorld.  Then, when our prototyping is done, we can very simply include the finished product in the HelloWorld target.  

Start by creating a new target (File > New > New Target... menu):
We want the sandbox target to include all the usual Xcode features (especially iOS Simulator), so let's create an empty iPhone app and use that.  Select "Single View Application" and then click "Next".  Name the target "LSDemo" or something.  Also, since this target is for prototyping, we shall not be writing unit tests, so feel free to un-check the "Include Unit Tests" option.  Finally, click "Finish":

Yay!  Now we have an empty iPhone target containing the following:
  • Stub AppDelegate class
  • Stub ViewController class
  • Empty storyboard
  • Supporting Files
    • Includes main.m
We shall use this dummy application to test our prototyping code.  But first we need to create another scheme.

Prototyping Scheme
When we created the HelloWorld project (see the Hello World post), Xcode also provided us with a default HelloWorld scheme.  However, as we rapidly prototype our sandbox code, we do not wish to be encumbered by the full HelloWorld app.  To accommodate this, lets give LSDemo its own scheme.  

Open the New Scheme... dialog (Product > New Scheme... menu):

Notice it automatically guesses "LSDemo" as the default build target and group name.  Click "OK" to create the scheme.  The new LSDemo scheme will be automatically selected in the Xcode toolbar.  Build and run the sandbox target as you would HelloWorld.  The iOS Simulator should appear with the empty app inside:

Yay!  We shall use this scheme to launch the sandbox build target as we prototype.  

Core Location framework
Finally, we must include the Core Location framework in our project.  Otherwise, Xcode will not be able to find any of the classes in the Core Location library.  Open the project properties and select the "LSDemo" build target.  Then open the Build Phases panel and expand the "Link Binary With Libraries" group:

This shows all the frameworks currently used for the "LSDemo" target.  Click the "+" button and choose "CoreLocation.framework" from the list of libraries:

Click "Add" to complete the transaction.  Confirm the Core Location framework now appears in the "Link Binary With Libraries" group.

A brief word about organizing your project.  Notice when we added "CoreLocation.framework", Xcode places it at the root of the project:
(Circled in red.)  Feel free to drag it down to the "Frameworks" group:
(Circled in red.)  This will not modify any existing associations.  Rather, it merely changes where "CoreLocation.framework" appears in the Project Navigator.  

Yay!  Now it is time to start playing with some actual code.