Skip to content

Instantly share code, notes, and snippets.

@marcweil
Created February 27, 2012 04:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcweil/1921508 to your computer and use it in GitHub Desktop.
Save marcweil/1921508 to your computer and use it in GitHub Desktop.
CloudMine and Urban Airship Integration
#import <CloudMine/CloudMine.h>
@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) CMStore *store;
@end
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// DTDeviceToken is a simple class that wraps an NSString that represents the device's push token and is
// serializable by CloudMine. Take a look at the complete app on GitHub to see its implementation.
DTDeviceToken *token = [[DTDeviceToken alloc] initWithTokenData:deviceToken];
// Request all the objects of type DTDeviceToken from CloudMine.
[store allObjectsOfType:[DTDeviceToken class] additionalOptions:nil callback:^(NSArray *objects, NSDictionary *errors) {
// Check to see if this device's token is in the list of registered tokens.
NSUInteger tokenIdx = [objects indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [token.token isEqualToString:[obj token]];
}];
// If this device's token isn't found in the list of registered tokens, register it.
if (tokenIdx == NSNotFound) {
[self registerDeviceToken:token];
}
}];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ... initialization code ...
// Initialize the CloudMine iOS library.
[[CMAPICredentials sharedInstance] setAppIdentifier:@"83e145d117db4aef9c399808c54e1672"];
[[CMAPICredentials sharedInstance] setAppSecret:@"6ce718b3781c47c79373aee39816e560"];
// Initialize the CMStore for storing the device's push token (defined in the MyAppDelegate header above).
if (!store) {
store = [CMStore store];
}
// Register with iOS for push notifications with sounds and visual alerts.
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
// ... more initialization code ...
}
- (void)locationUpdated:(NSNotification *)notification {
NSDictionary *userInfo = [notification.userInfo objectForKey:@"aps"];
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake([[userInfo objectForKey:@"lat"] floatValue], [[userInfo objectForKey:@"lon"] floatValue]);
// ... more code for dealing with MKMapView and MKAnnotations ...
}
// These are the keys Urban Airship provides for the app. Using your master key here is safe as this code will
// never be transmitted outside our secure infrastructure.
var uaAppKey = "myappkey";
var uaAppMaster = "myappMaster";
// See http://urbanairship.com/docs/push.html#push for the full Urban Airship docs on sending
// push notifications.
var uaUrl = "https://go.urbanairship.com/api/push/";
// This is the new location of the sensitive device as reported.
var location = data.input.curr_loc;
// This payload is defined by Urban Airship and Apple. We are just following instructions. :)
var payload = {
"aps": {
"alert": "Movement alert!",
"sound": "default",
"lat": ""+location.lat, // Notice the use of the "lat" and "lon" keys here, which correspond
"lon": ""+location.lon // to the keys used in the Objective-C code when interacting with the notification.
},
"device_tokens": [] // This will be filled with all the device tokens that will get the push.
};
// Initialize the CloudMine library with the App ID and Secret.
cloudmine.init({
app_id: "83e145d117db4aef9c399808c54e1672",
api_key: "6ce718b3781c47c79373aee39816e560"
});
// We store the upper-left and lower-right coordinates of the rectangular geo-fence as defined
// by the user via an admin interface (not shown in this demo). We must compute whether the location stored in
// the 'location' variable (defined above) is inside or outside of this region. We use the CloudMine Javascript library
// to access this data, which has the key "bounds".
cloudmine.getValues(["bounds"], function(data) {
var bounds = data.bounds;
var upperLeft = bounds.ul;
var lowerRight = bounds.lr;
if (location.lon > upperLeft.lon &&
location.lon < lowerRight.lon &&
location.lat < upperLeft.lat &&
location.lat > lowerRight.lat) {
// Location is INSIDE the boundaries of the geo-fence, so just exit.
exit('inside');
} else {
// Location is OUTISDE the boundaries of the geo-fence, so push!
// Find all the registered device tokens in CloudMine
// and make sure the push notification goes to all of them.
cloudmine.search('[__class__ = "DTDeviceToken"]', function(objects) {
objects = objects.success;
for (var key in objects) {
payload.device_tokens.push(objects[key].token);
}
// Push to Urban Airship!
restler.post(uaUrl, {
username: uaAppKey,
password: uaAppMaster,
data: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' }
}).on('complete', function(data, response) {
exit(response);
});
});
}
});
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[[NSNotificationCenter defaultCenter] postNotificationName:@"LocationUpdated" object:self userInfo:userInfo];
}
// These are the keys Urban Airship provides for the app. Using your master key here is safe as this code will
// never be transmitted outside our secure infrastructure.
var uaAppKey = "myappkey";
var uaAppMaster = "myappMaster";
// If you refer to the Objective-C code for registerDevice:, you'll see where this device_token
// parameter is created.
var deviceToken = data.params.device_token;
// See http://urbanairship.com/docs/push.html#registration for UA's reference on registering
// your users' devices for push.
var uaUrl = "https://go.urbanairship.com/api/device_tokens/"+deviceToken;
// This is where the magic happens. We send an HTTP PUT request to UA (as per their documentation) that
// causes the device to be registered.
restler.put(uaUrl, {
username: uaAppKey,
password: uaAppMaster,
data: "{}",
headers: { 'Content-Type': 'application/json' }
}).on('complete', function(data, response) {
exit(response);
});
- (void)registerDeviceToken:(DTDeviceToken *)token {
// These options let you specify additional actions to take during a CloudMine operation. In this case,
// we are specifying a server-side function to run along with the token as a parameter.
CMStoreOptions *storeOptions = [[CMStoreOptions alloc] initWithServerSideFunction:
[CMServerFunction serverFunctionWithName:@"registerDevice"
extraParameters:[NSDictionary dictionaryWithObject:token.token
forKey:@"device_token"]
responseContainsResultOnly:YES]];
// Here we use the CMStore from earlier to save the token and, using the CMStoreOptions created above,
// we trigger the server-side function we defined earlier to actually register the token with Urban Airship.
[store saveObject:token additionalOptions:storeOptions callback:^(NSDictionary *uploadStatuses) {
if (store.lastError) {
NSLog(@"Ruh roh! There was an error. %@", [store.lastError description]);
} else {
NSLog(@"Token registered successfully");
}
}];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment