Commit cac11bc1 by Sebastián Katzer

Schedule notifications with support for custom intervals on iOS

parent ca85d768
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
<header-file src="src/ios/APPLocalNotification.h" /> <header-file src="src/ios/APPLocalNotification.h" />
<source-file src="src/ios/APPLocalNotification.m" /> <source-file src="src/ios/APPLocalNotification.m" />
<!-- <header-file src="src/ios/APPLocalNotificationOptions.h" /> <header-file src="src/ios/APPLocalNotificationOptions.h" />
<source-file src="src/ios/APPLocalNotificationOptions.m" /> <source-file src="src/ios/APPLocalNotificationOptions.m" />
<header-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.h" /> <header-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.h" />
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
<source-file src="src/ios/UNMutableNotificationContent+APPLocalNotification.m" /> <source-file src="src/ios/UNMutableNotificationContent+APPLocalNotification.m" />
<header-file src="src/ios/UNNotificationRequest+APPLocalNotification.h" /> <header-file src="src/ios/UNNotificationRequest+APPLocalNotification.h" />
<source-file src="src/ios/UNNotificationRequest+APPLocalNotification.m" /> --> <source-file src="src/ios/UNNotificationRequest+APPLocalNotification.m" />
</platform> </platform>
......
...@@ -35,8 +35,8 @@ ...@@ -35,8 +35,8 @@
// Request permission to show notifications // Request permission to show notifications
- (void) request:(CDVInvokedUrlCommand*)command; - (void) request:(CDVInvokedUrlCommand*)command;
//// Schedule set of notifications // Schedule notifications
//- (void) schedule:(CDVInvokedUrlCommand*)command; - (void) schedule:(CDVInvokedUrlCommand*)command;
//// Update set of notifications //// Update set of notifications
//- (void) update:(CDVInvokedUrlCommand*)command; //- (void) update:(CDVInvokedUrlCommand*)command;
//// Cancel set of notifications //// Cancel set of notifications
......
...@@ -22,25 +22,18 @@ ...@@ -22,25 +22,18 @@
*/ */
#import "APPLocalNotification.h" #import "APPLocalNotification.h"
//#import "APPLocalNotificationOptions.h" #import "APPLocalNotificationOptions.h"
//#import "UNUserNotificationCenter+APPLocalNotification.h" #import "UNUserNotificationCenter+APPLocalNotification.h"
//#import "UNNotificationRequest+APPLocalNotification.h" #import "UNNotificationRequest+APPLocalNotification.h"
//#import "UNMutableNotificationContent+APPLocalNotification.h" #import "UNMutableNotificationContent+APPLocalNotification.h"
@interface APPLocalNotification () @interface APPLocalNotification ()
// Property reader for [self app] @property (strong, nonatomic) UIApplication* app;
@property (readonly, getter=app) UIApplication* app; @property (strong, nonatomic) UNUserNotificationCenter* center;
// Property reader for [self center]
@property (readonly, getter=center) UNUserNotificationCenter* center;
// All events will be queued until deviceready has been fired
@property (readwrite, assign) BOOL deviceready; @property (readwrite, assign) BOOL deviceready;
// Event queue
@property (readonly, nonatomic, retain) NSMutableArray* eventQueue; @property (readonly, nonatomic, retain) NSMutableArray* eventQueue;
// IOS9: TODO remove later
@property (nonatomic, retain) CDVInvokedUrlCommand* command;
@end @end
@implementation APPLocalNotification @implementation APPLocalNotification
...@@ -52,6 +45,8 @@ ...@@ -52,6 +45,8 @@
/** /**
* Execute all queued events. * Execute all queued events.
*
* @return [ Void ]
*/ */
- (void) deviceready:(CDVInvokedUrlCommand*)command - (void) deviceready:(CDVInvokedUrlCommand*)command
{ {
...@@ -63,48 +58,32 @@ ...@@ -63,48 +58,32 @@
[eventQueue removeAllObjects]; [eventQueue removeAllObjects];
} }
//
///** /**
// * Schedule a set of notifications. * Schedule notifications.
// * *
// * @param properties * @param [Array<Hash>] properties A list of key-value properties.
// * A dict of properties for each notification *
// */ * @return [ Void ]
//- (void) schedule:(CDVInvokedUrlCommand*)command */
//{ - (void) schedule:(CDVInvokedUrlCommand*)command
// NSArray* notifications = command.arguments; {
// NSArray* notifications = command.arguments;
// [self.commandDelegate runInBackground:^{
// if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) { [self.commandDelegate runInBackground:^{
// for (NSDictionary* options in notifications) { for (NSDictionary* options in notifications) {
// UNMutableNotificationContent* notification; UNMutableNotificationContent* notification;
//
// notification = [[UNMutableNotificationContent alloc] notification = [[UNMutableNotificationContent alloc]
// initWithOptions:options]; initWithOptions:options];
//
// [self scheduleNotification:notification]; [self scheduleNotification:notification];
// //[self fireEvent:@"add" notification:notification]; }
// }
// } else { [self execCallback:command];
// for (NSDictionary* options in notifications) { }];
// UILocalNotification* notification; }
//
// notification = [[UILocalNotification alloc]
// initWithOptions:options];
//
// [self scheduleLocalNotification:[notification copy]];
// [self fireEvent:@"schedule" localnotification:notification];
//
// if (notifications.count > 1) {
// [NSThread sleepForTimeInterval:0.01];
// }
// }
// }
//
// [self execCallback:command];
// }];
//}
//
///** ///**
// * Update a set of notifications. // * Update a set of notifications.
// * // *
...@@ -535,7 +514,7 @@ ...@@ -535,7 +514,7 @@
*/ */
- (void) check:(CDVInvokedUrlCommand*)command - (void) check:(CDVInvokedUrlCommand*)command
{ {
[self.center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* settings) { [_center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* settings) {
BOOL authorized = settings.authorizationStatus == UNAuthorizationStatusAuthorized; BOOL authorized = settings.authorizationStatus == UNAuthorizationStatusAuthorized;
BOOL enabled = settings.notificationCenterSetting == UNNotificationSettingEnabled; BOOL enabled = settings.notificationCenterSetting == UNNotificationSettingEnabled;
BOOL permitted = authorized && enabled; BOOL permitted = authorized && enabled;
...@@ -563,19 +542,22 @@ ...@@ -563,19 +542,22 @@
} }
#pragma mark - #pragma mark -
#pragma mark Core Logic #pragma mark Private
/**
* Schedule the local notification.
*/
- (void) scheduleNotification:(UNMutableNotificationContent*)notification
{
__weak APPLocalNotification* weakSelf = self;
UNNotificationRequest* request = notification.request;
[_center addNotificationRequest:request withCompletionHandler:^(NSError* e) {
__strong APPLocalNotification* strongSelf = weakSelf;
[strongSelf fireEvent:@"add" notification:request];
}];
}
///**
// * Schedule the local notification.
// */
//- (void) scheduleNotification:(UNMutableNotificationContent*)notification
//{
// [self.center addNotificationRequest:notification.request
// withCompletionHandler:^(NSError* e) {
// [self fireEvent:@"add" notification:notification.request];
// }];
//}
//
///** ///**
// * Update the local notification. // * Update the local notification.
// */ // */
...@@ -620,44 +602,43 @@ ...@@ -620,44 +602,43 @@
// //
// [self.app setApplicationIconBadgeNumber:0]; // [self.app setApplicationIconBadgeNumber:0];
//} //}
//
//#pragma mark - #pragma mark -
//#pragma mark Delegates #pragma mark UNUserNotificationCenterDelegate
//
///** /**
// * Called when a notification is delivered to a foreground app. * Called when a notification is delivered to the app while being in foreground.
// */ */
//- (void) userNotificationCenter:(UNUserNotificationCenter *)center - (void) userNotificationCenter:(UNUserNotificationCenter *)center
// willPresentNotification:(UNNotification *)notification willPresentNotification:(UNNotification *)notification
// withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
//{ {
// [self fireEvent:@"trigger" notification:notification.request]; [self fireEvent:@"trigger" notification:notification.request];
// completionHandler(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert); completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);
//} }
//
// /**
///** * Called to let your app know which action was selected by the user for a given
// * Called to let your app know which action was selected by the user for a given * notification.
// * notification. */
// */ - (void) userNotificationCenter:(UNUserNotificationCenter *)center
//- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response
// didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
// withCompletionHandler:(void (^)())completionHandler {
//{ UNNotificationRequest* notification = response.notification.request;
// UNNotificationRequest* notification = response.notification.request;
// [self fireEvent:@"click" notification:notification];
// [self fireEvent:@"click" notification:notification];
//
// if ([notification.options isRepeating]) { // if ([notification.options isRepeating]) {
// [self.center clearNotification:notification]; // [_center clearNotification:notification];
// [self fireEvent:@"clear" notification:notification]; // [self fireEvent:@"clear" notification:notification];
// } else { // } else {
// [self.center cancelNotification:notification]; // [_center cancelNotification:notification];
// [self fireEvent:@"cancel" notification:notification]; // [self fireEvent:@"cancel" notification:notification];
// } // }
//
// completionHandler(); completionHandler();
//} }
#pragma mark - #pragma mark -
#pragma mark Life Cycle #pragma mark Life Cycle
...@@ -668,249 +649,73 @@ ...@@ -668,249 +649,73 @@
- (void) pluginInitialize - (void) pluginInitialize
{ {
eventQueue = [[NSMutableArray alloc] init]; eventQueue = [[NSMutableArray alloc] init];
_app = [UIApplication sharedApplication];
_center = [UNUserNotificationCenter currentNotificationCenter];
self.center.delegate = self; _center.delegate = self;
} }
#pragma mark - #pragma mark -
#pragma mark Helper #pragma mark Helper
///** /**
// * Retrieves the application state * Retrieve the state of the application.
// * *
// * @return * @return "background" or "foreground"
// * Either "background" or "foreground" */
// */ - (NSString*) applicationState
//- (NSString*) applicationState {
//{ UIApplicationState state = [_app applicationState];
// UIApplicationState state = [self.app applicationState];
// bool isActive = state == UIApplicationStateActive;
// bool isActive = state == UIApplicationStateActive;
// return isActive ? @"foreground" : @"background";
// return isActive ? @"foreground" : @"background"; }
//}
//
///**
// * Simply invokes the callback without any parameter.
// */
//- (void) execCallback:(CDVInvokedUrlCommand*)command
//{
// CDVPluginResult *result = [CDVPluginResult
// resultWithStatus:CDVCommandStatus_OK];
//
// [self.commandDelegate sendPluginResult:result
// callbackId:command.callbackId];
//}
//
///**
// * Short hand for shared application instance.
// */
//- (UIApplication*) app
//{
// return [UIApplication sharedApplication];
//}
/** /**
* Short hand for current notification center. * Simply invokes the callback without any parameter.
*/ */
- (UNUserNotificationCenter*) center - (void) execCallback:(CDVInvokedUrlCommand*)command
{ {
return [UNUserNotificationCenter currentNotificationCenter]; CDVPluginResult *result = [CDVPluginResult
resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:result
callbackId:command.callbackId];
} }
///** /**
// * Fire general event. * Fire general event.
// */ */
//- (void) fireEvent:(NSString*)event - (void) fireEvent:(NSString*)event
//{ {
// [self fireEvent:event notification:NULL]; [self fireEvent:event notification:NULL];
//} }
//
///** /**
// * Fire event for local notification. * Fire event for local notification.
// */ */
//- (void) fireEvent:(NSString*)event - (void) fireEvent:(NSString*)event
// notification:(UNNotificationRequest*)notification notification:(UNNotificationRequest*)notification
//{ {
// NSString* js; NSString* js;
// NSString* appState = [self applicationState]; NSString* appState = [self applicationState];
// NSString* params = [NSString stringWithFormat:@"\"%@\"", appState]; NSString* params = [NSString stringWithFormat:@"\"%@\"", appState];
//
// if (notification) { if (notification) {
// NSString* args = [notification encodeToJSON]; NSString* args = [notification encodeToJSON];
// params = [NSString stringWithFormat:@"%@,'%@'", args, appState]; params = [NSString stringWithFormat:@"%@,'%@'", args, appState];
// } }
//
// js = [NSString stringWithFormat: js = [NSString stringWithFormat:
// @"cordova.plugins.notification.local.core.fireEvent('%@', %@)", @"cordova.plugins.notification.local.core.fireEvent('%@', %@)",
// event, params]; event, params];
//
// if (deviceready) { if (deviceready) {
// [self.commandDelegate evalJs:js]; [self.commandDelegate evalJs:js];
// } else { } else {
// [self.eventQueue addObject:js]; [self.eventQueue addObject:js];
// } }
//} }
//
//#pragma mark -
//#pragma mark ios 9
//
///**
// * Schedule the local notification.
// */
//- (void) scheduleLocalNotification:(UILocalNotification*)notification
//{
// [self cancelForerunnerLocalNotification:notification];
// [self.app scheduleLocalNotification:notification];
//}
//
///**
// * Update the local notification.
// */
//- (void) updateLocalNotification:(UILocalNotification*)notification
// withOptions:(NSDictionary*)newOptions
//{
// NSMutableDictionary* options = [notification.userInfo mutableCopy];
//
// [options addEntriesFromDictionary:newOptions];
// [options setObject:[NSDate date] forKey:@"updatedAt"];
//
// notification = [[UILocalNotification alloc]
// initWithOptions:options];
//
// [self scheduleLocalNotification:notification];
//}
//
///**
// * Cancel a maybe given forerunner with the same ID.
// */
//- (void) cancelForerunnerLocalNotification:(UILocalNotification*)notification
//{
// NSNumber* id = notification.options.id;
// UILocalNotification* forerunner;
//
// forerunner = [self.app localNotificationWithId:id];
//
// if (!forerunner)
// return;
//
// [self.app cancelLocalNotification:forerunner];
//}
//
///**
// * Cancels all non-repeating local notification older then
// * a specific amount of seconds
// */
//- (void) cancelAllNotificationsWhichAreOlderThen:(float)seconds
//{
// NSArray* notifications;
//
// notifications = [self.app localNotifications];
//
// for (UILocalNotification* notification in notifications)
// {
// if (![notification isRepeating]
// && notification.timeIntervalSinceFireDate > seconds)
// {
// [self.app cancelLocalNotification:notification];
// [self fireEvent:@"cancel" localnotification:notification];
// }
// }
//}
//
///**
// * Calls the cancel or trigger event after a local notification was received.
// * Cancels the local notification if autoCancel was set to true.
// */
//- (void) didReceiveLocalNotification:(NSNotification*)localNotification
//{
// UILocalNotification* notification = [localNotification object];
//
// if ([notification userInfo] == NULL || [notification wasUpdated])
// return;
//
// NSTimeInterval timeInterval = [notification timeIntervalSinceLastTrigger];
// NSString* event = timeInterval < 0.2 && deviceready ? @"trigger" : @"click";
//
// [self fireEvent:event localnotification:notification];
//
// if (![event isEqualToString:@"click"])
// return;
//
// if ([notification isRepeating]) {
// [self fireEvent:@"clear" localnotification:notification];
// } else {
// [self.app cancelLocalNotification:notification];
// [self fireEvent:@"cancel" localnotification:notification];
// }
//}
//
///**
// * Called when app has started
// * (by clicking on a local notification).
// */
//- (void) didFinishLaunchingWithOptions:(NSNotification*)notification
//{
// NSDictionary* launchOptions = [notification userInfo];
//
// UILocalNotification* localNotification;
//
// localNotification = [launchOptions objectForKey:
// UIApplicationLaunchOptionsLocalNotificationKey];
//
// if (localNotification) {
// [self didReceiveLocalNotification:
// [NSNotification notificationWithName:CDVLocalNotification
// object:localNotification]];
// }
//}
//
///**
// * Called on notification settings registration is completed.
// */
//- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings
//{
// if (_command) {
// [self hasPermission:_command];
// _command = NULL;
// }
//}
//
///**
// * Cancels all single non-repeating notifications which are older then 5 days
// * before the app terminates.
// */
//- (void) onAppTerminate
//{
// [self cancelAllNotificationsWhichAreOlderThen:432000];
//}
//
///**
// * Fire event for local notification.
// */
//- (void) fireEvent:(NSString*)event localnotification:(UILocalNotification*)notification
//{
// NSString* js;
// NSString* params = [NSString stringWithFormat:
// @"\"%@\"", self.applicationState];
//
// if (notification) {
// NSString* args = [notification encodeToJSON];
//
// params = [NSString stringWithFormat:
// @"%@,'%@'",
// args, self.applicationState];
// }
//
// js = [NSString stringWithFormat:
// @"cordova.plugins.notification.local.core.fireEvent('%@', %@)",
// event, params];
//
// if (deviceready) {
// [self.commandDelegate evalJs:js];
// } else {
// [self.eventQueue addObject:js];
// }
//}
@end @end
...@@ -21,27 +21,21 @@ ...@@ -21,27 +21,21 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import <UserNotifications/UNNotificationSound.h> @import UserNotifications;
#import <UserNotifications/UNNotificationRequest.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface APPLocalNotificationOptions : NSObject @interface APPLocalNotificationOptions : NSObject
- (id) initWithDict:(NSDictionary*)dict; @property (readonly, getter=id) NSNumber* id;
@property (readonly, getter=identifier) NSString* identifier;
@property (readonly, getter=id) NSNumber* id; @property (readonly, getter=title) NSString* title;
@property (readonly, getter=identifier) NSString* identifier; @property (readonly, getter=subtitle) NSString* subtitle;
@property (readonly, getter=title) NSString* title; @property (readonly, getter=badge) NSNumber* badge;
@property (readonly, getter=subtitle) NSString* subtitle; @property (readonly, getter=text) NSString* text;
@property (readonly, getter=badge) NSNumber* badge; @property (readonly, getter=sound) UNNotificationSound* sound;
@property (readonly, getter=text) NSString* text; @property (readonly, getter=userInfo) NSDictionary* userInfo;
@property (readonly, getter=sound) UNNotificationSound* sound;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// If it's a repeating notification - (id) initWithDict:(NSDictionary*)dict;
- (BOOL) isRepeating; - (BOOL) isRepeating;
// how and when to trigger the notification
- (UNNotificationTrigger*) trigger; - (UNNotificationTrigger*) trigger;
@end @end
...@@ -40,8 +40,11 @@ ...@@ -40,8 +40,11 @@
#pragma mark Initialization #pragma mark Initialization
/** /**
* Initialize the object with the given options when calling on JS side: * Initialize by using the given property values.
* notification.local.add(options) *
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ APPLocalNotificationOptions ]
*/ */
- (id) initWithDict:(NSDictionary*)dictionary - (id) initWithDict:(NSDictionary*)dictionary
{ {
...@@ -53,10 +56,12 @@ ...@@ -53,10 +56,12 @@
} }
#pragma mark - #pragma mark -
#pragma mark Attributes #pragma mark Properties
/** /**
* The notification's ID. * The ID for the notification.
*
* @return [ NSNumber* ]
*/ */
- (NSNumber*) id - (NSNumber*) id
{ {
...@@ -66,7 +71,9 @@ ...@@ -66,7 +71,9 @@
} }
/** /**
* The notification's ID as a string. * The ID for the notification.
*
* @return [ NSString* ]
*/ */
- (NSString*) identifier - (NSString*) identifier
{ {
...@@ -74,7 +81,9 @@ ...@@ -74,7 +81,9 @@
} }
/** /**
* The notification's title. * The title for the notification.
*
* @return [ NSString* ]
*/ */
- (NSString*) title - (NSString*) title
{ {
...@@ -82,7 +91,9 @@ ...@@ -82,7 +91,9 @@
} }
/** /**
* The notification's title. * The subtitle for the notification.
*
* @return [ NSString* ]
*/ */
- (NSString*) subtitle - (NSString*) subtitle
{ {
...@@ -92,7 +103,9 @@ ...@@ -92,7 +103,9 @@
} }
/** /**
* The notification's message. * The text for the notification.
*
* @return [ NSString* ]
*/ */
- (NSString*) text - (NSString*) text
{ {
...@@ -100,7 +113,9 @@ ...@@ -100,7 +113,9 @@
} }
/** /**
* The notification's badge number. * The badge number for the notification.
*
* @return [ NSNumber* ]
*/ */
- (NSNumber*) badge - (NSNumber*) badge
{ {
...@@ -108,14 +123,16 @@ ...@@ -108,14 +123,16 @@
} }
/** /**
* The notification's sound path. * The sound file for the notification.
*
* @return [ UNNotificationSound* ]
*/ */
- (UNNotificationSound*) sound - (UNNotificationSound*) sound
{ {
NSString* path = [dict objectForKey:@"sound"]; NSString* path = [dict objectForKey:@"sound"];
NSString* file; NSString* file;
if ([self stringIsNullOrEmpty:path]) if (!path.length)
return NULL; return NULL;
if ([path isEqualToString:@"res://platform_default"]) if ([path isEqualToString:@"res://platform_default"])
...@@ -132,7 +149,9 @@ ...@@ -132,7 +149,9 @@
} }
/** /**
* The notification's fire date. * The date when to fire the notification.
*
* @return [ NSDate* ]
*/ */
- (NSDate*) fireDate - (NSDate*) fireDate
{ {
...@@ -142,29 +161,41 @@ ...@@ -142,29 +161,41 @@
return [NSDate dateWithTimeIntervalSince1970:timestamp]; return [NSDate dateWithTimeIntervalSince1970:timestamp];
} }
#pragma mark -
#pragma mark Public
/** /**
* If it's a repeating notification. * If the notification shall be repeating.
*
* @return [ BOOL ]
*/ */
- (BOOL) isRepeating - (BOOL) isRepeating
{ {
NSString* interval = [dict objectForKey:@"every"]; id every = [dict objectForKey:@"every"];
return ![self stringIsNullOrEmpty:interval]; if ([every isKindOfClass:NSString.class])
} return ((NSString*) every).length > 0;
#pragma mark - return every > 0;
#pragma mark Methods }
/** /**
* Specify how and when to trigger the notification. * Specify how and when to trigger the notification.
*
* @return [ UNNotificationTrigger* ]
*/ */
- (UNNotificationTrigger*) trigger - (UNNotificationTrigger*) trigger
{ {
return [self isRepeating] ? [self triggerWithDateMatchingComponents] : [self triggerWithTimeInterval]; if ([self isRepeating])
return [self repeatingTrigger];
return [self nonRepeatingTrigger];
} }
/** /**
* The notification's user info dict. * The notification's user info dict.
*
* @return [ NSDictionary* ]
*/ */
- (NSDictionary*) userInfo - (NSDictionary*) userInfo
{ {
...@@ -183,18 +214,55 @@ ...@@ -183,18 +214,55 @@
#pragma mark Private #pragma mark Private
/** /**
* Returns a trigger based on a custom time interval in seconds. * Non repeating trigger.
*
* @return [ UNTimeIntervalNotificationTrigger* ]
*/ */
- (UNTimeIntervalNotificationTrigger*) triggerWithTimeInterval - (UNTimeIntervalNotificationTrigger*) nonRepeatingTrigger
{ {
return [UNTimeIntervalNotificationTrigger return [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:[self timeInterval] repeats:NO]; triggerWithTimeInterval:[self timeInterval] repeats:NO];
} }
/** /**
* Returns a trigger based on a calendar time. * Repeating trigger.
*
* @return [ UNNotificationTrigger* ]
*/
- (UNNotificationTrigger*) repeatingTrigger
{
id every = [dict objectForKey:@"every"];
if ([every isKindOfClass:NSString.class])
return [self repeatingTriggerWithDateMatchingComponents];
return [self repeatingTriggerWithTimeInterval];
}
/**
* A trigger based on a calendar time defined by the user.
*
* @return [ UNTimeIntervalNotificationTrigger* ]
*/
- (UNTimeIntervalNotificationTrigger*) repeatingTriggerWithTimeInterval
{
long interval = [[dict objectForKey:@"every"] longValue];
if (interval < 60) {
NSLog(@"time interval must be at least 60 if repeating");
interval = 60;
}
return [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:interval repeats:YES];
}
/**
* A repeating trigger based on a calendar time defined by the user.
*
* @return [ UNCalendarNotificationTrigger* ]
*/ */
- (UNCalendarNotificationTrigger*) triggerWithDateMatchingComponents - (UNCalendarNotificationTrigger*) repeatingTriggerWithDateMatchingComponents
{ {
NSCalendar* cal = [[NSCalendar alloc] NSCalendar* cal = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
...@@ -209,7 +277,9 @@ ...@@ -209,7 +277,9 @@
} }
/** /**
* Timeinterval between future fire date and now. * The time interval between the next fire date and now.
*
* @return [ double ]
*/ */
- (double) timeInterval - (double) timeInterval
{ {
...@@ -217,44 +287,49 @@ ...@@ -217,44 +287,49 @@
} }
/** /**
* The notification's repeat interval. * The repeat interval for the notification.
*
* @return [ NSCalendarUnit ]
*/ */
- (NSCalendarUnit) repeatInterval - (NSCalendarUnit) repeatInterval
{ {
NSString* interval = [dict objectForKey:@"every"]; NSString* interval = [dict objectForKey:@"every"];
NSCalendarUnit unitFlags = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond; NSCalendarUnit units = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
if ([self stringIsNullOrEmpty:interval]) { if (!interval.length)
return unitFlags; return units;
}
else if ([interval isEqualToString:@"second"]) { if ([interval isEqualToString:@"second"])
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay; return NSCalendarUnitNanosecond;
}
else if ([interval isEqualToString:@"minute"]) { if ([interval isEqualToString:@"minute"])
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitSecond; return NSCalendarUnitSecond;
}
else if ([interval isEqualToString:@"hour"]) { if ([interval isEqualToString:@"hour"])
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitMinute; return NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"day"]) { if ([interval isEqualToString:@"day"])
return NSCalendarUnitHour|NSCalendarUnitMinute; return NSCalendarUnitHour|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"week"]) {
return NSCalendarUnitWeekday|NSCalendarUnitHour|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"month"]) {
return NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"year"]) {
return NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute;
}
return unitFlags; if ([interval isEqualToString:@"week"])
return NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitWeekday;
if ([interval isEqualToString:@"month"])
return NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitDay;
if ([interval isEqualToString:@"year"])
return NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitDay|NSCalendarUnitMonth;
return units;
} }
/** /**
* Convert relative path to valid sound name attribute. * Convert an assets path to an valid sound name attribute.
*
* @param [ NSString* ] path A relative assets file path.
*
* @return [ NSString* ]
*/ */
- (NSString*) soundNameForAsset:(NSString*)path - (NSString*) soundNameForAsset:(NSString*)path
{ {
...@@ -263,19 +338,15 @@ ...@@ -263,19 +338,15 @@
} }
/** /**
* Convert resource path to valid sound name attribute. * Convert a ressource path to an valid sound name attribute.
*
* @param [ NSString* ] path A relative ressource file path.
*
* @return [ NSString* ]
*/ */
- (NSString*) soundNameForResource:(NSString*)path - (NSString*) soundNameForResource:(NSString*)path
{ {
return [path pathComponents].lastObject; return [path pathComponents].lastObject;
} }
/**
* If the string is empty.
*/
- (BOOL) stringIsNullOrEmpty:(NSString*)str
{
return (!str.length);
}
@end @end
...@@ -27,13 +27,9 @@ ...@@ -27,13 +27,9 @@
@interface UNMutableNotificationContent (APPLocalNotification) @interface UNMutableNotificationContent (APPLocalNotification)
// Initialize a new local notification
- (id) initWithOptions:(NSDictionary*)dict; - (id) initWithOptions:(NSDictionary*)dict;
// The options provided by the plug-in
- (APPLocalNotificationOptions*) options; - (APPLocalNotificationOptions*) options;
// Fully configured request to add the notification to the notification center
- (UNNotificationRequest*) request; - (UNNotificationRequest*) request;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON; - (NSString*) encodeToJSON;
@end @end
...@@ -35,8 +35,11 @@ static char optionsKey; ...@@ -35,8 +35,11 @@ static char optionsKey;
#pragma mark Init #pragma mark Init
/** /**
* Initialize a local notification with the given options when calling on JS side: * Initialize a notification with the given options.
* notification.local.add(options) *
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ UNMutableNotificationContent ]
*/ */
- (id) initWithOptions:(NSDictionary*)dict - (id) initWithOptions:(NSDictionary*)dict
{ {
...@@ -49,9 +52,9 @@ static char optionsKey; ...@@ -49,9 +52,9 @@ static char optionsKey;
} }
/** /**
* Applies the given options when calling on JS side: * Initialize a notification by using the options found under userInfo.
* notification.local.add(options) *
* @return [ Void ]
*/ */
- (void) __init - (void) __init
{ {
...@@ -65,10 +68,12 @@ static char optionsKey; ...@@ -65,10 +68,12 @@ static char optionsKey;
} }
#pragma mark - #pragma mark -
#pragma mark Methods #pragma mark Public
/** /**
* The options provided by the plug-in. * The options used to initialize the notification.
*
* @return [ APPLocalNotificationOptions* ] options
*/ */
- (APPLocalNotificationOptions*) options - (APPLocalNotificationOptions*) options
{ {
...@@ -85,30 +90,15 @@ static char optionsKey; ...@@ -85,30 +90,15 @@ static char optionsKey;
} }
/** /**
* Get associated option object
*/
- (APPLocalNotificationOptions*) getOptions
{
return objc_getAssociatedObject(self, &optionsKey);
}
/**
* Set associated option object
*/
- (void) setOptions:(APPLocalNotificationOptions*)options
{
objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/**
* The notifcations request ready to add to the notification center including * The notifcations request ready to add to the notification center including
* all informations about trigger behavior. * all informations about trigger behavior.
*
* @return [ UNNotificationRequest* ]
*/ */
- (UNNotificationRequest*) request - (UNNotificationRequest*) request
{ {
APPLocalNotificationOptions* opts = [self getOptions]; APPLocalNotificationOptions* opts = [self getOptions];
return [UNNotificationRequest requestWithIdentifier:opts.identifier return [UNNotificationRequest requestWithIdentifier:opts.identifier
content:self content:self
trigger:opts.trigger]; trigger:opts.trigger];
...@@ -116,27 +106,55 @@ static char optionsKey; ...@@ -116,27 +106,55 @@ static char optionsKey;
/** /**
* Encode the user info dict to JSON. * Encode the user info dict to JSON.
*
* @return [ NSString* ]
*/ */
- (NSString*) encodeToJSON - (NSString*) encodeToJSON
{ {
NSString* json; NSString* json;
NSData* data; NSData* data;
NSMutableDictionary* obj = [self.userInfo mutableCopy]; NSMutableDictionary* obj = [self.userInfo mutableCopy];
[obj removeObjectForKey:@"updatedAt"]; [obj removeObjectForKey:@"updatedAt"];
if (obj == NULL || obj.count == 0) if (obj == NULL || obj.count == 0)
return json; return json;
data = [NSJSONSerialization dataWithJSONObject:obj data = [NSJSONSerialization dataWithJSONObject:obj
options:NSJSONWritingPrettyPrinted options:NSJSONWritingPrettyPrinted
error:NULL]; error:NULL];
json = [[NSString alloc] initWithData:data json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding]; encoding:NSUTF8StringEncoding];
return [json stringByReplacingOccurrencesOfString:@"\n" return [json stringByReplacingOccurrencesOfString:@"\n"
withString:@""]; withString:@""];
} }
#pragma mark -
#pragma mark Private
/**
* The options used to initialize the notification.
*
* @return [ APPLocalNotificationOptions* ]
*/
- (APPLocalNotificationOptions*) getOptions
{
return objc_getAssociatedObject(self, &optionsKey);
}
/**
* Set the options used to initialize the notification.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ Void ]
*/
- (void) setOptions:(APPLocalNotificationOptions*)options
{
objc_setAssociatedObject(self, &optionsKey,
options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end @end
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "APPLocalNotificationOptions.h"
@import UserNotifications; @import UserNotifications;
@interface UNNotificationRequest (APPLocalNotification) @interface UNNotificationRequest (APPLocalNotification)
......
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
* @APPPLANT_LICENSE_HEADER_END@ * @APPPLANT_LICENSE_HEADER_END@
*/ */
#import "UNMutableNotificationContent+APPLocalNotification.h"
#import "APPLocalNotificationOptions.h" #import "APPLocalNotificationOptions.h"
#import "UNNotificationRequest+APPLocalNotification.h" #import "UNNotificationRequest+APPLocalNotification.h"
#import "UNMutableNotificationContent+APPLocalNotification.h"
#import <objc/runtime.h> #import <objc/runtime.h>
@import UserNotifications; @import UserNotifications;
......
...@@ -55,66 +55,39 @@ exports.requestPermission = function (callback, scope) { ...@@ -55,66 +55,39 @@ exports.requestPermission = function (callback, scope) {
exec(fn, null, 'LocalNotification', 'request', []); exec(fn, null, 'LocalNotification', 'request', []);
}; };
// /** /**
// * Returns the default settings. * Schedule notifications.
// * *
// * @return {Object} * @param [ Array ] notifications The notifications to schedule.
// */ * @param [ Function ] callback The function to be exec as the callback.
// exports.getDefaults = function () { * @param [ Object ] scope The callback function's scope.
// return this._defaults; * @param [ Object ] args Optional flags how to schedule.
// }; *
* @return [ Void ]
// /** */
// * Overwrite default settings. exports.schedule = function (msgs, callback, scope, args) {
// * var fn = function (granted) {
// * @param {Object} defaults
// */
// exports.setDefaults = function (newDefaults) {
// var defaults = this.getDefaults();
// for (var key in defaults) {
// if (newDefaults.hasOwnProperty(key)) {
// defaults[key] = newDefaults[key];
// }
// }
// };
// /**
// * Schedule a new local notification.
// *
// * @param {Object} msgs
// * The notification properties
// * @param {Function} callback
// * A function to be called after the notification has been canceled
// * @param {Object?} scope
// * The scope for the callback function
// * @param {Object?} args
// * skipPermission:true schedules the notifications immediatly without
// * registering or checking for permission
// */
// exports.schedule = function (msgs, callback, scope, args) {
// var fn = function(granted) {
// if (!granted) return; if (!granted) return;
// var notifications = Array.isArray(msgs) ? msgs : [msgs]; var notifications = Array.isArray(msgs) ? msgs : [msgs];
// for (var i = 0; i < notifications.length; i++) { for (var i = 0; i < notifications.length; i++) {
// var notification = notifications[i]; var notification = notifications[i];
// this.mergeWithDefaults(notification); this.mergeWithDefaults(notification);
// this.convertProperties(notification); this.convertProperties(notification);
// } }
// this.exec('schedule', notifications, callback, scope); this.exec('schedule', notifications, callback, scope);
// }; };
// if (args && args.skipPermission) { if (args && args.skipPermission) {
// fn.call(this, true); fn.call(this, true);
// } else { } else {
// this.registerPermission(fn, this); this.requestPermission(fn, this);
// } }
// }; };
// /** // /**
// * Update existing notifications specified by IDs in options. // * Update existing notifications specified by IDs in options.
...@@ -435,55 +408,75 @@ exports.requestPermission = function (callback, scope) { ...@@ -435,55 +408,75 @@ exports.requestPermission = function (callback, scope) {
// this.exec('getTriggered', null, callback, scope); // this.exec('getTriggered', null, callback, scope);
// }; // };
/**
* The (platform specific) default settings.
*
* @return [ Object ]
*/
exports.getDefaults = function () {
return this._defaults;
};
/**
* Overwrite default settings.
*
* @param [ Object ] newDefaults New default values.
*
* @return [ Void ]
*/
exports.setDefaults = function (newDefaults) {
var defaults = this.getDefaults();
// /********** for (var key in defaults) {
// * EVENTS * if (newDefaults.hasOwnProperty(key)) {
// **********/ defaults[key] = newDefaults[key];
}
}
};
// /** /**
// * Register callback for given event. * Register callback for given event.
// * *
// * @param {String} event * @param [ String ] event The name of the event.
// * The event's name * @param [ Function ] callback The function to be exec as callback.
// * @param {Function} callback * @param [ Object ] scope The callback function's scope.
// * The function to be exec as callback *
// * @param {Object?} scope * @return [ Void ]
// * The callback function's scope */
// */ exports.on = function (event, callback, scope) {
// exports.on = function (event, callback, scope) {
// if (typeof callback !== "function") if (typeof callback !== "function")
// return; return;
// if (!this._listener[event]) { if (!this._listener[event]) {
// this._listener[event] = []; this._listener[event] = [];
// } }
// var item = [callback, scope || window]; var item = [callback, scope || window];
// this._listener[event].push(item); this._listener[event].push(item);
// }; };
// /** /**
// * Unregister callback for given event. * Unregister callback for given event.
// * *
// * @param {String} event * @param [ String ] event The name of the event.
// * The event's name * @param [ Function ] callback The function to be exec as callback.
// * @param {Function} callback *
// * The function to be exec as callback * @return [ Void ]
// */ */
// exports.un = function (event, callback) { exports.un = function (event, callback) {
// var listener = this._listener[event]; var listener = this._listener[event];
// if (!listener) if (!listener)
// return; return;
// for (var i = 0; i < listener.length; i++) { for (var i = 0; i < listener.length; i++) {
// var fn = listener[i][0]; var fn = listener[i][0];
// if (fn == callback) { if (fn == callback) {
// listener.splice(i, 1); listener.splice(i, 1);
// break; break;
// } }
// } }
// }; };
...@@ -15,166 +15,140 @@ ...@@ -15,166 +15,140 @@
* limitations under the License. * limitations under the License.
*/ */
// var exec = require('cordova/exec'), var exec = require('cordova/exec'),
// channel = require('cordova/channel'); channel = require('cordova/channel');
// Default values
// /*********** exports._defaults = {
// * MEMBERS * text: '',
// ***********/ title: '',
sound: 'res://platform_default',
// // Default values badge: 0,
// exports._defaults = { id: 0,
// text: '', data: undefined,
// title: '', every: undefined,
// sound: 'res://platform_default', at: undefined
// badge: 0, };
// id: 0,
// data: undefined, // Listener
// every: undefined, exports._listener = {};
// at: undefined
// }; /**
* Merge platform specific properties into the default ones.
// // listener *
// exports._listener = {}; * @return [ Void ]
*/
exports.applyPlatformSpecificOptions = function () {
// /******** var defaults = this._defaults;
// * UTIL *
// ********/ switch (device.platform) {
case 'Android':
// /** defaults.icon = 'res://ic_popup_reminder';
// * Merge platform specific properties into the default ones. defaults.smallIcon = undefined;
// * defaults.ongoing = false;
// * @return {Object} defaults.autoClear = true;
// * The default properties for the platform defaults.led = undefined;
// */ defaults.color = undefined;
// exports.applyPlatformSpecificOptions = function () {
// var defaults = this._defaults; break;
}
// switch (device.platform) { };
// case 'Android':
// defaults.icon = 'res://ic_popup_reminder'; /**
// defaults.smallIcon = undefined; * Merge custom properties with the default values.
// defaults.ongoing = false; *
// defaults.autoClear = true; * @param [ Object ] options Set of custom values.
// defaults.led = undefined; *
// defaults.color = undefined; * @retrun [ Object ]
// break; */
// } exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults();
// return defaults;
// }; options.at = this.getValueFor(options, 'at', 'firstAt', 'date');
options.text = this.getValueFor(options, 'text', 'message');
// /** options.data = this.getValueFor(options, 'data', 'json');
// * Merge custom properties with the default values.
// * if (defaults.hasOwnProperty('autoClear')) {
// * @param {Object} options options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel');
// * Set of custom values }
// *
// * @retrun {Object} if (options.autoClear !== true && options.ongoing) {
// * The merged property list options.autoClear = false;
// */ }
// exports.mergeWithDefaults = function (options) {
// var defaults = this.getDefaults(); if (options.at === undefined || options.at === null) {
options.at = new Date();
// options.at = this.getValueFor(options, 'at', 'firstAt', 'date'); }
// options.text = this.getValueFor(options, 'text', 'message');
// options.data = this.getValueFor(options, 'data', 'json'); for (var key in defaults) {
if (options[key] === null || options[key] === undefined) {
// if (defaults.hasOwnProperty('autoClear')) { if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
// options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel'); options[key] = undefined;
// } } else {
options[key] = defaults[key];
// if (options.autoClear !== true && options.ongoing) { }
// options.autoClear = false; }
// } }
// if (options.at === undefined || options.at === null) { for (key in options) {
// options.at = new Date(); if (!defaults.hasOwnProperty(key)) {
// } delete options[key];
console.warn('Unknown property: ' + key);
// for (var key in defaults) { }
// if (options[key] === null || options[key] === undefined) { }
// if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
// options[key] = undefined; return options;
// } else { };
// options[key] = defaults[key];
// } /**
// } * Convert the passed values to their required type.
// } *
* @param [ Object ] options Properties to convert for.
// for (key in options) { *
// if (!defaults.hasOwnProperty(key)) { * @return [ Object ] The converted property list
// delete options[key]; */
// console.warn('Unknown property: ' + key); exports.convertProperties = function (options) {
// }
// } if (options.id) {
if (isNaN(options.id)) {
// return options; options.id = this.getDefaults().id;
// }; console.warn('Id is not a number: ' + options.id);
} else {
// /** options.id = Number(options.id);
// * Convert the passed values to their required type. }
// * }
// * @param {Object} options
// * Set of custom values if (options.title) {
// * options.title = options.title.toString();
// * @retrun {Object} }
// * The converted property list
// */ if (options.text) {
// exports.convertProperties = function (options) { options.text = options.text.toString();
}
// if (options.id) {
// if (isNaN(options.id)) { if (options.badge) {
// options.id = this.getDefaults().id; if (isNaN(options.badge)) {
// console.warn('Id is not a number: ' + options.id); options.badge = this.getDefaults().badge;
// } else { console.warn('Badge number is not a number: ' + options.id);
// options.id = Number(options.id); } else {
// } options.badge = Number(options.badge);
// } }
}
// if (options.title) {
// options.title = options.title.toString(); if (options.at) {
// } if (typeof options.at == 'object') {
options.at = options.at.getTime();
// if (options.text) { }
// options.text = options.text.toString();
// } options.at = Math.round(options.at/1000);
}
// if (options.badge) {
// if (isNaN(options.badge)) { if (typeof options.data == 'object') {
// options.badge = this.getDefaults().badge; options.data = JSON.stringify(options.data);
// console.warn('Badge number is not a number: ' + options.id); }
// } else {
// options.badge = Number(options.badge); return options;
// } };
// }
// if (options.at) {
// if (typeof options.at == 'object') {
// options.at = options.at.getTime();
// }
// options.at = Math.round(options.at/1000);
// }
// if (typeof options.data == 'object') {
// options.data = JSON.stringify(options.data);
// }
// if (options.every) {
// if (device.platform == 'iOS' && typeof options.every != 'string') {
// options.every = this.getDefaults().every;
// var warning = 'Every option is not a string: ' + options.id;
// warning += '. Expects one of: second, minute, hour, day, week, ';
// warning += 'month, year on iOS.';
// console.warn(warning);
// }
// }
// return options;
// };
/** /**
* Create a callback function to get executed within a specific scope. * Create a callback function to get executed within a specific scope.
...@@ -194,108 +168,101 @@ exports.createCallbackFn = function (fn, scope) { ...@@ -194,108 +168,101 @@ exports.createCallbackFn = function (fn, scope) {
}; };
}; };
// /** /**
// * Convert the IDs to numbers. * Convert the IDs to numbers.
// * *
// * @param {String/Number[]} ids * @param [ Array ] ids
// * *
// * @return Array of Numbers * @return [ Array<Number> ]
// */ */
// exports.convertIds = function (ids) { exports.convertIds = function (ids) {
// var convertedIds = []; var convertedIds = [];
// for (var i = 0; i < ids.length; i++) { for (var i = 0; i < ids.length; i++) {
// convertedIds.push(Number(ids[i])); convertedIds.push(Number(ids[i]));
// } }
// return convertedIds; return convertedIds;
// }; };
// /** /**
// * First found value for the given keys. * First found value for the given keys.
// * *
// * @param {Object} options * @param [ Object ] options Object with key-value properties.
// * Object with key-value properties * @param [ *Array<String> ] keys List of keys.
// * @param {String[]} keys* *
// * Key list * @return [ Object ]
// */ */
// exports.getValueFor = function (options) { exports.getValueFor = function (options) {
// var keys = Array.apply(null, arguments).slice(1); var keys = Array.apply(null, arguments).slice(1);
// for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
// var key = keys[i]; var key = keys[i];
// if (options.hasOwnProperty(key)) { if (options.hasOwnProperty(key)) {
// return options[key]; return options[key];
// } }
// } }
// }; };
// /** /**
// * Fire event with given arguments. * Fire the event with given arguments.
// * *
// * @param {String} event * @param [ String ] event The event's name.
// * The event's name * @param [ *Array] args The callback's arguments.
// * @param {args*} *
// * The callback's arguments * @return [ Void]
// */ */
// exports.fireEvent = function (event) { exports.fireEvent = function (event) {
// var args = Array.apply(null, arguments).slice(1), var args = Array.apply(null, arguments).slice(1),
// listener = this._listener[event]; listener = this._listener[event];
// if (!listener) if (!listener)
// return; return;
// for (var i = 0; i < listener.length; i++) { for (var i = 0; i < listener.length; i++) {
// var fn = listener[i][0], var fn = listener[i][0],
// scope = listener[i][1]; scope = listener[i][1];
// fn.apply(scope, args); fn.apply(scope, args);
// } }
// }; };
// /** /**
// * Execute the native counterpart. * Execute the native counterpart.
// * *
// * @param {String} action * @param [ String ] action The name of the action.
// * The name of the action * @param [ Array ] args Array of arguments.
// * @param args[] * @param [ Function] callback The callback function.
// * Array of arguments * @param [ Object ] scope The scope for the function.
// * @param {Function} callback *
// * The callback function * @return [ Void ]
// * @param {Object} scope */
// * The scope for the function exports.exec = function (action, args, callback, scope) {
// */ var fn = this.createCallbackFn(callback, scope),
// exports.exec = function (action, args, callback, scope) { params = [];
// var fn = this.createCallbackFn(callback, scope),
// params = []; if (Array.isArray(args)) {
params = args;
// if (Array.isArray(args)) { } else if (args) {
// params = args; params.push(args);
// } else if (args) { }
// params.push(args);
// } exec(fn, null, 'LocalNotification', action, params);
};
// exec(fn, null, 'LocalNotification', action, params);
// }; // Called after 'deviceready' event
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// /********* // and all queued events can be executed.
// * HOOKS * exec(null, null, 'LocalNotification', 'deviceready', []);
// *********/ });
// // Called after 'deviceready' event // Called before 'deviceready' event
// channel.deviceready.subscribe(function () { channel.onCordovaReady.subscribe(function () {
// // Device is ready now, the listeners are registered // Device plugin is ready now
// // and all queued events can be executed. channel.onCordovaInfoReady.subscribe(function () {
// exec(null, null, 'LocalNotification', 'deviceready', []); // Merge platform specifics into defaults
// }); exports.applyPlatformSpecificOptions();
});
// // Called before 'deviceready' event });
// channel.onCordovaReady.subscribe(function () {
// // Device plugin is ready now
// channel.onCordovaInfoReady.subscribe(function () {
// // Merge platform specifics into defaults
// exports.applyPlatformSpecificOptions();
// });
// });
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
var exec = require('cordova/exec');
/** /**
* Request permission to show notifications. * Request permission to show notifications.
* *
...@@ -24,7 +26,14 @@ ...@@ -24,7 +26,14 @@
* @return [ Void ] * @return [ Void ]
*/ */
exports.hasPermission = function (callback, scope) { exports.hasPermission = function (callback, scope) {
this.core.hasPermission(callback, scope); var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'check', []);
}; };
/** /**
...@@ -36,43 +45,49 @@ exports.hasPermission = function (callback, scope) { ...@@ -36,43 +45,49 @@ exports.hasPermission = function (callback, scope) {
* @return [ Void ] * @return [ Void ]
*/ */
exports.requestPermission = function (callback, scope) { exports.requestPermission = function (callback, scope) {
this.core.requestPermission(callback, scope); var fn = this.createCallbackFn(callback, scope);
if (device.platform != 'iOS') {
fn(true);
return;
}
exec(fn, null, 'LocalNotification', 'request', []);
}; };
// /** /**
// * Returns the default settings. * Schedule notifications.
// * *
// * @return {Object} * @param [ Array ] notifications The notifications to schedule.
// */ * @param [ Function ] callback The function to be exec as the callback.
// exports.getDefaults = function () { * @param [ Object ] scope The callback function's scope.
// return this.core.getDefaults(); * @param [ Object ] args Optional flags how to schedule.
// }; *
* @return [ Void ]
*/
exports.schedule = function (msgs, callback, scope, args) {
var fn = function (granted) {
// /** if (!granted) return;
// * Overwrite default settings.
// *
// * @param {Object} defaults
// */
// exports.setDefaults = function (defaults) {
// this.core.setDefaults(defaults);
// };
// /** var notifications = Array.isArray(msgs) ? msgs : [msgs];
// * Schedule a new local notification.
// * for (var i = 0; i < notifications.length; i++) {
// * @param {Object} notifications var notification = notifications[i];
// * The notification properties
// * @param {Function} callback this.mergeWithDefaults(notification);
// * A function to be called after the notification has been canceled this.convertProperties(notification);
// * @param {Object?} scope }
// * The scope for the callback function
// * @param {Object?} args this.exec('schedule', notifications, callback, scope);
// * skipPermission:true schedules the notifications immediatly without };
// * registering or checking for permission
// */ if (args && args.skipPermission) {
// exports.schedule = function (notifications, callback, scope, args) { fn.call(this, true);
// this.core.schedule(notifications, callback, scope, args); } else {
// }; this.requestPermission(fn, this);
}
};
// /** // /**
// * Update existing notifications specified by IDs in options. // * Update existing notifications specified by IDs in options.
...@@ -87,8 +102,27 @@ exports.requestPermission = function (callback, scope) { ...@@ -87,8 +102,27 @@ exports.requestPermission = function (callback, scope) {
// * skipPermission:true schedules the notifications immediatly without // * skipPermission:true schedules the notifications immediatly without
// * registering or checking for permission // * registering or checking for permission
// */ // */
// exports.update = function (notifications, callback, scope, args) { // exports.update = function (msgs, callback, scope, args) {
// this.core.update(notifications, callback, scope, args); // var fn = function(granted) {
// if (!granted) return;
// var notifications = Array.isArray(msgs) ? msgs : [msgs];
// for (var i = 0; i < notifications.length; i++) {
// var notification = notifications[i];
// this.convertProperties(notification);
// }
// this.exec('update', notifications, callback, scope);
// };
// if (args && args.skipPermission) {
// fn.call(this, true);
// } else {
// this.registerPermission(fn, this);
// }
// }; // };
// /** // /**
...@@ -102,7 +136,10 @@ exports.requestPermission = function (callback, scope) { ...@@ -102,7 +136,10 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.clear = function (ids, callback, scope) { // exports.clear = function (ids, callback, scope) {
// this.core.clear(ids, callback, scope); // ids = Array.isArray(ids) ? ids : [ids];
// ids = this.convertIds(ids);
// this.exec('clear', ids, callback, scope);
// }; // };
// /** // /**
...@@ -114,7 +151,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -114,7 +151,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.clearAll = function (callback, scope) { // exports.clearAll = function (callback, scope) {
// this.core.clearAll(callback, scope); // this.exec('clearAll', null, callback, scope);
// }; // };
// /** // /**
...@@ -128,7 +165,10 @@ exports.requestPermission = function (callback, scope) { ...@@ -128,7 +165,10 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.cancel = function (ids, callback, scope) { // exports.cancel = function (ids, callback, scope) {
// this.core.cancel(ids, callback, scope); // ids = Array.isArray(ids) ? ids : [ids];
// ids = this.convertIds(ids);
// this.exec('cancel', ids, callback, scope);
// }; // };
// /** // /**
...@@ -140,7 +180,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -140,7 +180,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.cancelAll = function (callback, scope) { // exports.cancelAll = function (callback, scope) {
// this.core.cancelAll(callback, scope); // this.exec('cancelAll', null, callback, scope);
// }; // };
// /** // /**
...@@ -154,7 +194,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -154,7 +194,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.isPresent = function (id, callback, scope) { // exports.isPresent = function (id, callback, scope) {
// this.core.isPresent(id, callback, scope); // this.exec('isPresent', id || 0, callback, scope);
// }; // };
// /** // /**
...@@ -168,10 +208,10 @@ exports.requestPermission = function (callback, scope) { ...@@ -168,10 +208,10 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.isScheduled = function (id, callback, scope) { // exports.isScheduled = function (id, callback, scope) {
// this.core.isScheduled(id, callback, scope); // this.exec('isScheduled', id || 0, callback, scope);
// }; // };
// * // /**
// * Check if a notification with an ID was triggered. // * Check if a notification with an ID was triggered.
// * // *
// * @param {String} id // * @param {String} id
...@@ -180,21 +220,21 @@ exports.requestPermission = function (callback, scope) { ...@@ -180,21 +220,21 @@ exports.requestPermission = function (callback, scope) {
// * A callback function to be called with the list // * A callback function to be called with the list
// * @param {Object?} scope // * @param {Object?} scope
// * The scope for the callback function // * The scope for the callback function
// */
// exports.isTriggered = function (id, callback, scope) { // exports.isTriggered = function (id, callback, scope) {
// this.core.isTriggered(id, callback, scope); // this.exec('isTriggered', id || 0, callback, scope);
// }; // };
// /** // *
// * List all local notification IDs. // * List all local notification IDs.
// * // *
// * @param {Function} callback // * @param {Function} callback
// * A callback function to be called with the list // * A callback function to be called with the list
// * @param {Object?} scope // * @param {Object?} scope
// * The scope for the callback function // * The scope for the callback function
// */
// exports.getAllIds = function (callback, scope) { // exports.getAllIds = function (callback, scope) {
// this.core.getAllIds(callback, scope); // this.exec('getAllIds', null, callback, scope);
// }; // };
// /** // /**
...@@ -213,7 +253,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -213,7 +253,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getScheduledIds = function (callback, scope) { // exports.getScheduledIds = function (callback, scope) {
// this.core.getScheduledIds(callback, scope); // this.exec('getScheduledIds', null, callback, scope);
// }; // };
// /** // /**
...@@ -225,7 +265,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -225,7 +265,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getTriggeredIds = function (callback, scope) { // exports.getTriggeredIds = function (callback, scope) {
// this.core.getTriggeredIds(callback, scope); // this.exec('getTriggeredIds', null, callback, scope);
// }; // };
// /** // /**
...@@ -240,7 +280,24 @@ exports.requestPermission = function (callback, scope) { ...@@ -240,7 +280,24 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.get = function () { // exports.get = function () {
// this.core.get.apply(this.core, arguments); // var args = Array.apply(null, arguments);
// if (typeof args[0] == 'function') {
// args.unshift([]);
// }
// var ids = args[0],
// callback = args[1],
// scope = args[2];
// if (!Array.isArray(ids)) {
// this.exec('getSingle', Number(ids), callback, scope);
// return;
// }
// ids = this.convertIds(ids);
// this.exec('getAll', ids, callback, scope);
// }; // };
// /** // /**
...@@ -252,7 +309,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -252,7 +309,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getAll = function (callback, scope) { // exports.getAll = function (callback, scope) {
// this.core.getAll(callback, scope); // this.exec('getAll', null, callback, scope);
// }; // };
// /** // /**
...@@ -267,7 +324,28 @@ exports.requestPermission = function (callback, scope) { ...@@ -267,7 +324,28 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getScheduled = function () { // exports.getScheduled = function () {
// this.core.getScheduled.apply(this.core, arguments); // var args = Array.apply(null, arguments);
// if (typeof args[0] == 'function') {
// args.unshift([]);
// }
// var ids = args[0],
// callback = args[1],
// scope = args[2];
// if (!Array.isArray(ids)) {
// ids = [ids];
// }
// if (!Array.isArray(ids)) {
// this.exec('getSingleScheduled', Number(ids), callback, scope);
// return;
// }
// ids = this.convertIds(ids);
// this.exec('getScheduled', ids, callback, scope);
// }; // };
// /** // /**
...@@ -279,7 +357,7 @@ exports.requestPermission = function (callback, scope) { ...@@ -279,7 +357,7 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getAllScheduled = function (callback, scope) { // exports.getAllScheduled = function (callback, scope) {
// this.core.getAllScheduled(callback, scope); // this.exec('getScheduled', null, callback, scope);
// }; // };
// /** // /**
...@@ -294,7 +372,28 @@ exports.requestPermission = function (callback, scope) { ...@@ -294,7 +372,28 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getTriggered = function () { // exports.getTriggered = function () {
// this.core.getTriggered.apply(this.core, arguments); // var args = Array.apply(null, arguments);
// if (typeof args[0] == 'function') {
// args.unshift([]);
// }
// var ids = args[0],
// callback = args[1],
// scope = args[2];
// if (!Array.isArray(ids)) {
// ids = [ids];
// }
// if (!Array.isArray(ids)) {
// this.exec('getSingleTriggered', Number(ids), callback, scope);
// return;
// }
// ids = this.convertIds(ids);
// this.exec('getTriggered', ids, callback, scope);
// }; // };
// /** // /**
...@@ -306,31 +405,78 @@ exports.requestPermission = function (callback, scope) { ...@@ -306,31 +405,78 @@ exports.requestPermission = function (callback, scope) {
// * The scope for the callback function // * The scope for the callback function
// */ // */
// exports.getAllTriggered = function (callback, scope) { // exports.getAllTriggered = function (callback, scope) {
// this.core.getAllTriggered(callback, scope); // this.exec('getTriggered', null, callback, scope);
// }; // };
// /** /**
// * Register callback for given event. * The (platform specific) default settings.
// * *
// * @param {String} event * @return [ Object ]
// * The event's name */
// * @param {Function} callback exports.getDefaults = function () {
// * The function to be exec as callback return this._defaults;
// * @param {Object?} scope };
// * The callback function's scope
// */
// exports.on = function (event, callback, scope) {
// this.core.on(event, callback, scope);
// };
// /** /**
// * Unregister callback for given event. * Overwrite default settings.
// * *
// * @param {String} event * @param [ Object ] newDefaults New default values.
// * The event's name *
// * @param {Function} callback * @return [ Void ]
// * The function to be exec as callback */
// */ exports.setDefaults = function (newDefaults) {
// exports.un = function (event, callback) { var defaults = this.getDefaults();
// this.core.un(event, callback);
// }; for (var key in defaults) {
if (newDefaults.hasOwnProperty(key)) {
defaults[key] = newDefaults[key];
}
}
};
/**
* Register callback for given event.
*
* @param [ String ] event The name of the event.
* @param [ Function ] callback The function to be exec as callback.
* @param [ Object ] scope The callback function's scope.
*
* @return [ Void ]
*/
exports.on = function (event, callback, scope) {
if (typeof callback !== "function")
return;
if (!this._listener[event]) {
this._listener[event] = [];
}
var item = [callback, scope || window];
this._listener[event].push(item);
};
/**
* Unregister callback for given event.
*
* @param [ String ] event The name of the event.
* @param [ Function ] callback The function to be exec as callback.
*
* @return [ Void ]
*/
exports.un = function (event, callback) {
var listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0];
if (fn == callback) {
listener.splice(i, 1);
break;
}
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment