diff --git a/plugin.xml b/plugin.xml index 5de95e0..856f89d 100755 --- a/plugin.xml +++ b/plugin.xml @@ -15,6 +15,8 @@ + + @@ -54,6 +56,11 @@ + + + remote-notification + + diff --git a/src/ios/AppDelegate+notification.m b/src/ios/AppDelegate+notification.m index 7a1a6fd..62ebfd3 100644 --- a/src/ios/AppDelegate+notification.m +++ b/src/ios/AppDelegate+notification.m @@ -52,8 +52,7 @@ - (AppDelegate *)swizzled_init // to process notifications in cold-start situations - (void)createNotificationChecker:(NSNotification *)notification { - if (notification) - { + if (notification) { NSDictionary *launchOptions = [notification userInfo]; if (launchOptions) self.launchNotification = [launchOptions objectForKey: @"UIApplicationLaunchOptionsRemoteNotificationKey"]; @@ -92,6 +91,17 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N } } +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler { + // if the user clicked the notification, we know that the callback has already been called, so we simply return. + if (application.applicationState == UIApplicationStateInactive) { + return; + } + + PushPlugin *pushHandler = [self getCommandInstance:@"PushPlugin"]; + [pushHandler backgroundFetch:completionHandler userInfo:userInfo]; +} + + - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"active"); diff --git a/src/ios/PushPlugin.h b/src/ios/PushPlugin.h index 728bea9..7cfb197 100644 --- a/src/ios/PushPlugin.h +++ b/src/ios/PushPlugin.h @@ -28,6 +28,8 @@ @property(nonatomic, strong) NSDictionary *notificationMessage; @property BOOL isInline; +@property(nonatomic, strong) NSMutableArray *completionHandlers; + - (void)register:(CDVInvokedUrlCommand *)command; - (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; @@ -38,4 +40,7 @@ - (void)notificationReceived; +- (void)setContentAvailable:(CDVInvokedUrlCommand *)command; + +- (void)backgroundFetch:(void (^)(UIBackgroundFetchResult))handler userInfo:(NSDictionary *)userInfo; @end diff --git a/src/ios/PushPlugin.m b/src/ios/PushPlugin.m index b09336b..5622e7b 100644 --- a/src/ios/PushPlugin.m +++ b/src/ios/PushPlugin.m @@ -100,6 +100,27 @@ - (void)notificationReceived { } } +- (void)setContentAvailable:(CDVInvokedUrlCommand*)command { + NSLog(@"setContentAvailable"); + if ([self.completionHandlers count]) { + NSMutableDictionary *options = [command.arguments objectAtIndex:0]; + NSString *type = [options objectForKey:@"type"]; + void (^handler)(UIBackgroundFetchResult) = [self.completionHandlers objectAtIndex:0]; + handler((UIBackgroundFetchResult) [type intValue]); + [self.completionHandlers removeObject:handler]; + } +} + +- (void)backgroundFetch:(void (^)(UIBackgroundFetchResult))handler userInfo:(NSDictionary *)userInfo { + NSLog(@"Background Fetch"); + if (!self.completionHandlers) { + self.completionHandlers = [[NSMutableArray alloc] init]; + } + [self.completionHandlers addObject:handler]; + self.notificationMessage = userInfo; + [self notificationReceived]; +} + - (void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command; { DLog(@"setApplicationIconBadgeNumber:%@\n withDict:%@", arguments, options); diff --git a/www/aerogear-push.js b/www/aerogear-push.js index 96cfe3d..66f49ae 100644 --- a/www/aerogear-push.js +++ b/www/aerogear-push.js @@ -20,8 +20,14 @@ var exec = require("cordova/exec"); * This is a global variable called push exposed by cordova * @status Stable * @constructs Push - */ -var Push = function(){}; + */ +function Push(){ + this.FetchResult = { + NewData: 0, + NoData: 1, + Failed: 2 + } +} /** Registers the device with the APNS (iOS) or GCM (Android) and the Unified Push server. @@ -133,4 +139,18 @@ Push.prototype.setApplicationIconBadgeNumber = function (successCallback, badge) ]); }; -module.exports = new Push(); +/** + * Call this function to tell the OS if there was data or not so it can schedule the next fetch operation + * @param {int} dataType - one of the BackgroundFetchResults or 0 new data 1 no data or 2 failed + * @returns {void} + */ +Push.prototype.setContentAvailable = function(dataType) { + return exec(null, null, "PushPlugin", "setContentAvailable", [{type: dataType}]); +}; + +var push = new Push(); +if (Object.freeze) { + Object.freeze(push.FetchResult); +} + +module.exports = push;