Skip to content

Instantly share code, notes, and snippets.

@ericktai
Created February 19, 2013 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ericktai/4990052 to your computer and use it in GitHub Desktop.
Save ericktai/4990052 to your computer and use it in GitHub Desktop.
StackMob ios geolocation

Just want the full project? Download Source Code

Objective

Query and return all objects based on their distance from a specified GeoPoint.

Experience Level

Beginner

Estimated time to complete

~5 minutes

Prerequisites

Let's get started!

Configure XCode Project

Open the StackMob Geo Location App

We’ll use the project from the Saving Geo Location Data Tutorial where we added geo location objects to our datastore. It has StackMob imported, Core Data and a GeoPoint field defined for us. This allows you to focus on the objective of this tutorial.

For more information on what's inside of the Geo Location app, see Saving Geo Location Data Tutorial.

If you haven't already, download the Geo Location App from the link under Prerequisites above.

Unzip and open geo-location.xcodeproj.

Add your Public Key

Go to Manage App Info in the StackMob Dashboard and copy the **Development Public Key** and paste it into the **AppDelegate.m** file where is says **YOUR\_PUBLIC\_KEY** in the method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    self.client = [[SMClient alloc] initWithAPIVersion:@"0" publicKey:@"YOUR_PUBLIC_KEY"];
    self.coreDataStore = [self.client coreDataStoreWithManagedObjectModel:self.managedObjectModel];
    return YES;
}

Add Geo Query Button

Select the storyboard file and drag and drop a bar button item to your toolbar. Set the label of the toolbar button as Within 10 miles.



Hold down the Option key and click on ViewController.h (the ViewController.h file will open next to your storyboard.)

To ensure you select the button inside the toolbar, open the Document Outline (you can do so by selecting Editor > Show Document Outline). Hold the Control key and click on the Bar button item - Within 10 miles and drag to your ViewController.h file.


In the menu, set the Connection to **Action** and enter the name **geoQuery**.

Open ViewController.h

Your ViewController.h file should look like the following:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface ViewController : UIViewController <MKMapViewDelegate> 

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (weak, nonatomic) IBOutlet MKMapView *mapView;

- (IBAction)saveLocation:(id)sender;
- (IBAction)geoQuery:(id)sender;

@end

Open ViewController.m

Add the following highlighted code to your ViewController.m file. We create a special SMPredicate to perform geo-queries.

#import "ViewController.h"
#import "AppDelegate.h"
/*
 Import the StackMob header file.
 */
#import "StackMob.h"
/*
 Import the StackMob header file.
 */
 #import "Todo.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize managedObjectContext = _managedObjectContext;

- (AppDelegate *)appDelegate {
    return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    /*
     Set the mapView delegate.
     */
    _mapView.delegate = self;
    
    self.managedObjectContext = [[self.appDelegate coreDataStore] contextForCurrentThread];
}

- (void)viewDidUnload
{
    [self setMapView:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)saveLocation:(id)sender {
     /*
     Get the current latitude and longitude in an SMGeoPoint.
     */
    [SMGeoPoint getGeoPointForCurrentLocationOnSuccess:^(SMGeoPoint *geoPoint) {
        
        Todo *todo = [NSEntityDescription insertNewObjectForEntityForName:@"Todo" inManagedObjectContext:self.managedObjectContext];
        todo.todoId = [todo assignObjectId];
        todo.title = @"My Location";
        todo.location = [NSKeyedArchiver archivedDataWithRootObject:geoPoint];
        
        /*
         Save the location to StackMob.
         */
        [self.managedObjectContext saveOnSuccess:^{
            NSLog(@"Created new object in Todo schema");
        } onFailure:^(NSError *error) {
            NSLog(@"Error creating object: %@", error);
        }];
        
    } onFailure:^(NSError *error) {
        NSLog(@"Error getting SMGeoPoint: %@", error);
    }];
}

- (IBAction)geoQuery:(id)sender {
    
    /*
     Get the current location.
     */
    [SMGeoPoint getGeoPointForCurrentLocationOnSuccess:^(SMGeoPoint *geoPoint) {
        
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo" inManagedObjectContext:self.managedObjectContext];
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setEntity:entity];
        
        /*
         Set a predicate with an SMGeoPoint
         */
        SMPredicate *predicate = [SMPredicate predicateWhere:@"location" isWithin:10 milesOfGeoPoint:geoPoint];
        [fetchRequest setPredicate:predicate];
        
        [self.managedObjectContext executeFetchRequest:fetchRequest onSuccess:^(NSArray *results) {
            NSLog(@"Successful query %@", results);
        } onFailure:^(NSError *error) {
            NSLog(@"Error: %@", error);
        }];
        
    } onFailure:^(NSError *error) {
        NSLog(@"Error getting SMGeoPoint: %@", error);
    }]; 
}
@end

Build and Run!

Run your project.

If you're working with the simulator, simulate a location in the bottom pane of Xcode.



Allow the app to use your current location and click the save location button. Now, click the within 10 miles button to query the results.

Watch the debug output for a response from StackMob.

Other types of queries

You can also perform other types of geo queries. Check out the SMPredicate class for more information.

Congratulations on completing this tutorial!

Download Source Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment