Making an iOS HTML5/Javascript app with Geolocation Still Work in the Background

It’s great that HTML5/Javascript is an option for making apps on the iPhone and most every other mobile device today, but you quickly run into limitations if you want to do anything that uses the users current location information (for instance) even if they aren’t looking at your application.  Apple doesn’t allow the Jscript to continue to run in the background even if your app is setup as a geolocation app and is running in the background. I developed a little trick for this by wrapping an HTML5 page (hosted, but would also probably work if not) in a native iOS objective-c app.  I tried to keep it very minimal (we use Facebook for authentication, so there is some extra stuff in there), but for the most part, here’s how to make the minimal wrapper:

1)  Make your AppDelegate a CLLocationManagerDelegate.  I’ve included some private members to illustrate the type of app we’re creating.

@interface AppDelegate : NSObject <UIApplicationDelegate,UIAlertViewDelegate,
CLLocationManagerDelegate>{
    CLLocationDegrees lat;
    CLLocationDegrees lon;
    NSURLConnection* urlConnection;
    NSURLConnection* urlLoginConnection;
    NSMutableData* receivedData;
    CLLocationManager *locationManager;
    CLLocation *lastUpdateLocation;
}
@property (strong, nonatomic) UINavigationController* navController;
@property (strong, nonatomic) MainViewController *mainViewController;
@property (nonatomic) bool isAppInBackGround;
@property (nonatomic) bool didNotifyUserOfNewInfo;
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) NSString *auth_token
2) Create a very minimal MainViewController to hold the UIWebView
@interface MainViewController : UIViewController{
}
@property (weak, nonatomic) IBOutlet UIWebView *webView;
3) In your AppDelegate, implement the didUpdateToLocation callback:
– (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
        if ([lastUpdateLocation distanceFromLocation:newLocation] > 1000 || isAppInBackGround == true){ //just for test the background
            lastUpdateLocation = newLocation;
    //do restful find call…if has data…tell about it via local notifications, your RESTful call can update your server if you need it, or just get new things based on location
           [self getNewStuff:newLocation.coordinate.latitude :newLocation.coordinate.longitude];
            }else{
          // Do whatever is normal when the app isn’t in the background, like show the view with the webpage in it…
[[self mainViewController] showWebPage];
    }
}
This all assumes you’ve setup the app for being a geolocation app and have implemented a basis API on the server that returns objects you know how to handle.  The goal is to make sure that if there are new objects when the webpage Javascript polling isn’t taking place, then you can still alert the user and when the app opens, the Javascript polling takes over.
Advertisements

Jason is an technical business professional who has deep hands-on technical experience as a software engineer and architect and has leveraged this experience to transition from project leadership into product management. He holds a MS in Computer Science from Northeastern University and an MBA from Babson College. He is continuously striving to learn and experience new challenges.

Tagged with: , , ,
Posted in Software Development
One comment on “Making an iOS HTML5/Javascript app with Geolocation Still Work in the Background

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: