Commit 9c65b6c2 by Sebastián Katzer

Update to latest dev

parent 6540f331
/*
* Copyright (c) 2013 by appPlant GmbH. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import <Cordova/CDVPlugin.h>
......@@ -27,6 +21,8 @@
@interface APPLocalNotification : CDVPlugin <UNUserNotificationCenterDelegate>
// Set launchDetails object
- (void) launchDetails:(CDVInvokedUrlCommand*)command;
// Execute all queued events
- (void) deviceready:(CDVInvokedUrlCommand*)command;
......
/*
* Copyright (c) 2013 by appPlant GmbH. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPLocalNotification.h"
......@@ -32,6 +26,7 @@
@property (strong, nonatomic) UIApplication* app;
@property (strong, nonatomic) UNUserNotificationCenter* center;
@property (readwrite, assign) BOOL deviceready;
@property (readonly, nonatomic, retain) NSArray* launchDetails;
@property (readonly, nonatomic, retain) NSMutableArray* eventQueue;
@end
......@@ -44,6 +39,27 @@
#pragma mark Interface
/**
* Set launchDetails object.
*
* @return [ Void ]
*/
- (void) launchDetails:(CDVInvokedUrlCommand*)command
{
if (!_launchDetails)
return;
NSString* js;
js = [NSString stringWithFormat:
@"cordova.plugins.notification.local.launchDetails = {id:%@, action:'%@'}",
_launchDetails[0], _launchDetails[1]];
[self.commandDelegate evalJs:js];
_launchDetails = NULL;
}
/**
* Execute all queued events.
*
* @return [ Void ]
......@@ -512,10 +528,10 @@
[self.commandDelegate runInBackground:^{
NSDictionary* options = command.arguments[0];
APPNotificationContent* notification;
notification = [[APPNotificationContent alloc]
initWithOptions:options];
[_center addNotificationCategory:notification.category];
[self execCallback:command];
}];
......@@ -533,7 +549,7 @@
UNNotificationRequest* request = notification.request;
[_center addNotificationCategory:notification.category];
[_center addNotificationRequest:request withCompletionHandler:^(NSError* e) {
__strong APPLocalNotification* strongSelf = weakSelf;
[strongSelf fireEvent:@"add" notification:request];
......@@ -583,6 +599,8 @@
NSString* action = response.actionIdentifier;
NSString* event = action;
completionHandler();
if ([action isEqualToString:UNNotificationDefaultActionIdentifier]) {
event = @"click";
} else
......@@ -590,9 +608,15 @@
event = @"clear";
}
[self fireEvent:event notification:notification];
if (!deviceready && [event isEqualToString:@"click"]) {
_launchDetails = @[notification.options.id, event];
}
completionHandler();
if (![event isEqualToString:@"clear"]) {
[self fireEvent:@"clear" notification:notification];
}
[self fireEvent:event notification:notification];
}
#pragma mark -
......@@ -663,12 +687,12 @@
- (void) fireEvent:(NSString*)event
notification:(UNNotificationRequest*)request
{
NSString* js;
NSString* appState = [self applicationState];
NSString* params = [NSString stringWithFormat:@"\"%@\"", appState];
NSString *js;
NSString *appState = [self applicationState];
NSString *params = [NSString stringWithFormat:@"\"%@\"", appState];
if (request) {
NSString* args = [request encodeToJSON];
NSString *args = [request encodeToJSON];
params = [NSString stringWithFormat:@"%@,'%@'", args, appState];
}
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
@import UserNotifications;
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,13 +13,12 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
#import "UNUserNotificationCenter+APPLocalNotification.h"
@import CoreLocation;
@import UserNotifications;
@interface APPNotificationOptions ()
......@@ -52,7 +47,7 @@
self = [self init];
self.dict = dictionary;
[self actions];
return self;
......@@ -62,6 +57,18 @@
#pragma mark Properties
/**
* The type for the notification.
*
* @return [ NSString* ]
*/
- (NSString*) type
{
NSString* type = [dict objectForKey:@"type"];
return type.length ? type : @"normal";
}
/**
* The ID for the notification.
*
* @return [ NSNumber* ]
......@@ -123,7 +130,7 @@
- (NSNumber*) badge
{
id value = [dict objectForKey:@"badge"];
return (value == NULL) ? NULL : [NSNumber numberWithInt:[value intValue]];
}
......@@ -135,7 +142,7 @@
- (NSString*) categoryId
{
NSString* value = [dict objectForKey:@"actionGroupId"];
return value.length ? value : kAPPGeneralCategory;
}
......@@ -175,10 +182,10 @@
{
NSArray* paths = [dict objectForKey:@"attachments"];
NSMutableArray* attachments = [[NSMutableArray alloc] init];
if (!paths)
return attachments;
for (NSString* path in paths) {
NSURL* url = [self urlForAttachmentPath:path];
......@@ -187,12 +194,12 @@
URL:url
options:NULL
error:NULL];
if (attachment) {
[attachments addObject:attachment];
}
}
return attachments;
}
......@@ -205,35 +212,57 @@
{
NSArray* items = [dict objectForKey:@"actions"];
NSMutableArray* actions = [[NSMutableArray alloc] init];
if (!items)
return actions;
for (NSDictionary* item in items) {
NSString* id = [item objectForKey:@"id"];
NSString* title = [item objectForKey:@"title"];
NSString* type = [item objectForKey:@"type"];
UNNotificationActionOptions options = UNNotificationActionOptionNone;
UNNotificationAction* action;
if ([[item objectForKey:@"launch"] boolValue]) {
options = UNNotificationActionOptionForeground;
}
if ([[item objectForKey:@"ui"] isEqualToString:@"decline"]) {
options = options | UNNotificationActionOptionDestructive;
}
if ([[item objectForKey:@"needsAuth"] boolValue]) {
options = options | UNNotificationActionOptionAuthenticationRequired;
}
UNNotificationAction* action;
action = [UNNotificationAction actionWithIdentifier:id
title:title
options:options];
[actions addObject:action];
if ([type isEqualToString:@"input"]) {
NSString* submitTitle = [item objectForKey:@"submitTitle"];
NSString* placeholder = [item objectForKey:@"emptyText"];
if (!submitTitle.length) {
submitTitle = @"Submit";
}
action = [UNTextInputNotificationAction actionWithIdentifier:id
title:title
options:options
textInputButtonTitle:submitTitle
textInputPlaceholder:placeholder];
} else
if (!type.length || [type isEqualToString:@"button"]) {
action = [UNNotificationAction actionWithIdentifier:id
title:title
options:options];
} else {
NSLog(@"Unknown action type: %@", type);
}
if (action) {
[actions addObject:action];
}
}
return actions;
}
......@@ -247,6 +276,14 @@
*/
- (UNNotificationTrigger*) trigger
{
NSString* type = [self type];
if ([type isEqualToString:@"location"])
return [self triggerWithRegion];
if (![type isEqualToString:@"normal"])
NSLog(@"Unknown type: %@", type);
if ([self isRepeating])
return [self repeatingTrigger];
......@@ -283,7 +320,7 @@
{
double timestamp = [[dict objectForKey:@"at"]
doubleValue];
return [NSDate dateWithTimeIntervalSince1970:timestamp];
}
......@@ -326,12 +363,12 @@
id every = [dict objectForKey:@"every"];
if ([every isKindOfClass:NSString.class])
return [self repeatingTriggerWithDateMatchingComponents];
return [self triggerWithDateMatchingComponents];
if ([every isKindOfClass:NSDictionary.class])
return [self repeatingTriggerWithCustomDateMatchingComponents];
return [self triggerWithCustomDateMatchingComponents];
return [self repeatingTriggerWithTimeInterval];
return [self triggerWithTimeInterval];
}
/**
......@@ -339,7 +376,7 @@
*
* @return [ UNTimeIntervalNotificationTrigger* ]
*/
- (UNTimeIntervalNotificationTrigger*) repeatingTriggerWithTimeInterval
- (UNTimeIntervalNotificationTrigger*) triggerWithTimeInterval
{
long interval = [[dict objectForKey:@"every"] longValue];
......@@ -357,7 +394,7 @@
*
* @return [ UNCalendarNotificationTrigger* ]
*/
- (UNCalendarNotificationTrigger*) repeatingTriggerWithDateMatchingComponents
- (UNCalendarNotificationTrigger*) triggerWithDateMatchingComponents
{
NSCalendar* cal = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
......@@ -376,7 +413,7 @@
*
* @return [ UNCalendarNotificationTrigger* ]
*/
- (UNCalendarNotificationTrigger*) repeatingTriggerWithCustomDateMatchingComponents
- (UNCalendarNotificationTrigger*) triggerWithCustomDateMatchingComponents
{
NSCalendar* cal = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
......@@ -391,6 +428,30 @@
}
/**
* A repeating trigger based on a location region.
*
* @return [ UNLocationNotificationTrigger* ]
*/
- (UNLocationNotificationTrigger*) triggerWithRegion
{
NSArray* center = [dict objectForKey:@"center"];
double radius = [[dict objectForKey:@"radius"] doubleValue];
CLLocationCoordinate2D coord =
CLLocationCoordinate2DMake([center[0] doubleValue], [center[1] doubleValue]);
CLCircularRegion* region =
[[CLCircularRegion alloc] initWithCenter:coord
radius:radius
identifier:self.identifier];
region.notifyOnEntry = [[dict objectForKey:@"notifyOnEntry"] boolValue];
region.notifyOnExit = [[dict objectForKey:@"notifyOnExit"] boolValue];
return [UNLocationNotificationTrigger triggerWithRegion:region repeats:YES];
}
/**
* The time interval between the next fire date and now.
*
* @return [ double ]
......@@ -580,7 +641,7 @@
if ([path isEqualToString:@"res://icon"]) {
path = @"res://AppIcon60x60@3x.png";
}
NSString* absPath;
absPath = [path stringByReplacingOccurrencesOfString:@"res:/"
withString:@""];
......@@ -606,7 +667,7 @@
NSFileManager* fm = [NSFileManager defaultManager];
NSBundle* mainBundle = [NSBundle mainBundle];
NSString* bundlePath = [mainBundle bundlePath];
NSString* absPath;
absPath = [path stringByReplacingOccurrencesOfString:@"file:/"
withString:@"/www"];
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "UNUserNotificationCenter+APPLocalNotification.h"
......@@ -62,17 +56,17 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
{
if (!category)
return;
[self getNotificationCategoriesWithCompletionHandler:^(NSSet<UNNotificationCategory *> *set) {
NSMutableSet* categories = [NSMutableSet setWithSet:set];
for (UNNotificationCategory* item in categories) {
if ([category.identifier isEqualToString:item.identifier]) {
[categories removeObject:item];
break;
}
}
[categories addObject:category];
[self setNotificationCategories:categories];
}];
......
{
"libz.tbd": 1,
"QuartzCore.framework": 1,
"UserNotifications.framework": 1
"UserNotifications.framework": 1,
"CoreLocation.framework": 1
}
\ No newline at end of file
......@@ -22,6 +22,7 @@ var exec = require('cordova/exec'),
// Default values
exports._defaults = {
id: 0,
type: 'normal',
text: '',
title: '',
sound: 'res://platform_default',
......@@ -55,6 +56,8 @@ exports.applyPlatformSpecificOptions = function () {
break;
case 'iOS':
defaults.attachments = undefined;
defaults.region = undefined;
defaults.radius = undefined;
break;
}
};
......@@ -303,11 +306,13 @@ exports.exec = function (action, args, callback, scope) {
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// and all queued events can be executed.
exec(null, null, 'LocalNotification', 'deviceready', []);
exports.exec('deviceready');
});
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Set launchDetails object
exports.exec('launchDetails');
// Device plugin is ready now
channel.onCordovaInfoReady.subscribe(function () {
// Merge platform specifics into defaults
......
......@@ -76,6 +76,12 @@ var app = {
document.getElementById('multiple_nots').onclick = app.multipleNots;
document.getElementById('notifications').onclick = app.notifications;
document.getElementById('defaults').onclick = app.setDefaultTitle;
var details = cordova.plugins.notification.local.launchDetails;
if (details) {
alert('Launched by notification with ID ' + details.id);
}
},
// Check permissions to read accounts
hasPermission: function () {
......@@ -157,12 +163,20 @@ var app = {
actionGroupId: 'like-dislike',
actions: [{
id: 'like',
type: 'button',
title: 'Like',
launch: true
},{
id: 'dislike',
type: 'button',
title: 'Dislike',
ui: 'decline'
},{
id: 'feedback',
type: 'input',
title: 'Feedback',
emptyText: 'Enter feedback',
submitTitle: 'Send'
}]
});
},
......@@ -272,37 +286,45 @@ var app = {
// Listen for events
bindNotificationEvents: function () {
cordova.plugins.notification.local.on('schedule', function (obj) {
console.log('onschedule', arguments);
console.log('schedule', arguments);
// showToast('scheduled: ' + obj.id);
});
cordova.plugins.notification.local.on('update', function (obj) {
console.log('onupdate', arguments);
console.log('update', arguments);
// showToast('updated: ' + obj.id);
});
cordova.plugins.notification.local.on('trigger', function (obj) {
console.log('ontrigger', arguments);
console.log('trigger', arguments);
showToast('triggered: ' + obj.id);
});
cordova.plugins.notification.local.on('click', function (obj) {
console.log('onclick', arguments);
console.log('click', arguments);
showToast('clicked: ' + obj.id);
});
cordova.plugins.notification.local.on('cancel', function (obj) {
console.log('oncancel', arguments);
console.log('cancel', arguments);
// showToast('canceled: ' + obj.id);
});
cordova.plugins.notification.local.on('clear', function (obj) {
console.log('onclear', arguments);
console.log('clear', arguments);
showToast('cleared: ' + obj.id);
});
cordova.plugins.notification.local.on('cancelall', function () {
console.log('oncancelall', arguments);
console.log('cancelall', arguments);
// showToast('canceled all');
});
cordova.plugins.notification.local.on('clearall', function () {
console.log('onclearall', arguments);
console.log('clearall', arguments);
// showToast('cleared all');
});
cordova.plugins.notification.local.on('like', function () {
console.log('like', arguments);
showToast('liked');
});
cordova.plugins.notification.local.on('dislike', function () {
console.log('dislike', arguments);
showToast('disliked');
});
}
};
......
......@@ -22,6 +22,7 @@ var exec = require('cordova/exec'),
// Default values
exports._defaults = {
id: 0,
type: 'normal',
text: '',
title: '',
sound: 'res://platform_default',
......@@ -55,6 +56,8 @@ exports.applyPlatformSpecificOptions = function () {
break;
case 'iOS':
defaults.attachments = undefined;
defaults.region = undefined;
defaults.radius = undefined;
break;
}
};
......@@ -303,11 +306,13 @@ exports.exec = function (action, args, callback, scope) {
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// and all queued events can be executed.
exec(null, null, 'LocalNotification', 'deviceready', []);
exports.exec('deviceready');
});
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Set launchDetails object
exports.exec('launchDetails');
// Device plugin is ready now
channel.onCordovaInfoReady.subscribe(function () {
// Merge platform specifics into defaults
......
......@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2013-2015 appPlant UG, Inc.
Copyright 2013 appPlant GmbH
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
......
......@@ -54,6 +54,7 @@
</config-file>
<framework src="UserNotifications.framework" />
<framework src="CoreLocation.framework" />
<header-file src="src/ios/APPLocalNotification.h" />
<source-file src="src/ios/APPLocalNotification.m" />
......
/*
* Copyright (c) 2013 by appPlant GmbH. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import <Cordova/CDVPlugin.h>
......@@ -27,6 +21,8 @@
@interface APPLocalNotification : CDVPlugin <UNUserNotificationCenterDelegate>
// Set launchDetails object
- (void) launchDetails:(CDVInvokedUrlCommand*)command;
// Execute all queued events
- (void) deviceready:(CDVInvokedUrlCommand*)command;
......
/*
* Copyright (c) 2013 by appPlant GmbH. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPLocalNotification.h"
......@@ -32,6 +26,7 @@
@property (strong, nonatomic) UIApplication* app;
@property (strong, nonatomic) UNUserNotificationCenter* center;
@property (readwrite, assign) BOOL deviceready;
@property (readonly, nonatomic, retain) NSArray* launchDetails;
@property (readonly, nonatomic, retain) NSMutableArray* eventQueue;
@end
......@@ -44,6 +39,27 @@
#pragma mark Interface
/**
* Set launchDetails object.
*
* @return [ Void ]
*/
- (void) launchDetails:(CDVInvokedUrlCommand*)command
{
if (!_launchDetails)
return;
NSString* js;
js = [NSString stringWithFormat:
@"cordova.plugins.notification.local.launchDetails = {id:%@, action:'%@'}",
_launchDetails[0], _launchDetails[1]];
[self.commandDelegate evalJs:js];
_launchDetails = NULL;
}
/**
* Execute all queued events.
*
* @return [ Void ]
......@@ -512,10 +528,10 @@
[self.commandDelegate runInBackground:^{
NSDictionary* options = command.arguments[0];
APPNotificationContent* notification;
notification = [[APPNotificationContent alloc]
initWithOptions:options];
[_center addNotificationCategory:notification.category];
[self execCallback:command];
}];
......@@ -533,7 +549,7 @@
UNNotificationRequest* request = notification.request;
[_center addNotificationCategory:notification.category];
[_center addNotificationRequest:request withCompletionHandler:^(NSError* e) {
__strong APPLocalNotification* strongSelf = weakSelf;
[strongSelf fireEvent:@"add" notification:request];
......@@ -583,6 +599,8 @@
NSString* action = response.actionIdentifier;
NSString* event = action;
completionHandler();
if ([action isEqualToString:UNNotificationDefaultActionIdentifier]) {
event = @"click";
} else
......@@ -590,9 +608,15 @@
event = @"clear";
}
[self fireEvent:event notification:notification];
if (!deviceready && [event isEqualToString:@"click"]) {
_launchDetails = @[notification.options.id, event];
}
completionHandler();
if (![event isEqualToString:@"clear"]) {
[self fireEvent:@"clear" notification:notification];
}
[self fireEvent:event notification:notification];
}
#pragma mark -
......@@ -663,12 +687,12 @@
- (void) fireEvent:(NSString*)event
notification:(UNNotificationRequest*)request
{
NSString* js;
NSString* appState = [self applicationState];
NSString* params = [NSString stringWithFormat:@"\"%@\"", appState];
NSString *js;
NSString *appState = [self applicationState];
NSString *params = [NSString stringWithFormat:@"\"%@\"", appState];
if (request) {
NSString* args = [request encodeToJSON];
NSString *args = [request encodeToJSON];
params = [NSString stringWithFormat:@"%@,'%@'", args, appState];
}
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
@import UserNotifications;
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,13 +13,12 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
#import "UNUserNotificationCenter+APPLocalNotification.h"
@import CoreLocation;
@import UserNotifications;
@interface APPNotificationOptions ()
......@@ -52,7 +47,7 @@
self = [self init];
self.dict = dictionary;
[self actions];
return self;
......@@ -62,6 +57,18 @@
#pragma mark Properties
/**
* The type for the notification.
*
* @return [ NSString* ]
*/
- (NSString*) type
{
NSString* type = [dict objectForKey:@"type"];
return type.length ? type : @"normal";
}
/**
* The ID for the notification.
*
* @return [ NSNumber* ]
......@@ -123,7 +130,7 @@
- (NSNumber*) badge
{
id value = [dict objectForKey:@"badge"];
return (value == NULL) ? NULL : [NSNumber numberWithInt:[value intValue]];
}
......@@ -135,7 +142,7 @@
- (NSString*) categoryId
{
NSString* value = [dict objectForKey:@"actionGroupId"];
return value.length ? value : kAPPGeneralCategory;
}
......@@ -175,10 +182,10 @@
{
NSArray* paths = [dict objectForKey:@"attachments"];
NSMutableArray* attachments = [[NSMutableArray alloc] init];
if (!paths)
return attachments;
for (NSString* path in paths) {
NSURL* url = [self urlForAttachmentPath:path];
......@@ -187,12 +194,12 @@
URL:url
options:NULL
error:NULL];
if (attachment) {
[attachments addObject:attachment];
}
}
return attachments;
}
......@@ -205,35 +212,57 @@
{
NSArray* items = [dict objectForKey:@"actions"];
NSMutableArray* actions = [[NSMutableArray alloc] init];
if (!items)
return actions;
for (NSDictionary* item in items) {
NSString* id = [item objectForKey:@"id"];
NSString* title = [item objectForKey:@"title"];
NSString* type = [item objectForKey:@"type"];
UNNotificationActionOptions options = UNNotificationActionOptionNone;
UNNotificationAction* action;
if ([[item objectForKey:@"launch"] boolValue]) {
options = UNNotificationActionOptionForeground;
}
if ([[item objectForKey:@"ui"] isEqualToString:@"decline"]) {
options = options | UNNotificationActionOptionDestructive;
}
if ([[item objectForKey:@"needsAuth"] boolValue]) {
options = options | UNNotificationActionOptionAuthenticationRequired;
}
UNNotificationAction* action;
action = [UNNotificationAction actionWithIdentifier:id
title:title
options:options];
[actions addObject:action];
if ([type isEqualToString:@"input"]) {
NSString* submitTitle = [item objectForKey:@"submitTitle"];
NSString* placeholder = [item objectForKey:@"emptyText"];
if (!submitTitle.length) {
submitTitle = @"Submit";
}
action = [UNTextInputNotificationAction actionWithIdentifier:id
title:title
options:options
textInputButtonTitle:submitTitle
textInputPlaceholder:placeholder];
} else
if (!type.length || [type isEqualToString:@"button"]) {
action = [UNNotificationAction actionWithIdentifier:id
title:title
options:options];
} else {
NSLog(@"Unknown action type: %@", type);
}
if (action) {
[actions addObject:action];
}
}
return actions;
}
......@@ -247,6 +276,14 @@
*/
- (UNNotificationTrigger*) trigger
{
NSString* type = [self type];
if ([type isEqualToString:@"location"])
return [self triggerWithRegion];
if (![type isEqualToString:@"normal"])
NSLog(@"Unknown type: %@", type);
if ([self isRepeating])
return [self repeatingTrigger];
......@@ -283,7 +320,7 @@
{
double timestamp = [[dict objectForKey:@"at"]
doubleValue];
return [NSDate dateWithTimeIntervalSince1970:timestamp];
}
......@@ -326,12 +363,12 @@
id every = [dict objectForKey:@"every"];
if ([every isKindOfClass:NSString.class])
return [self repeatingTriggerWithDateMatchingComponents];
return [self triggerWithDateMatchingComponents];
if ([every isKindOfClass:NSDictionary.class])
return [self repeatingTriggerWithCustomDateMatchingComponents];
return [self triggerWithCustomDateMatchingComponents];
return [self repeatingTriggerWithTimeInterval];
return [self triggerWithTimeInterval];
}
/**
......@@ -339,7 +376,7 @@
*
* @return [ UNTimeIntervalNotificationTrigger* ]
*/
- (UNTimeIntervalNotificationTrigger*) repeatingTriggerWithTimeInterval
- (UNTimeIntervalNotificationTrigger*) triggerWithTimeInterval
{
long interval = [[dict objectForKey:@"every"] longValue];
......@@ -357,7 +394,7 @@
*
* @return [ UNCalendarNotificationTrigger* ]
*/
- (UNCalendarNotificationTrigger*) repeatingTriggerWithDateMatchingComponents
- (UNCalendarNotificationTrigger*) triggerWithDateMatchingComponents
{
NSCalendar* cal = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
......@@ -376,7 +413,7 @@
*
* @return [ UNCalendarNotificationTrigger* ]
*/
- (UNCalendarNotificationTrigger*) repeatingTriggerWithCustomDateMatchingComponents
- (UNCalendarNotificationTrigger*) triggerWithCustomDateMatchingComponents
{
NSCalendar* cal = [[NSCalendar alloc]
initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
......@@ -391,6 +428,30 @@
}
/**
* A repeating trigger based on a location region.
*
* @return [ UNLocationNotificationTrigger* ]
*/
- (UNLocationNotificationTrigger*) triggerWithRegion
{
NSArray* center = [dict objectForKey:@"center"];
double radius = [[dict objectForKey:@"radius"] doubleValue];
CLLocationCoordinate2D coord =
CLLocationCoordinate2DMake([center[0] doubleValue], [center[1] doubleValue]);
CLCircularRegion* region =
[[CLCircularRegion alloc] initWithCenter:coord
radius:radius
identifier:self.identifier];
region.notifyOnEntry = [[dict objectForKey:@"notifyOnEntry"] boolValue];
region.notifyOnExit = [[dict objectForKey:@"notifyOnExit"] boolValue];
return [UNLocationNotificationTrigger triggerWithRegion:region repeats:YES];
}
/**
* The time interval between the next fire date and now.
*
* @return [ double ]
......@@ -580,7 +641,7 @@
if ([path isEqualToString:@"res://icon"]) {
path = @"res://AppIcon60x60@3x.png";
}
NSString* absPath;
absPath = [path stringByReplacingOccurrencesOfString:@"res:/"
withString:@""];
......@@ -606,7 +667,7 @@
NSFileManager* fm = [NSFileManager defaultManager];
NSBundle* mainBundle = [NSBundle mainBundle];
NSString* bundlePath = [mainBundle bundlePath];
NSString* absPath;
absPath = [path stringByReplacingOccurrencesOfString:@"file:/"
withString:@"/www"];
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationOptions.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "APPNotificationContent.h"
......
/*
* Copyright (c) 2013-2015 by appPlant UG. All rights reserved.
*
* @APPPLANT_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
......@@ -17,8 +13,6 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPPLANT_LICENSE_HEADER_END@
*/
#import "UNUserNotificationCenter+APPLocalNotification.h"
......@@ -62,17 +56,17 @@ NSString * const kAPPGeneralCategory = @"GENERAL";
{
if (!category)
return;
[self getNotificationCategoriesWithCompletionHandler:^(NSSet<UNNotificationCategory *> *set) {
NSMutableSet* categories = [NSMutableSet setWithSet:set];
for (UNNotificationCategory* item in categories) {
if ([category.identifier isEqualToString:item.identifier]) {
[categories removeObject:item];
break;
}
}
[categories addObject:category];
[self setNotificationCategories:categories];
}];
......
......@@ -21,6 +21,7 @@ var exec = require('cordova/exec'),
// Default values
exports._defaults = {
id: 0,
type: 'normal',
text: '',
title: '',
sound: 'res://platform_default',
......@@ -54,6 +55,8 @@ exports.applyPlatformSpecificOptions = function () {
break;
case 'iOS':
defaults.attachments = undefined;
defaults.region = undefined;
defaults.radius = undefined;
break;
}
};
......@@ -302,11 +305,13 @@ exports.exec = function (action, args, callback, scope) {
channel.deviceready.subscribe(function () {
// Device is ready now, the listeners are registered
// and all queued events can be executed.
exec(null, null, 'LocalNotification', 'deviceready', []);
exports.exec('deviceready');
});
// Called before 'deviceready' event
channel.onCordovaReady.subscribe(function () {
// Set launchDetails object
exports.exec('launchDetails');
// Device plugin is ready now
channel.onCordovaInfoReady.subscribe(function () {
// Merge platform specifics into defaults
......
......@@ -76,6 +76,12 @@ var app = {
document.getElementById('multiple_nots').onclick = app.multipleNots;
document.getElementById('notifications').onclick = app.notifications;
document.getElementById('defaults').onclick = app.setDefaultTitle;
var details = cordova.plugins.notification.local.launchDetails;
if (details) {
alert('Launched by notification with ID ' + details.id);
}
},
// Check permissions to read accounts
hasPermission: function () {
......@@ -157,12 +163,20 @@ var app = {
actionGroupId: 'like-dislike',
actions: [{
id: 'like',
type: 'button',
title: 'Like',
launch: true
},{
id: 'dislike',
type: 'button',
title: 'Dislike',
ui: 'decline'
},{
id: 'feedback',
type: 'input',
title: 'Feedback',
emptyText: 'Enter feedback',
submitTitle: 'Send'
}]
});
},
......@@ -272,37 +286,45 @@ var app = {
// Listen for events
bindNotificationEvents: function () {
cordova.plugins.notification.local.on('schedule', function (obj) {
console.log('onschedule', arguments);
console.log('schedule', arguments);
// showToast('scheduled: ' + obj.id);
});
cordova.plugins.notification.local.on('update', function (obj) {
console.log('onupdate', arguments);
console.log('update', arguments);
// showToast('updated: ' + obj.id);
});
cordova.plugins.notification.local.on('trigger', function (obj) {
console.log('ontrigger', arguments);
console.log('trigger', arguments);
showToast('triggered: ' + obj.id);
});
cordova.plugins.notification.local.on('click', function (obj) {
console.log('onclick', arguments);
console.log('click', arguments);
showToast('clicked: ' + obj.id);
});
cordova.plugins.notification.local.on('cancel', function (obj) {
console.log('oncancel', arguments);
console.log('cancel', arguments);
// showToast('canceled: ' + obj.id);
});
cordova.plugins.notification.local.on('clear', function (obj) {
console.log('onclear', arguments);
console.log('clear', arguments);
showToast('cleared: ' + obj.id);
});
cordova.plugins.notification.local.on('cancelall', function () {
console.log('oncancelall', arguments);
console.log('cancelall', arguments);
// showToast('canceled all');
});
cordova.plugins.notification.local.on('clearall', function () {
console.log('onclearall', arguments);
console.log('clearall', arguments);
// showToast('cleared all');
});
cordova.plugins.notification.local.on('like', function () {
console.log('like', arguments);
showToast('liked');
});
cordova.plugins.notification.local.on('dislike', function () {
console.log('dislike', arguments);
showToast('disliked');
});
}
};
......
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