In order to support this post, I have published a demonstration project on Github. Feel free to clone it and follow along in this post.
I recently posted about how to implement location tracking via iOS Location Services, and felt a follow-up would be useful. It's one thing to make a location aware app, and it's quite another to see it work in the wild. Testing is very important here. But you don't have time to drive around, you say? You don't have the money to fly across country to see how your app behaves in other regions? Fortunately, Apple has provided some tools and mechanisms to test location aware apps from within the comforts of your own development environment.
With the release of iOS 5, location simulation was added to the corresponding development tools. As a result, there are a few ways to simulate locations.
- Xcode: GPX files, schemes
- Simulator (iOS 5+): manually set the location
- UI Automation Instrument: load up various lat/long points via a script to simulate movement
GPX (GPS exchange) files are XML files that conform to the GPX schema, which allows interchanging of GPS data. GPS systems generate and consume this format, and so does Xcode! Creating a location is fairly simple if you have the latitude and longitude of a point. You can also create routes and a whole host of location files that can be used to simulate locations. The following is a simple GPX file that targets a location in Lincoln, Nebraska, USA.
Once you have added your GPX files to your Xcode project, there are two ways to utilize them. The first is by setting the default location in a scheme. If you have several locations you need to test regularly, you can create a scheme for each location to make it simpler to test your app in each location quickly. When you run your app under the custom scheme, Xcode will automatically simulate the app running in the location according to the scheme configuration. To do this:
1. From the scheme menu, click New Scheme…
2. Enter a name, and click OK. I used my project name + location. For example, CSLocationTestKit-Lincoln, NE.
3. From the scheme menu, click Edit Scheme…
4. In the Options tab, check the Allow Location Simulation in the Core Location section.
5. Select the GPX file for the Default Location. If you added a GPX file to your project, it should be displayed in the list for you to select. Alternatively, you can add an existing GPX file from this menu.
What if I want to change the location in the middle of simulator testing? You can change the location in Xcode during runtime as well. After your app starts up, bring up Xcode and ensure the Debug pane is showing (the bottom view). Select the blue arrow to get a list of locations including those specified in GPX files in your project.
To change the location in the simulator directly, click the Debug menu, and select Navigation. This can be done at runtime while debugging or while navigating through the simulator detached from any Xcode projects.
The simulator options are vastly simpler and thus more limited. You can select Custom Location… to enter a set of coordinates, but this is less robust than using GPX file. However, if you have a need to do some ad hoc testing of coordinates, this method is sufficient.
UI Automation Instrument
The final and arguably the most powerful method of testing a location aware app is to use the UI Automation Instrument. It is also the trickiest because Apple’s documentation of instruments isn't very explicit on how to use it for testing movement amongst locations. Once you get started though, it gets much simpler.
To use the UI Automation instrument:
1. Click and hold the Run button in Xcode, and select Profile (or click Product > Profile from the menu at the top)
2. Instruments will open. Select Automation and click Profile
3. Stop the recording that is automatically triggered by Instruments.
4. In the Scripts section, click Add to create a new script. You can import existing scripts as well as calling up scripts you've recently used/exported. I have included a sample script to test driving a route to a country club in Lincoln, NE. This script works best if you use the Lincoln, NE GPX file as the starting location.
5. In Xcode, click the Profile button again to trigger a profiling restart using the script you just imported/created. Don't forget you have to stop the Recording once your script has run (this is documented).
Supplemental Recommended Viewing/Reading
Testing iPhone Location App with Automation by Plain Old Stan
Location Awareness Programming Guide from Apple
Session 500 at WWDC 2011: What’s New in Core Location – good basic intro to location services, particularly the new features that came with iOS 5
Session 518 at WWDC 2011: Testing Your Location-Aware Application – this is a must watch! It has a lot of good info on how to setup your environment to test different locations and even moving from location to location.
Session 303 at WWDC 2012: Staying on Track with Location Services