Commit cac11bc1 by Sebastián Katzer

Schedule notifications with support for custom intervals on iOS

parent ca85d768
......@@ -59,7 +59,7 @@
<header-file src="src/ios/APPLocalNotification.h" />
<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" />
<header-file src="src/ios/UNUserNotificationCenter+APPLocalNotification.h" />
......@@ -69,7 +69,7 @@
<source-file src="src/ios/UNMutableNotificationContent+APPLocalNotification.m" />
<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>
......
......@@ -35,8 +35,8 @@
// Request permission to show notifications
- (void) request:(CDVInvokedUrlCommand*)command;
//// Schedule set of notifications
//- (void) schedule:(CDVInvokedUrlCommand*)command;
// Schedule notifications
- (void) schedule:(CDVInvokedUrlCommand*)command;
//// Update set of notifications
//- (void) update:(CDVInvokedUrlCommand*)command;
//// Cancel set of notifications
......
......@@ -22,25 +22,18 @@
*/
#import "APPLocalNotification.h"
//#import "APPLocalNotificationOptions.h"
//#import "UNUserNotificationCenter+APPLocalNotification.h"
//#import "UNNotificationRequest+APPLocalNotification.h"
//#import "UNMutableNotificationContent+APPLocalNotification.h"
#import "APPLocalNotificationOptions.h"
#import "UNUserNotificationCenter+APPLocalNotification.h"
#import "UNNotificationRequest+APPLocalNotification.h"
#import "UNMutableNotificationContent+APPLocalNotification.h"
@interface APPLocalNotification ()
// Property reader for [self app]
@property (readonly, getter=app) UIApplication* app;
// Property reader for [self center]
@property (readonly, getter=center) UNUserNotificationCenter* center;
// All events will be queued until deviceready has been fired
@property (strong, nonatomic) UIApplication* app;
@property (strong, nonatomic) UNUserNotificationCenter* center;
@property (readwrite, assign) BOOL deviceready;
// Event queue
@property (readonly, nonatomic, retain) NSMutableArray* eventQueue;
// IOS9: TODO remove later
@property (nonatomic, retain) CDVInvokedUrlCommand* command;
@end
@implementation APPLocalNotification
......@@ -52,6 +45,8 @@
/**
* Execute all queued events.
*
* @return [ Void ]
*/
- (void) deviceready:(CDVInvokedUrlCommand*)command
{
......@@ -63,48 +58,32 @@
[eventQueue removeAllObjects];
}
//
///**
// * Schedule a set of notifications.
// *
// * @param properties
// * A dict of properties for each notification
// */
//- (void) schedule:(CDVInvokedUrlCommand*)command
//{
// NSArray* notifications = command.arguments;
//
// [self.commandDelegate runInBackground:^{
// if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
// for (NSDictionary* options in notifications) {
// UNMutableNotificationContent* notification;
//
// notification = [[UNMutableNotificationContent alloc]
// initWithOptions:options];
//
// [self scheduleNotification:notification];
// //[self fireEvent:@"add" notification:notification];
// }
// } else {
// 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];
// }];
//}
//
/**
* Schedule notifications.
*
* @param [Array<Hash>] properties A list of key-value properties.
*
* @return [ Void ]
*/
- (void) schedule:(CDVInvokedUrlCommand*)command
{
NSArray* notifications = command.arguments;
[self.commandDelegate runInBackground:^{
for (NSDictionary* options in notifications) {
UNMutableNotificationContent* notification;
notification = [[UNMutableNotificationContent alloc]
initWithOptions:options];
[self scheduleNotification:notification];
}
[self execCallback:command];
}];
}
///**
// * Update a set of notifications.
// *
......@@ -535,7 +514,7 @@
*/
- (void) check:(CDVInvokedUrlCommand*)command
{
[self.center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* settings) {
[_center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* settings) {
BOOL authorized = settings.authorizationStatus == UNAuthorizationStatusAuthorized;
BOOL enabled = settings.notificationCenterSetting == UNNotificationSettingEnabled;
BOOL permitted = authorized && enabled;
......@@ -563,19 +542,22 @@
}
#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.
// */
......@@ -620,44 +602,43 @@
//
// [self.app setApplicationIconBadgeNumber:0];
//}
//
//#pragma mark -
//#pragma mark Delegates
//
///**
// * Called when a notification is delivered to a foreground app.
// */
//- (void) userNotificationCenter:(UNUserNotificationCenter *)center
// willPresentNotification:(UNNotification *)notification
// withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
//{
// [self fireEvent:@"trigger" notification:notification.request];
// completionHandler(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
//}
//
//
///**
// * Called to let your app know which action was selected by the user for a given
// * notification.
// */
//- (void) userNotificationCenter:(UNUserNotificationCenter *)center
// didReceiveNotificationResponse:(UNNotificationResponse *)response
// withCompletionHandler:(void (^)())completionHandler
//{
// UNNotificationRequest* notification = response.notification.request;
//
// [self fireEvent:@"click" notification:notification];
//
#pragma mark -
#pragma mark UNUserNotificationCenterDelegate
/**
* Called when a notification is delivered to the app while being in foreground.
*/
- (void) userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
[self fireEvent:@"trigger" notification:notification.request];
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);
}
/**
* Called to let your app know which action was selected by the user for a given
* notification.
*/
- (void) userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler
{
UNNotificationRequest* notification = response.notification.request;
[self fireEvent:@"click" notification:notification];
// if ([notification.options isRepeating]) {
// [self.center clearNotification:notification];
// [_center clearNotification:notification];
// [self fireEvent:@"clear" notification:notification];
// } else {
// [self.center cancelNotification:notification];
// [_center cancelNotification:notification];
// [self fireEvent:@"cancel" notification:notification];
// }
//
// completionHandler();
//}
completionHandler();
}
#pragma mark -
#pragma mark Life Cycle
......@@ -668,249 +649,73 @@
- (void) pluginInitialize
{
eventQueue = [[NSMutableArray alloc] init];
_app = [UIApplication sharedApplication];
_center = [UNUserNotificationCenter currentNotificationCenter];
self.center.delegate = self;
_center.delegate = self;
}
#pragma mark -
#pragma mark Helper
///**
// * Retrieves the application state
// *
// * @return
// * Either "background" or "foreground"
// */
//- (NSString*) applicationState
//{
// UIApplicationState state = [self.app applicationState];
//
// bool isActive = state == UIApplicationStateActive;
//
// 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];
//}
/**
* Retrieve the state of the application.
*
* @return "background" or "foreground"
*/
- (NSString*) applicationState
{
UIApplicationState state = [_app applicationState];
bool isActive = state == UIApplicationStateActive;
return isActive ? @"foreground" : @"background";
}
/**
* 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.
// */
//- (void) fireEvent:(NSString*)event
//{
// [self fireEvent:event notification:NULL];
//}
//
///**
// * Fire event for local notification.
// */
//- (void) fireEvent:(NSString*)event
// notification:(UNNotificationRequest*)notification
//{
// NSString* js;
// NSString* appState = [self applicationState];
// NSString* params = [NSString stringWithFormat:@"\"%@\"", appState];
//
// if (notification) {
// NSString* args = [notification encodeToJSON];
// params = [NSString stringWithFormat:@"%@,'%@'", args, appState];
// }
//
// js = [NSString stringWithFormat:
// @"cordova.plugins.notification.local.core.fireEvent('%@', %@)",
// event, params];
//
// if (deviceready) {
// [self.commandDelegate evalJs:js];
// } else {
// [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];
// }
//}
/**
* Fire general event.
*/
- (void) fireEvent:(NSString*)event
{
[self fireEvent:event notification:NULL];
}
/**
* Fire event for local notification.
*/
- (void) fireEvent:(NSString*)event
notification:(UNNotificationRequest*)notification
{
NSString* js;
NSString* appState = [self applicationState];
NSString* params = [NSString stringWithFormat:@"\"%@\"", appState];
if (notification) {
NSString* args = [notification encodeToJSON];
params = [NSString stringWithFormat:@"%@,'%@'", args, appState];
}
js = [NSString stringWithFormat:
@"cordova.plugins.notification.local.core.fireEvent('%@', %@)",
event, params];
if (deviceready) {
[self.commandDelegate evalJs:js];
} else {
[self.eventQueue addObject:js];
}
}
@end
......@@ -21,15 +21,10 @@
* @APPPLANT_LICENSE_HEADER_END@
*/
#import <UserNotifications/UNNotificationSound.h>
#import <UserNotifications/UNNotificationRequest.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@import UserNotifications;
@interface APPLocalNotificationOptions : NSObject
- (id) initWithDict:(NSDictionary*)dict;
@property (readonly, getter=id) NSNumber* id;
@property (readonly, getter=identifier) NSString* identifier;
@property (readonly, getter=title) NSString* title;
......@@ -39,9 +34,8 @@
@property (readonly, getter=sound) UNNotificationSound* sound;
@property (readonly, getter=userInfo) NSDictionary* userInfo;
// If it's a repeating notification
- (id) initWithDict:(NSDictionary*)dict;
- (BOOL) isRepeating;
// how and when to trigger the notification
- (UNNotificationTrigger*) trigger;
@end
......@@ -40,8 +40,11 @@
#pragma mark Initialization
/**
* Initialize the object with the given options when calling on JS side:
* notification.local.add(options)
* Initialize by using the given property values.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ APPLocalNotificationOptions ]
*/
- (id) initWithDict:(NSDictionary*)dictionary
{
......@@ -53,10 +56,12 @@
}
#pragma mark -
#pragma mark Attributes
#pragma mark Properties
/**
* The notification's ID.
* The ID for the notification.
*
* @return [ NSNumber* ]
*/
- (NSNumber*) id
{
......@@ -66,7 +71,9 @@
}
/**
* The notification's ID as a string.
* The ID for the notification.
*
* @return [ NSString* ]
*/
- (NSString*) identifier
{
......@@ -74,7 +81,9 @@
}
/**
* The notification's title.
* The title for the notification.
*
* @return [ NSString* ]
*/
- (NSString*) title
{
......@@ -82,7 +91,9 @@
}
/**
* The notification's title.
* The subtitle for the notification.
*
* @return [ NSString* ]
*/
- (NSString*) subtitle
{
......@@ -92,7 +103,9 @@
}
/**
* The notification's message.
* The text for the notification.
*
* @return [ NSString* ]
*/
- (NSString*) text
{
......@@ -100,7 +113,9 @@
}
/**
* The notification's badge number.
* The badge number for the notification.
*
* @return [ NSNumber* ]
*/
- (NSNumber*) badge
{
......@@ -108,14 +123,16 @@
}
/**
* The notification's sound path.
* The sound file for the notification.
*
* @return [ UNNotificationSound* ]
*/
- (UNNotificationSound*) sound
{
NSString* path = [dict objectForKey:@"sound"];
NSString* file;
if ([self stringIsNullOrEmpty:path])
if (!path.length)
return NULL;
if ([path isEqualToString:@"res://platform_default"])
......@@ -132,7 +149,9 @@
}
/**
* The notification's fire date.
* The date when to fire the notification.
*
* @return [ NSDate* ]
*/
- (NSDate*) fireDate
{
......@@ -142,29 +161,41 @@
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
{
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 -
#pragma mark Methods
return every > 0;
}
/**
* Specify how and when to trigger the notification.
*
* @return [ UNNotificationTrigger* ]
*/
- (UNNotificationTrigger*) trigger
{
return [self isRepeating] ? [self triggerWithDateMatchingComponents] : [self triggerWithTimeInterval];
if ([self isRepeating])
return [self repeatingTrigger];
return [self nonRepeatingTrigger];
}
/**
* The notification's user info dict.
*
* @return [ NSDictionary* ]
*/
- (NSDictionary*) userInfo
{
......@@ -183,18 +214,55 @@
#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
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]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
......@@ -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
{
......@@ -217,44 +287,49 @@
}
/**
* The notification's repeat interval.
* The repeat interval for the notification.
*
* @return [ NSCalendarUnit ]
*/
- (NSCalendarUnit) repeatInterval
{
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]) {
return unitFlags;
}
else if ([interval isEqualToString:@"second"]) {
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay;
}
else if ([interval isEqualToString:@"minute"]) {
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitSecond;
}
else if ([interval isEqualToString:@"hour"]) {
return NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitMinute;
}
else if ([interval isEqualToString:@"day"]) {
if (!interval.length)
return units;
if ([interval isEqualToString:@"second"])
return NSCalendarUnitNanosecond;
if ([interval isEqualToString:@"minute"])
return NSCalendarUnitSecond;
if ([interval isEqualToString:@"hour"])
return NSCalendarUnitMinute;
if ([interval isEqualToString:@"day"])
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
{
......@@ -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
{
return [path pathComponents].lastObject;
}
/**
* If the string is empty.
*/
- (BOOL) stringIsNullOrEmpty:(NSString*)str
{
return (!str.length);
}
@end
......@@ -27,13 +27,9 @@
@interface UNMutableNotificationContent (APPLocalNotification)
// Initialize a new local notification
- (id) initWithOptions:(NSDictionary*)dict;
// The options provided by the plug-in
- (APPLocalNotificationOptions*) options;
// Fully configured request to add the notification to the notification center
- (UNNotificationRequest*) request;
// Encode the user info dict to JSON
- (NSString*) encodeToJSON;
@end
......@@ -35,8 +35,11 @@ static char optionsKey;
#pragma mark Init
/**
* Initialize a local notification with the given options when calling on JS side:
* notification.local.add(options)
* Initialize a notification with the given options.
*
* @param [ NSDictionary* ] dict A key-value property map.
*
* @return [ UNMutableNotificationContent ]
*/
- (id) initWithOptions:(NSDictionary*)dict
{
......@@ -49,9 +52,9 @@ static char optionsKey;
}
/**
* Applies the given options when calling on JS side:
* notification.local.add(options)
* Initialize a notification by using the options found under userInfo.
*
* @return [ Void ]
*/
- (void) __init
{
......@@ -65,10 +68,12 @@ static char optionsKey;
}
#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
{
......@@ -85,25 +90,10 @@ 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
* all informations about trigger behavior.
*
* @return [ UNNotificationRequest* ]
*/
- (UNNotificationRequest*) request
{
......@@ -116,6 +106,8 @@ static char optionsKey;
/**
* Encode the user info dict to JSON.
*
* @return [ NSString* ]
*/
- (NSString*) encodeToJSON
{
......@@ -139,4 +131,30 @@ static char optionsKey;
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
......@@ -21,6 +21,8 @@
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPLocalNotificationOptions.h"
@import UserNotifications;
@interface UNNotificationRequest (APPLocalNotification)
......
......@@ -21,9 +21,9 @@
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "UNMutableNotificationContent+APPLocalNotification.h"
#import "APPLocalNotificationOptions.h"
#import "UNNotificationRequest+APPLocalNotification.h"
#import "UNMutableNotificationContent+APPLocalNotification.h"
#import <objc/runtime.h>
@import UserNotifications;
......
......@@ -55,66 +55,39 @@ exports.requestPermission = function (callback, scope) {
exec(fn, null, 'LocalNotification', 'request', []);
};
// /**
// * Returns the default settings.
// *
// * @return {Object}
// */
// exports.getDefaults = function () {
// return this._defaults;
// };
// /**
// * Overwrite default settings.
// *
// * @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) {
/**
* Schedule notifications.
*
* @param [ Array ] notifications The notifications to schedule.
* @param [ Function ] callback The function to be exec as the callback.
* @param [ Object ] scope The callback function's scope.
* @param [ Object ] args Optional flags how to schedule.
*
* @return [ Void ]
*/
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++) {
// var notification = notifications[i];
for (var i = 0; i < notifications.length; i++) {
var notification = notifications[i];
// this.mergeWithDefaults(notification);
// this.convertProperties(notification);
// }
this.mergeWithDefaults(notification);
this.convertProperties(notification);
}
// this.exec('schedule', notifications, callback, scope);
// };
this.exec('schedule', notifications, callback, scope);
};
// if (args && args.skipPermission) {
// fn.call(this, true);
// } else {
// this.registerPermission(fn, this);
// }
// };
if (args && args.skipPermission) {
fn.call(this, true);
} else {
this.requestPermission(fn, this);
}
};
// /**
// * Update existing notifications specified by IDs in options.
......@@ -435,55 +408,75 @@ exports.requestPermission = function (callback, scope) {
// this.exec('getTriggered', null, callback, scope);
// };
/**
* The (platform specific) default settings.
*
* @return [ Object ]
*/
exports.getDefaults = function () {
return this._defaults;
};
// /**********
// * EVENTS *
// **********/
/**
* Overwrite default settings.
*
* @param [ Object ] newDefaults New default values.
*
* @return [ Void ]
*/
exports.setDefaults = function (newDefaults) {
var defaults = this.getDefaults();
// /**
// * Register callback for given event.
// *
// * @param {String} event
// * The event's name
// * @param {Function} callback
// * The function to be exec as callback
// * @param {Object?} scope
// * The callback function's scope
// */
// exports.on = function (event, callback, scope) {
for (var key in defaults) {
if (newDefaults.hasOwnProperty(key)) {
defaults[key] = newDefaults[key];
}
}
};
// if (typeof callback !== "function")
// return;
/**
* 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 (!this._listener[event]) {
// this._listener[event] = [];
// }
if (typeof callback !== "function")
return;
// var item = [callback, scope || window];
if (!this._listener[event]) {
this._listener[event] = [];
}
// this._listener[event].push(item);
// };
var item = [callback, scope || window];
// /**
// * Unregister callback for given event.
// *
// * @param {String} event
// * The event's name
// * @param {Function} callback
// * The function to be exec as callback
// */
// exports.un = function (event, callback) {
// var listener = this._listener[event];
this._listener[event].push(item);
};
// if (!listener)
// return;
/**
* 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];
// for (var i = 0; i < listener.length; i++) {
// var fn = listener[i][0];
if (!listener)
return;
// if (fn == callback) {
// listener.splice(i, 1);
// break;
// }
// }
// };
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0];
if (fn == callback) {
listener.splice(i, 1);
break;
}
}
};
......@@ -15,166 +15,140 @@
* limitations under the License.
*/
// var exec = require('cordova/exec'),
// channel = require('cordova/channel');
// /***********
// * MEMBERS *
// ***********/
// // Default values
// exports._defaults = {
// text: '',
// title: '',
// sound: 'res://platform_default',
// badge: 0,
// id: 0,
// data: undefined,
// every: undefined,
// at: undefined
// };
// // listener
// exports._listener = {};
// /********
// * UTIL *
// ********/
// /**
// * Merge platform specific properties into the default ones.
// *
// * @return {Object}
// * The default properties for the platform
// */
// exports.applyPlatformSpecificOptions = function () {
// var defaults = this._defaults;
// switch (device.platform) {
// case 'Android':
// defaults.icon = 'res://ic_popup_reminder';
// defaults.smallIcon = undefined;
// defaults.ongoing = false;
// defaults.autoClear = true;
// defaults.led = undefined;
// defaults.color = undefined;
// break;
// }
// return defaults;
// };
// /**
// * Merge custom properties with the default values.
// *
// * @param {Object} options
// * Set of custom values
// *
// * @retrun {Object}
// * The merged property list
// */
// exports.mergeWithDefaults = function (options) {
// var defaults = this.getDefaults();
// options.at = this.getValueFor(options, 'at', 'firstAt', 'date');
// options.text = this.getValueFor(options, 'text', 'message');
// options.data = this.getValueFor(options, 'data', 'json');
// if (defaults.hasOwnProperty('autoClear')) {
// options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel');
// }
// if (options.autoClear !== true && options.ongoing) {
// options.autoClear = false;
// }
// if (options.at === undefined || options.at === null) {
// options.at = new Date();
// }
// for (var key in defaults) {
// if (options[key] === null || options[key] === undefined) {
// if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
// options[key] = undefined;
// } else {
// options[key] = defaults[key];
// }
// }
// }
// for (key in options) {
// if (!defaults.hasOwnProperty(key)) {
// delete options[key];
// console.warn('Unknown property: ' + key);
// }
// }
// return options;
// };
// /**
// * Convert the passed values to their required type.
// *
// * @param {Object} options
// * Set of custom values
// *
// * @retrun {Object}
// * The converted property list
// */
// exports.convertProperties = function (options) {
// if (options.id) {
// if (isNaN(options.id)) {
// options.id = this.getDefaults().id;
// console.warn('Id is not a number: ' + options.id);
// } else {
// options.id = Number(options.id);
// }
// }
// if (options.title) {
// options.title = options.title.toString();
// }
// if (options.text) {
// options.text = options.text.toString();
// }
// if (options.badge) {
// if (isNaN(options.badge)) {
// options.badge = this.getDefaults().badge;
// console.warn('Badge number is not a number: ' + options.id);
// } else {
// options.badge = Number(options.badge);
// }
// }
// 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;
// };
var exec = require('cordova/exec'),
channel = require('cordova/channel');
// Default values
exports._defaults = {
text: '',
title: '',
sound: 'res://platform_default',
badge: 0,
id: 0,
data: undefined,
every: undefined,
at: undefined
};
// Listener
exports._listener = {};
/**
* Merge platform specific properties into the default ones.
*
* @return [ Void ]
*/
exports.applyPlatformSpecificOptions = function () {
var defaults = this._defaults;
switch (device.platform) {
case 'Android':
defaults.icon = 'res://ic_popup_reminder';
defaults.smallIcon = undefined;
defaults.ongoing = false;
defaults.autoClear = true;
defaults.led = undefined;
defaults.color = undefined;
break;
}
};
/**
* Merge custom properties with the default values.
*
* @param [ Object ] options Set of custom values.
*
* @retrun [ Object ]
*/
exports.mergeWithDefaults = function (options) {
var defaults = this.getDefaults();
options.at = this.getValueFor(options, 'at', 'firstAt', 'date');
options.text = this.getValueFor(options, 'text', 'message');
options.data = this.getValueFor(options, 'data', 'json');
if (defaults.hasOwnProperty('autoClear')) {
options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel');
}
if (options.autoClear !== true && options.ongoing) {
options.autoClear = false;
}
if (options.at === undefined || options.at === null) {
options.at = new Date();
}
for (var key in defaults) {
if (options[key] === null || options[key] === undefined) {
if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) {
options[key] = undefined;
} else {
options[key] = defaults[key];
}
}
}
for (key in options) {
if (!defaults.hasOwnProperty(key)) {
delete options[key];
console.warn('Unknown property: ' + key);
}
}
return options;
};
/**
* Convert the passed values to their required type.
*
* @param [ Object ] options Properties to convert for.
*
* @return [ Object ] The converted property list
*/
exports.convertProperties = function (options) {
if (options.id) {
if (isNaN(options.id)) {
options.id = this.getDefaults().id;
console.warn('Id is not a number: ' + options.id);
} else {
options.id = Number(options.id);
}
}
if (options.title) {
options.title = options.title.toString();
}
if (options.text) {
options.text = options.text.toString();
}
if (options.badge) {
if (isNaN(options.badge)) {
options.badge = this.getDefaults().badge;
console.warn('Badge number is not a number: ' + options.id);
} else {
options.badge = Number(options.badge);
}
}
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);
}
return options;
};
/**
* Create a callback function to get executed within a specific scope.
......@@ -194,108 +168,101 @@ exports.createCallbackFn = function (fn, scope) {
};
};
// /**
// * Convert the IDs to numbers.
// *
// * @param {String/Number[]} ids
// *
// * @return Array of Numbers
// */
// exports.convertIds = function (ids) {
// var convertedIds = [];
// for (var i = 0; i < ids.length; i++) {
// convertedIds.push(Number(ids[i]));
// }
// return convertedIds;
// };
// /**
// * First found value for the given keys.
// *
// * @param {Object} options
// * Object with key-value properties
// * @param {String[]} keys*
// * Key list
// */
// exports.getValueFor = function (options) {
// var keys = Array.apply(null, arguments).slice(1);
// for (var i = 0; i < keys.length; i++) {
// var key = keys[i];
// if (options.hasOwnProperty(key)) {
// return options[key];
// }
// }
// };
// /**
// * Fire event with given arguments.
// *
// * @param {String} event
// * The event's name
// * @param {args*}
// * The callback's arguments
// */
// exports.fireEvent = function (event) {
// var args = Array.apply(null, arguments).slice(1),
// listener = this._listener[event];
// if (!listener)
// return;
// for (var i = 0; i < listener.length; i++) {
// var fn = listener[i][0],
// scope = listener[i][1];
// fn.apply(scope, args);
// }
// };
// /**
// * Execute the native counterpart.
// *
// * @param {String} action
// * The name of the action
// * @param args[]
// * Array of arguments
// * @param {Function} callback
// * The callback function
// * @param {Object} scope
// * The scope for the function
// */
// exports.exec = function (action, args, callback, scope) {
// var fn = this.createCallbackFn(callback, scope),
// params = [];
// if (Array.isArray(args)) {
// params = args;
// } else if (args) {
// params.push(args);
// }
// exec(fn, null, 'LocalNotification', action, params);
// };
// /*********
// * HOOKS *
// *********/
// // Called after 'deviceready' event
// channel.deviceready.subscribe(function () {
// // Device is ready now, the listeners are registered
// // and all queued events can be executed.
// exec(null, null, 'LocalNotification', 'deviceready', []);
// });
// // Called before 'deviceready' event
// channel.onCordovaReady.subscribe(function () {
// // Device plugin is ready now
// channel.onCordovaInfoReady.subscribe(function () {
// // Merge platform specifics into defaults
// exports.applyPlatformSpecificOptions();
// });
// });
/**
* Convert the IDs to numbers.
*
* @param [ Array ] ids
*
* @return [ Array<Number> ]
*/
exports.convertIds = function (ids) {
var convertedIds = [];
for (var i = 0; i < ids.length; i++) {
convertedIds.push(Number(ids[i]));
}
return convertedIds;
};
/**
* First found value for the given keys.
*
* @param [ Object ] options Object with key-value properties.
* @param [ *Array<String> ] keys List of keys.
*
* @return [ Object ]
*/
exports.getValueFor = function (options) {
var keys = Array.apply(null, arguments).slice(1);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (options.hasOwnProperty(key)) {
return options[key];
}
}
};
/**
* Fire the event with given arguments.
*
* @param [ String ] event The event's name.
* @param [ *Array] args The callback's arguments.
*
* @return [ Void]
*/
exports.fireEvent = function (event) {
var args = Array.apply(null, arguments).slice(1),
listener = this._listener[event];
if (!listener)
return;
for (var i = 0; i < listener.length; i++) {
var fn = listener[i][0],
scope = listener[i][1];
fn.apply(scope, args);
}
};
/**
* Execute the native counterpart.
*
* @param [ String ] action The name of the action.
* @param [ Array ] args Array of arguments.
* @param [ Function] callback The callback function.
* @param [ Object ] scope The scope for the function.
*
* @return [ Void ]
*/
exports.exec = function (action, args, callback, scope) {
var fn = this.createCallbackFn(callback, scope),
params = [];
if (Array.isArray(args)) {
params = args;
} else if (args) {
params.push(args);
}
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.
exec(null, null, 'LocalNotification', 'deviceready', []);
});
// 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 @@
* limitations under the License.
*/
var exec = require('cordova/exec');
/**
* Request permission to show notifications.
*
......@@ -24,7 +26,14 @@
* @return [ Void ]
*/
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) {
* @return [ Void ]
*/
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.
// *
// * @return {Object}
// */
// exports.getDefaults = function () {
// return this.core.getDefaults();
// };
/**
* Schedule notifications.
*
* @param [ Array ] notifications The notifications to schedule.
* @param [ Function ] callback The function to be exec as the callback.
* @param [ Object ] scope The callback function's scope.
* @param [ Object ] args Optional flags how to schedule.
*
* @return [ Void ]
*/
exports.schedule = function (msgs, callback, scope, args) {
var fn = function (granted) {
// /**
// * Overwrite default settings.
// *
// * @param {Object} defaults
// */
// exports.setDefaults = function (defaults) {
// this.core.setDefaults(defaults);
// };
if (!granted) return;
// /**
// * Schedule a new local notification.
// *
// * @param {Object} notifications
// * 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 (notifications, callback, scope, args) {
// this.core.schedule(notifications, callback, scope, args);
// };
var notifications = Array.isArray(msgs) ? msgs : [msgs];
for (var i = 0; i < notifications.length; i++) {
var notification = notifications[i];
this.mergeWithDefaults(notification);
this.convertProperties(notification);
}
this.exec('schedule', notifications, callback, scope);
};
if (args && args.skipPermission) {
fn.call(this, true);
} else {
this.requestPermission(fn, this);
}
};
// /**
// * Update existing notifications specified by IDs in options.
......@@ -87,8 +102,27 @@ exports.requestPermission = function (callback, scope) {
// * skipPermission:true schedules the notifications immediatly without
// * registering or checking for permission
// */
// exports.update = function (notifications, callback, scope, args) {
// this.core.update(notifications, callback, scope, args);
// exports.update = function (msgs, 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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.
// *
// * @param {String} id
......@@ -180,21 +220,21 @@ exports.requestPermission = function (callback, scope) {
// * A callback function to be called with the list
// * @param {Object?} scope
// * The scope for the callback function
// */
// exports.isTriggered = function (id, callback, scope) {
// this.core.isTriggered(id, callback, scope);
// this.exec('isTriggered', id || 0, callback, scope);
// };
// /**
// *
// * List all local notification IDs.
// *
// * @param {Function} callback
// * A callback function to be called with the list
// * @param {Object?} scope
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback 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) {
// * The scope for the callback function
// */
// 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) {
// * The scope for the callback 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) {
// * The scope for the callback function
// */
// exports.getAllTriggered = function (callback, scope) {
// this.core.getAllTriggered(callback, scope);
// this.exec('getTriggered', null, callback, scope);
// };
// /**
// * Register callback for given event.
// *
// * @param {String} event
// * The event's name
// * @param {Function} callback
// * The function to be exec as callback
// * @param {Object?} scope
// * The callback function's scope
// */
// exports.on = function (event, callback, scope) {
// this.core.on(event, callback, scope);
// };
/**
* The (platform specific) default settings.
*
* @return [ Object ]
*/
exports.getDefaults = function () {
return this._defaults;
};
// /**
// * Unregister callback for given event.
// *
// * @param {String} event
// * The event's name
// * @param {Function} callback
// * The function to be exec as callback
// */
// exports.un = function (event, callback) {
// this.core.un(event, callback);
// };
/**
* Overwrite default settings.
*
* @param [ Object ] newDefaults New default values.
*
* @return [ Void ]
*/
exports.setDefaults = function (newDefaults) {
var defaults = this.getDefaults();
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