iOS Dev Notes

iOS Development From The Frontlines

SimpleGeo on the iOS: Getting Started Tutorial

with 6 comments

Mobile apps that are geographically-aware are all the rage these days, and there’s a number of ways to jump into this new geo-world we live in.  One of the more interesting ones is SimpleGeo.  They’re a startup in San Francisco that provides a number of APIs for doing geo-related things (like geofencing, and reverse geocoding which we’ll take a stab at today).

Although they have a pretty decent iOS framework, there is next to zero documentation on how to use it.  So I thought I’d write a simple app demonstrating how to do a reverse geocode (and retrieve the current weather) using SimpleGeo.framework.  Here’s the process:

  1. Get the current lat/lng using the built-in iOS Core Location framework.
  2. Create an SGPoint using the lat/lng.
  3. Setup SimpleGeo with your API keys
  4. Pass the SGPoint to getContextForPoint, with ourselves as a delegate

An SGContext will give us a whole slew of information, including the reverse geocoded address for our lat/lng (among the data is also weather information at this point and more).

A Little Background First

Why would we want to use SimpleGeo to do a reverse geocode in the first place?  What the heck is a reverse geocode?  And why does everything have the word “geo” in it all of a sudden?

Well, first of all, a “geocode” is the process of taking a postal address and converting it to latitude and longitude coordinates.  When we’re dealing with a phone that has a built-in GPS, however, we’re going to be getting only lat/lng points from our device.  It will then be up to us to figure out what the address is.  Hence, a “reverse geocode”.

As for why we’d want to use SimpleGeo to do this reverse geocode?  Built into the iOS is a reverse geocoder that uses Google Maps to achieve similar results.  For many people this is sufficient; however for others, it creates problems.  For one thing, you must be willing to agree to Google’s Maps TOS to use the service and be restricted by their rate limits (at the time of this writing they allow 2,500 requests per day).  SimpleGeo has a very handy API access monitoring and rate limiting system, and you can optionally pay for additional access as you need it.  Their free plan is also quite generous: our simple app will be able to do 10k requests per day.

Getting Started

To get started, create a new iOS project in Xcode.  You’ll need to add the YAJL and SimpleGeo frameworks along with:

  • Foundation
  • UIKit
  • CFNetwork
  • SystemConfiguration
  • MobileCoreServices
  • CoreGraphics
  • libz
  • MapKit
  • CoreLocation

Note that MapKit and CoreLocation are not listed as dependencies in the SimpleGeo.framework README file, but they are required (I submitted a pull request for the documentation – hopefully it will be updated).

Once you’ve got an app that builds using the framework, you next need to setup your developer access at www.simplegeo.com.  Create an account, login, and grab your consumer and secret keys.  We’ll need those in a moment.

Where Am I?

If you’re not already familiar with Core Location, it’s fairly easy to get started with.  I won’t rehash all the details here, but the general idea is that you need to register to receive location events and then act on them.  One tip that many people forget: be sure to turn off location updating to conserve power when you don’t need it.

First up, let’s setup our CLLocationManager and set ourselves as the delegate.  For my demo app, I’m doing this as part of the viewDidLoad, but you should really consider moving this (say, into its own singleton) if you plan to use it throughout your app:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;

Next, since we’ll be the delegate, we’ll want to implement the didUpdateToLocation method (as well as the error handler):

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
	// wait until we are within a certain level of accuracy
	if(newLocation.horizontalAccuracy <= 70.0f) {
		[locationManager stopUpdatingLocation];
	}
 
	// newLocation.coordinate.latitude
	// newLocation.coordinate.longitude
}

This method is called in response to the CLLocationManager getting a new location.  We first check that the accuracy is acceptable to us (remember that the accuracy can change depending on which method the device is using to determine location, as well as how many GPS satellites it can acquire, etc), then turn off updates.  I chose 70 (as in 70 meters) as that is what the simulator returns, but hopefully we can get more accurate than that.

Of course, we’ll want to tell the CLLocationManager to start updating.  I added this in the viewWillAppear method:

[locationManager startUpdatingLocation];

To be safe, I also added a stopUpdatingLocation to the viewWillDisappear (for the case where we can never get a good-enough accuracy before the user navigates to another screen).

Setting Up SimpleGeo

The first step to using SimpleGeo is to initialize an SGClient with your API credentials (you did set that up already, right?).

self.sgClient = [SimpleGeo clientWithDelegate:self
consumerKey:@"CONSUMER_KEY"
consumerSecret:@"SECRET"];

You can now use sgClient to subsequently get the SGContext information for the lat/lng we received from CoreLocation.  First, however, we need an SGPoint:

SGPoint* myPoint = [SGPoint pointWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];

Retrieving SGContext

Now that we have our lat/lng and an SGPoint, the next step is to ask SimpleGeo for details about it.  This can be done by querying for an SGContext, which will return all sorts of interesting details, including:

  • Street address (if known), province, country, etc
  • Street intersections
  • School district information
  • Voting precinct and government type
  • Time zone
  • And weather

Each response is slightly different depending on what SimpleGeo knows about the location so be sure you structure your results code to handle situations where expected information isn’t available.

To get context information, we need to do two things: first, implement a delegate to handle the asynchronous callback from SimpleGeo.framework, and then to actually request information.  When a context has been retrieved, SimpleGeo.framework will attempt to call the didLoadContext method:

- (void)didLoadContext:(NSDictionary *)context forQuery:(NSDictionary *)query {
}

Here’s how to kick off the request:

[sgClient getContextForPoint:myPoint];

When didLoadContext get’s called, the context dictionary contains all the goodies SimpleGeo has on your location, and this is where you’ll find things like your street address and weather.

Hope you found this helpful.  I’ve also created a demo iOS app with this code – just drop in your API credentials and check it out.


Looking to add push notifications to your iOS app? Check out PushLayer, a service from the authors of iOSDevNotes.

Bookmark and Share

Subscribe for updates

Fill out the form below to join my newsletter. I'll also send you a bonus copy of my ebook, "5 Steps To Becoming a Better iOS Developer".

Written by rtwomey

August 1st, 2011 at 11:27 am

Posted in Tutorials,UI

6 Responses to 'SimpleGeo on the iOS: Getting Started Tutorial'

Subscribe to comments with RSS or TrackBack to 'SimpleGeo on the iOS: Getting Started Tutorial'.

  1. Great tutorial.

    Suggestion: Can you make another tutorial explaining how to make a wheel of fortune (a rotary picker/chooser)?

    like this:
    http://goo.gl/1pTkq
    http://goo.gl/WPJLe
    http://goo.gl/GGgva
    http://goo.gl/ZdTOs

    Thanks!!

    moosc

    1 Aug 11 at 2:42 pm

  2. [...] service (though there is a built-in geocoder in iOS that uses Google). Be sure to check out the article on using SimpleGeo to reverse geocode a pair of lat/lng coordinates into a street address. #af-form-1503460406 .af-body [...]

  3. [...] To get started, create a new iOS project in Xcode. You’ll need to add the YAJL and SimpleGeo frameworks along with: Foundation Getting Started UIKit SimpleGeo on the iOS: Getting Started Tutorial | iOS Dev Notes [...]

  4. If you want a free reverse phone search to find out about someone, use Podze (Google “podze” to see how).

  5. What is the status of SimpleGeo? The web link seems to be dead and the blog I found for them ‘simplegeo.tumblr.com’ is formatted so bad (missing CSS?) I had to pull it into a text editor to be able to read it. The last update in Git seems to be pretty old. Were they bought out or something? Where can we find about licensing, etc.

    Dbowser

    27 Feb 13 at 4:08 pm

  6. SimpleGeo was bought by Urban Airship late in 2011, and seems to have effectively shut it down. It’s unfortunate, as it was a great service. I don’t know of any similar alternatives at the moment. Good luck

    rtwomey

    27 Feb 13 at 4:18 pm

Leave a Reply