Geo-Fencing with CloudMine and Urban Airship

marcweil

Many mobile apps need to be able to send push notifications intelligently to their users. In order to send these, we must be able to determine when and to whom the notifications are sent, as well as the content of those notifications. It is important that users are able to receive these pushes regardless of whether or not the mobile app is open; hence, the need for the server.

Urban Airship does a great job of simplifying both the process of registering your users’ devices for push notifications and the procedure for sending them. They have a simple REST API for interacting with their services, and they play well with CloudMine’s JavaScript-based server-side code execution service. In this post, we’ll explore a sample app we wrote that simply sends a notification to registered devices when another device moves outside of a specific geo-fenced region. This app is written for the iPhone in Objective-C, but the same concepts apply to Android and Windows Phone 7. There isn’t any overly complicated code here, so you should be able to follow along even if you aren’t familiar with Objective-C.

Dessert First

Before we dive into the code, let’s see what the finished app looks like.

final screenshot

Imagine that you have a phone or tablet containing some sensitive data, and you would like to be sent an alert if it leaves a secure area (represented by a geo-fence). The screenshot above shows the app that notifies you when the device leaves the secure area. Each time the secure device checks in, the pin is moved to the new location.

The iPhone App

It’s coding time. Let’s begin at the beginning of the app’s lifecycle, in the application delegate. As soon as the app is launched we want to initialize the CloudMine iOS library with the app’s secret and ID. We also need to initialize a CMStore (which is where we’ll be storing the device’s push token). Finally, we need to request permission from iOS and the end user to receive push notifications.

This is the header file for the MyAppDelegate class, which implements the protocol required for registering as an application delegate.

This is the initialization method called by iOS immediately after the app is launched. I’ve removed all the code that doesn’t pertain to the three tasks listed above, but if you’d like to see the rest of it, you can clone the app from its GitHub repository.

All we’ve done at this point is perform some simple initialization and register with the system for push notifications.

After getting authorization from the end-user to receive and display push notifications, iOS will automatically call application:didRegisterForRemoteNotificationsWithDeviceToken: on the application delegate. In this method, we check CloudMine to see if we’ve registered this device already. If not, we register it with CloudMine (which then registers the phone with Urban Airship, as we’ll see later).

There’s just one missing piece left in the application delegate: the implementation of registerDeviceToken:.

This method takes the DTDeviceToken instance containing the device’s push token, saves it to CloudMine, and triggers the server-side code snippet (named registerDevice) that actually registers the device with Urban Airship.

On the JavaScript side of things, the snippet to register the device with Urban Airship is short and sweet.

The comments in the JavaScript explain what’s going on. The gist of it is that we make a PUT request to Urban Airship and send along the user’s device token. This is needed for sending push notifications. Remember that the device token was sent up to CloudMine for processing from the registerDeviceToken: method above.

When the app receives a push notification, it triggers an internal notification so the view controller (which holds the map view) knows to update its location.

The remainder of the iPhone app consists of a Google map view (using Apple’s MKMapView), as well as the mechanisms necessary to notify the map view when to update the location of the pin. Most of that code is outside the scope of this post, but it’s important to see how the coordinates of the new location are processed.

This code is located in DTViewController and is triggered when the app delegate receives a push notification. The important thing to note is the use of the keys lat and lon to access the new latitude and longitude of the sensitive device.

The Push Trigger

Now that we’ve seen how the iOS app is notified of changes in the location of the sensitive device, let’s take a look at how the push notification is actually sent. There is an app running on the sensitive device that periodically reports its location to CloudMine and calls the pushLocation code snippet (see below). This snippet detects whether the new location is inside or outside the geo-fenced area previously defined, and if it’s outside the fence it triggers the push notification to all devices registered to receive it.

Take a moment to re-read lines 54 to 58 in the gist above. What you see here is a contrived example (performing a simple search for other objects in CloudMine), but imagine the possibilities. You can decide which devices or users to notify based on their location/proximity, friendship status, or time of day. In fact, use whatever logic you need for your app, because it’s just code! You can even call out to third party services, giving you the power to easily implement notifications in a way that’s right for you. The possibilities are endless.

Fin

That’s it! Not too difficult, right? If you want to try the app for yourself, you’ll need to sign up for a CloudMine and Urban Airship account so you have the proper keys. You’ll also have to run the app on an iPhone or iPad since Apple’s simulator doesn’t allow push notifications. Here are the important links:

The perceptive reader may notice that many of the Objective-C code samples include what appears to be a CloudMine iOS library, and you are absolutely correct! Our native iOS library’s release is imminent, and once we finish putting together screencasts, docs, and tutorials for you there will be an official announcement. Stay tuned!

Please leave questions in the section below, or feel free to contact us directly at team@cloudmine.me.

twitter.com/cloudmine



About Us