APNS LaunchPad

This commit is contained in:
ChrisTomAlxNeu
2019-04-05 19:51:32 +05:30
parent fac5e348af
commit 600864c33e
9 changed files with 1582 additions and 1 deletions

20
MIT-LICENSE Normal file
View File

@@ -0,0 +1,20 @@
Copyright 2012-2017 Adobe Systems
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,2 +1,52 @@
# cordova-plugin-apns-push
APNS only push plugin | Alpha release
> Register and receive APNS push notifications
# Usage
```js
var push = window['APNSPushNotification'].init({
ios: {
alert: "true",
badge: "true",
sound: "true"
}
});
push.on('registration', (data) => {
// data.registrationId
this.sendRegDetails(data.registrationId);
});
push.on('notification', (data) => {
window['cordova'].plugins.notification.local.schedule({
title: data.title,
text: data.message,
sound: data.sound,
at: new Date().getTime()
});
});
push.on('error', (e) => {
// e.message
console.error(e);
});
```
# Supported Platforms
- iOS
# More about us
Find out more or contact us directly here :- http://www.neutrinos.co/
Facebook :- https://www.facebook.com/Neutrinos.co/ <br/>
LinkedIn :- https://www.linkedin.com/company/25057297/ <br/>
Twitter :- https://twitter.com/Neutrinosco <br/>
Instagram :- https://www.instagram.com/neutrinos.co/
[![N|Solid](https://image4.owler.com/logo/neutrinos_owler_20171023_142541_original.jpg "Neutrinos")](http://www.neutrinos.co/)

31
package.json Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "cordova-plugin-apns-push",
"description": "Register and receive APNS push notifications.",
"version": "1.0.0",
"repository": {
"type": "git",
"url": "https://github.com/NeutrinosPlatform/cordova-plugin-apns-push"
},
"bugs": {
"url": "https://github.com/NeutrinosPlatform/cordova-plugin-apns-push/issues"
},
"cordova": {
"id": "cordova-plugin-apns-push",
"platforms": [
"ios"
]
},
"keywords": [
"ecosystem:cordova",
"ecosystem:phonegap",
"cordova-ios"
],
"engines": {
"cordovaDependencies": {
"cordova": ">=7.1.0",
"cordova-ios": ">=4.5.0"
}
},
"author": "jatahworx",
"license": "MIT"
}

41
plugin.xml Normal file
View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="cordova-plugin-apns-push"
version="1.0.0">
<name>APNSPushPlugin</name>
<description> This plugin allows your application to receive apple push notifications (APNS) on iOS devices. </description>
<license>MIT</license>
<js-module src="www/apnspush.js" name="APNSPushNotification">
<clobbers target="APNSPushNotification"/>
</js-module>
<engines>
<engine name="cordova" version=">=7.1.0"/>
<engine name="cordova-ios" version=">=4.5.0"/>
</engines>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="APNSPushNotification">
<param name="ios-package" value="PushPlugin"/>
</feature>
</config-file>
<config-file target="*-Info.plist" parent="UIBackgroundModes">
<array>
<string>remote-notification</string>
</array>
</config-file>
<config-file target="*-Debug.plist" parent="aps-environment">
<string>development</string>
</config-file>
<config-file target="*-Release.plist" parent="aps-environment">
<string>production</string>
</config-file>
<source-file src="src/ios/AppDelegate+apnsnotification.m"/>
<source-file src="src/ios/APNSPushPlugin.m"/>
<header-file src="src/ios/AppDelegate+apnsnotification.h"/>
<header-file src="src/ios/APNSPushPlugin.h"/>
<framework src="PushKit.framework"/>
</platform>
</plugin>

86
src/ios/APNSPushPlugin.h Normal file
View File

@@ -0,0 +1,86 @@
/*
Copyright 2009-2011 Urban Airship Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binaryform must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided withthe distribution.
THIS SOFTWARE IS PROVIDED BY THE URBAN AIRSHIP INC``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL URBAN AIRSHIP INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@import Foundation;
@import UserNotifications;
#import <Cordova/CDV.h>
#import <Cordova/CDVPlugin.h>
#import <PushKit/PushKit.h>
@protocol GGLInstanceIDDelegate;
@protocol GCMReceiverDelegate;
@interface PushPlugin : CDVPlugin
{
NSDictionary *notificationMessage;
BOOL isInline;
NSString *notificationCallbackId;
NSString *callback;
BOOL clearBadge;
NSMutableDictionary *handlerObj;
void (^completionHandler)(UIBackgroundFetchResult);
BOOL ready;
}
@property (nonatomic, copy) NSString *callbackId;
@property (nonatomic, copy) NSString *notificationCallbackId;
@property (nonatomic, copy) NSString *callback;
@property (nonatomic, strong) NSDictionary *notificationMessage;
@property BOOL isInline;
@property BOOL coldstart;
@property BOOL clearBadge;
@property (nonatomic, strong) NSMutableDictionary *handlerObj;
- (void)init:(CDVInvokedUrlCommand*)command;
- (void)unregister:(CDVInvokedUrlCommand*)command;
- (void)subscribe:(CDVInvokedUrlCommand*)command;
- (void)unsubscribe:(CDVInvokedUrlCommand*)command;
- (void)clearNotification:(CDVInvokedUrlCommand*)command;
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
- (void)setNotificationMessage:(NSDictionary *)notification;
- (void)notificationReceived;
- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error;
- (void)didSendDataMessageWithID:(NSString *)messageID;
- (void)didDeleteMessagesOnServer;
// VoIP Features
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type;
// FCM Features
@property(nonatomic, assign) BOOL usesFCM;
@property(nonatomic, strong) NSNumber *fcmSandbox;
@property(nonatomic, strong) NSString *fcmSenderId;
@property(nonatomic, strong) NSDictionary *fcmRegistrationOptions;
@property(nonatomic, strong) NSString *fcmRegistrationToken;
@property(nonatomic, strong) NSArray *fcmTopics;
@end

646
src/ios/APNSPushPlugin.m Normal file
View File

@@ -0,0 +1,646 @@
/*
Copyright 2009-2011 Urban Airship Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binaryform must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided withthe distribution.
THIS SOFTWARE IS PROVIDED BY THE URBAN AIRSHIP INC``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL URBAN AIRSHIP INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// See GGLInstanceID.h
#define GMP_NO_MODULES true
#import "APNSPushPlugin.h"
#import "AppDelegate+apnsnotification.h"
@implementation PushPlugin : CDVPlugin
@synthesize notificationMessage;
@synthesize isInline;
@synthesize coldstart;
@synthesize callbackId;
@synthesize notificationCallbackId;
@synthesize callback;
@synthesize clearBadge;
@synthesize handlerObj;
@synthesize usesFCM;
@synthesize fcmSandbox;
@synthesize fcmSenderId;
@synthesize fcmRegistrationOptions;
@synthesize fcmRegistrationToken;
@synthesize fcmTopics;
//////////////////////////////////=====================
//-(void)initRegistration;
//{
// NSString * registrationToken = [[FIRInstanceID instanceID] token];
//
// if (registrationToken != nil) {
// NSLog(@"FCM Registration Token: %@", registrationToken);
// [self setFcmRegistrationToken: registrationToken];
//
// id topics = [self fcmTopics];
// if (topics != nil) {
// for (NSString *topic in topics) {
// NSLog(@"subscribe to topic: %@", topic);
// id pubSub = [FIRMessaging messaging];
// [pubSub subscribeToTopic:topic];
// }
// }
//
// [self registerWithToken:registrationToken];
// } else {
// NSLog(@"FCM token is null");
// }
//
//}
// FCM refresh token
// Unclear how this is testable under normal circumstances
/////////////////////////////////=====================
//- (void)onTokenRefresh {
//#if !TARGET_IPHONE_SIMULATOR
// // A rotation of the registration tokens is happening, so the app needs to request a new token.
// NSLog(@"The FCM registration token needs to be changed.");
// [[FIRInstanceID instanceID] token];
// [self initRegistration];
//#endif
//}
// contains error info
- (void)sendDataMessageFailure:(NSNotification *)notification {
NSLog(@"sendDataMessageFailure");
}
- (void)sendDataMessageSuccess:(NSNotification *)notification {
NSLog(@"sendDataMessageSuccess");
}
- (void)didSendDataMessageWithID:messageID {
NSLog(@"didSendDataMessageWithID");
}
- (void)willSendDataMessageWithID:messageID error:error {
NSLog(@"willSendDataMessageWithID");
}
- (void)didDeleteMessagesOnServer {
NSLog(@"didDeleteMessagesOnServer");
// Some messages sent to this device were deleted on the GCM server before reception, likely
// because the TTL expired. The client should notify the app server of this, so that the app
// server can resend those messages.
}
/////////////////////////////////=====================
- (void)unregister:(CDVInvokedUrlCommand*)command;
{
NSArray* topics = [command argumentAtIndex:0];
if (topics != nil) {
/////////////////////////////////=====================id pubSub = [FIRMessaging messaging];
for (NSString *topic in topics) {
NSLog(@"unsubscribe from topic: %@", topic);
/////////////////////////////////=====================[pubSub unsubscribeFromTopic:topic];
}
} else {
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
[self successWithMessage:command.callbackId withMsg:@"unregistered"];
}
}
- (void)subscribe:(CDVInvokedUrlCommand*)command;
{
NSString* topic = [command argumentAtIndex:0];
if (topic != nil) {
NSLog(@"subscribe from topic: %@", topic);
/////////////////////////////////=====================id pubSub = [FIRMessaging messaging];
/////////////////////////////////=====================[pubSub subscribeToTopic:topic];
NSLog(@"Successfully subscribe to topic %@", topic);
[self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully subscribe to topic %@", topic]];
} else {
NSLog(@"There is no topic to subscribe");
[self successWithMessage:command.callbackId withMsg:@"There is no topic to subscribe"];
}
}
- (void)unsubscribe:(CDVInvokedUrlCommand*)command;
{
NSString* topic = [command argumentAtIndex:0];
if (topic != nil) {
NSLog(@"unsubscribe from topic: %@", topic);
/////////////////////////////////=====================id pubSub = [FIRMessaging messaging];
/////////////////////////////////=====================[pubSub unsubscribeFromTopic:topic];
NSLog(@"Successfully unsubscribe from topic %@", topic);
[self successWithMessage:command.callbackId withMsg:[NSString stringWithFormat:@"Successfully unsubscribe from topic %@", topic]];
} else {
NSLog(@"There is no topic to unsubscribe");
[self successWithMessage:command.callbackId withMsg:@"There is no topic to unsubscribe"];
}
}
- (void)init:(CDVInvokedUrlCommand*)command;
{
NSMutableDictionary* options = [command.arguments objectAtIndex:0];
NSMutableDictionary* iosOptions = [options objectForKey:@"ios"];
BOOL apnsForce = false;
id apnsForceArg = [iosOptions objectForKey:@"apnsForce"];
if (([apnsForceArg isKindOfClass:[NSString class]] && [apnsForceArg isEqualToString:@"true"]) || [apnsForceArg boolValue]) {
apnsForce = true;
NSLog(@"Push Plugin will now use APNS even if GoogleService-Info.plist is present");
}
id voipArg = [iosOptions objectForKey:@"voip"];
if (([voipArg isKindOfClass:[NSString class]] && [voipArg isEqualToString:@"true"]) || [voipArg boolValue]) {
[self.commandDelegate runInBackground:^ {
NSLog(@"Push Plugin VoIP set to true");
self.callbackId = command.callbackId;
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}];
} else {
NSLog(@"Push Plugin VoIP missing or false");
/////////////////////////////////=====================[[NSNotificationCenter defaultCenter]
/////////////////////////////////=====================addObserver:self selector:@selector(onTokenRefresh)
/////////////////////////////////=====================name:kFIRInstanceIDTokenRefreshNotification object:nil];
/////////////////////////////////=====================[[NSNotificationCenter defaultCenter]
/////////////////////////////////=====================addObserver:self selector:@selector(sendDataMessageFailure:)
/////////////////////////////////=====================name:FIRMessagingSendErrorNotification object:nil];
/////////////////////////////////=====================[[NSNotificationCenter defaultCenter]
/////////////////////////////////=====================addObserver:self selector:@selector(sendDataMessageSuccess:)
/////////////////////////////////=====================name:FIRMessagingSendSuccessNotification object:nil];
/////////////////////////////////=====================[[NSNotificationCenter defaultCenter]
/////////////////////////////////=====================addObserver:self selector:@selector(didDeleteMessagesOnServer)
/////////////////////////////////=====================name:FIRMessagingMessagesDeletedNotification object:nil];
[self.commandDelegate runInBackground:^ {
NSLog(@"Push Plugin register called");
self.callbackId = command.callbackId;
NSArray* topics = [iosOptions objectForKey:@"topics"];
[self setFcmTopics:topics];
UNAuthorizationOptions authorizationOptions = UNAuthorizationOptionNone;
id badgeArg = [iosOptions objectForKey:@"badge"];
id soundArg = [iosOptions objectForKey:@"sound"];
id alertArg = [iosOptions objectForKey:@"alert"];
id clearBadgeArg = [iosOptions objectForKey:@"clearBadge"];
if (([badgeArg isKindOfClass:[NSString class]] && [badgeArg isEqualToString:@"true"]) || [badgeArg boolValue])
{
authorizationOptions |= UNAuthorizationOptionBadge;
}
if (([soundArg isKindOfClass:[NSString class]] && [soundArg isEqualToString:@"true"]) || [soundArg boolValue])
{
authorizationOptions |= UNAuthorizationOptionSound;
}
if (([alertArg isKindOfClass:[NSString class]] && [alertArg isEqualToString:@"true"]) || [alertArg boolValue])
{
authorizationOptions |= UNAuthorizationOptionAlert;
}
if (clearBadgeArg == nil || ([clearBadgeArg isKindOfClass:[NSString class]] && [clearBadgeArg isEqualToString:@"false"]) || ![clearBadgeArg boolValue]) {
NSLog(@"PushPlugin.register: setting badge to false");
clearBadge = NO;
} else {
NSLog(@"PushPlugin.register: setting badge to true");
clearBadge = YES;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
NSLog(@"PushPlugin.register: clear badge is set to %d", clearBadge);
isInline = NO;
NSLog(@"PushPlugin.register: better button setup");
// setup action buttons
NSMutableSet<UNNotificationCategory *> *categories = [[NSMutableSet alloc] init];
id categoryOptions = [iosOptions objectForKey:@"categories"];
if (categoryOptions != nil && [categoryOptions isKindOfClass:[NSDictionary class]]) {
for (id key in categoryOptions) {
NSLog(@"categories: key %@", key);
id category = [categoryOptions objectForKey:key];
id yesButton = [category objectForKey:@"yes"];
UNNotificationAction *yesAction;
if (yesButton != nil && [yesButton isKindOfClass:[NSDictionary class]]) {
yesAction = [self createAction: yesButton];
}
id noButton = [category objectForKey:@"no"];
UNNotificationAction *noAction;
if (noButton != nil && [noButton isKindOfClass:[NSDictionary class]]) {
noAction = [self createAction: noButton];
}
id maybeButton = [category objectForKey:@"maybe"];
UNNotificationAction *maybeAction;
if (maybeButton != nil && [maybeButton isKindOfClass:[NSDictionary class]]) {
maybeAction = [self createAction: maybeButton];
}
// Identifier to include in your push payload and local notification
NSString *identifier = key;
NSMutableArray<UNNotificationAction *> *actions = [[NSMutableArray alloc] init];
if (yesButton != nil) {
[actions addObject:yesAction];
}
if (noButton != nil) {
[actions addObject:noAction];
}
if (maybeButton != nil) {
[actions addObject:maybeAction];
}
UNNotificationCategory *notificationCategory = [UNNotificationCategory categoryWithIdentifier:identifier
actions:actions
intentIdentifiers:@[]
options:UNNotificationCategoryOptionNone];
NSLog(@"Adding category %@", key);
[categories addObject:notificationCategory];
}
}
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center setNotificationCategories:categories];
[self handleNotificationSettingsWithAuthorizationOptions:[NSNumber numberWithInteger:authorizationOptions]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationSettings:)
name:pushPluginApplicationDidBecomeActiveNotification
object:nil];
NSLog(@"Using APNS Notification");
[self setUsesFCM:NO];
id fcmSandboxArg = [iosOptions objectForKey:@"fcmSandbox"];
if (notificationMessage) { // if there is a pending startup notification
dispatch_async(dispatch_get_main_queue(), ^{
// delay to allow JS event handlers to be setup
[self performSelector:@selector(notificationReceived) withObject:nil afterDelay: 0.5];
});
}
}];
}
}
- (UNNotificationAction *)createAction:(NSDictionary *)dictionary {
NSString *identifier = [dictionary objectForKey:@"callback"];
NSString *title = [dictionary objectForKey:@"title"];
UNNotificationActionOptions options = UNNotificationActionOptionNone;
id mode = [dictionary objectForKey:@"foreground"];
if (mode != nil && (([mode isKindOfClass:[NSString class]] && [mode isEqualToString:@"true"]) || [mode boolValue])) {
options |= UNNotificationActionOptionForeground;
}
id destructive = [dictionary objectForKey:@"destructive"];
if (destructive != nil && (([destructive isKindOfClass:[NSString class]] && [destructive isEqualToString:@"true"]) || [destructive boolValue])) {
options |= UNNotificationActionOptionDestructive;
}
return [UNNotificationAction actionWithIdentifier:identifier title:title options:options];
}
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (self.callbackId == nil) {
NSLog(@"Unexpected call to didRegisterForRemoteNotificationsWithDeviceToken, ignoring: %@", deviceToken);
return;
}
NSLog(@"Push Plugin register success: %@", deviceToken);
NSString *token = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
#if !TARGET_IPHONE_SIMULATOR
// Check what Notifications the user has turned on. We registered for all three, but they may have manually disabled some or all of them.
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
__weak PushPlugin *weakSelf = self;
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if(![weakSelf usesFCM]) {
[weakSelf registerWithToken: token];
}
}];
#endif
}
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
if (self.callbackId == nil) {
NSLog(@"Unexpected call to didFailToRegisterForRemoteNotificationsWithError, ignoring: %@", error);
return;
}
NSLog(@"Push Plugin register failed");
[self failWithMessage:self.callbackId withMsg:@"" withError:error];
}
- (void)notificationReceived {
NSLog(@"Notification received");
if (notificationMessage && self.callbackId != nil)
{
NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:4];
NSMutableDictionary* additionalData = [NSMutableDictionary dictionaryWithCapacity:4];
for (id key in notificationMessage) {
if ([key isEqualToString:@"aps"]) {
id aps = [notificationMessage objectForKey:@"aps"];
for(id key in aps) {
NSLog(@"Push Plugin key: %@", key);
id value = [aps objectForKey:key];
if ([key isEqualToString:@"alert"]) {
if ([value isKindOfClass:[NSDictionary class]]) {
for (id messageKey in value) {
id messageValue = [value objectForKey:messageKey];
if ([messageKey isEqualToString:@"body"]) {
[message setObject:messageValue forKey:@"message"];
} else if ([messageKey isEqualToString:@"title"]) {
[message setObject:messageValue forKey:@"title"];
} else {
[additionalData setObject:messageValue forKey:messageKey];
}
}
}
else {
[message setObject:value forKey:@"message"];
}
} else if ([key isEqualToString:@"title"]) {
[message setObject:value forKey:@"title"];
} else if ([key isEqualToString:@"badge"]) {
[message setObject:value forKey:@"count"];
} else if ([key isEqualToString:@"sound"]) {
[message setObject:value forKey:@"sound"];
} else if ([key isEqualToString:@"image"]) {
[message setObject:value forKey:@"image"];
} else {
[additionalData setObject:value forKey:key];
}
}
} else {
[additionalData setObject:[notificationMessage objectForKey:key] forKey:key];
}
}
if (isInline) {
[additionalData setObject:[NSNumber numberWithBool:YES] forKey:@"foreground"];
} else {
[additionalData setObject:[NSNumber numberWithBool:NO] forKey:@"foreground"];
}
if (coldstart) {
[additionalData setObject:[NSNumber numberWithBool:YES] forKey:@"coldstart"];
} else {
[additionalData setObject:[NSNumber numberWithBool:NO] forKey:@"coldstart"];
}
[message setObject:additionalData forKey:@"additionalData"];
// send notification message
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];
[pluginResult setKeepCallbackAsBool:YES];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
self.coldstart = NO;
self.notificationMessage = nil;
}
}
- (void)clearNotification:(CDVInvokedUrlCommand *)command
{
NSNumber *notId = [command.arguments objectAtIndex:0];
[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
/*
* If the server generates a unique "notId" for every push notification, there should only be one match in these arrays, but if not, it will delete
* all notifications with the same value for "notId"
*/
NSPredicate *matchingNotificationPredicate = [NSPredicate predicateWithFormat:@"request.content.userInfo.notId == %@", notId];
NSArray<UNNotification *> *matchingNotifications = [notifications filteredArrayUsingPredicate:matchingNotificationPredicate];
NSMutableArray<NSString *> *matchingNotificationIdentifiers = [NSMutableArray array];
for (UNNotification *notification in matchingNotifications) {
[matchingNotificationIdentifiers addObject:notification.request.identifier];
}
[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:matchingNotificationIdentifiers];
NSString *message = [NSString stringWithFormat:@"Cleared notification with ID: %@", notId];
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
}];
}
- (void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command
{
NSMutableDictionary* options = [command.arguments objectAtIndex:0];
int badge = [[options objectForKey:@"badge"] intValue] ?: 0;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badge];
NSString* message = [NSString stringWithFormat:@"app badge count set to %d", badge];
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
}
- (void)getApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command
{
NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)badge];
[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
}
- (void)clearAllNotifications:(CDVInvokedUrlCommand *)command
{
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
NSString* message = [NSString stringWithFormat:@"cleared all notifications"];
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
}
- (void)hasPermission:(CDVInvokedUrlCommand *)command
{
id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
if ([appDelegate respondsToSelector:@selector(checkUserHasRemoteNotificationsEnabledWithCompletionHandler:)]) {
[appDelegate performSelector:@selector(checkUserHasRemoteNotificationsEnabledWithCompletionHandler:) withObject:^(BOOL isEnabled) {
NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:1];
[message setObject:[NSNumber numberWithBool:isEnabled] forKey:@"isEnabled"];
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];
[self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
}];
}
}
-(void)successWithMessage:(NSString *)myCallbackId withMsg:(NSString *)message
{
if (myCallbackId != nil)
{
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
[self.commandDelegate sendPluginResult:commandResult callbackId:myCallbackId];
}
}
-(void)registerWithToken:(NSString*)token; {
// Send result to trigger 'registration' event but keep callback
NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:2];
[message setObject:token forKey:@"registrationId"];
[message setObject:@"APNS" forKey:@"registrationType"];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];
[pluginResult setKeepCallbackAsBool:YES];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
-(void)failWithMessage:(NSString *)myCallbackId withMsg:(NSString *)message withError:(NSError *)error
{
NSString *errorMessage = (error) ? [NSString stringWithFormat:@"%@ - %@", message, [error localizedDescription]] : message;
CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage];
[self.commandDelegate sendPluginResult:commandResult callbackId:myCallbackId];
}
-(void) finish:(CDVInvokedUrlCommand*)command
{
NSLog(@"Push Plugin finish called");
[self.commandDelegate runInBackground:^ {
NSString* notId = [command.arguments objectAtIndex:0];
dispatch_async(dispatch_get_main_queue(), ^{
[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(stopBackgroundTask:)
userInfo:notId
repeats:NO];
});
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
}
-(void)stopBackgroundTask:(NSTimer*)timer
{
UIApplication *app = [UIApplication sharedApplication];
NSLog(@"Push Plugin stopBackgroundTask called");
if (handlerObj) {
NSLog(@"Push Plugin handlerObj");
completionHandler = [handlerObj[[timer userInfo]] copy];
if (completionHandler) {
NSLog(@"Push Plugin: stopBackgroundTask (remaining t: %f)", app.backgroundTimeRemaining);
completionHandler(UIBackgroundFetchResultNewData);
completionHandler = nil;
}
}
}
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
if([credentials.token length] == 0) {
NSLog(@"VoIPPush Plugin register error - No device token:");
return;
}
NSLog(@"VoIPPush Plugin register success");
const unsigned *tokenBytes = [credentials.token bytes];
NSString *sToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
[self registerWithToken:sToken];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
NSLog(@"VoIP Notification received");
self.notificationMessage = payload.dictionaryPayload;
[self notificationReceived];
}
- (void)handleNotificationSettings:(NSNotification *)notification
{
[self handleNotificationSettingsWithAuthorizationOptions:nil];
}
- (void)handleNotificationSettingsWithAuthorizationOptions:(NSNumber *)authorizationOptionsObject
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNAuthorizationOptions authorizationOptions = [authorizationOptionsObject unsignedIntegerValue];
__weak UNUserNotificationCenter *weakCenter = center;
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus) {
case UNAuthorizationStatusNotDetermined:
{
[weakCenter requestAuthorizationWithOptions:authorizationOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
[self performSelectorOnMainThread:@selector(registerForRemoteNotifications)
withObject:nil
waitUntilDone:NO];
}
}];
break;
}
case UNAuthorizationStatusAuthorized:
{
[self performSelectorOnMainThread:@selector(registerForRemoteNotifications)
withObject:nil
waitUntilDone:NO];
break;
}
case UNAuthorizationStatusDenied:
default:
break;
}
}];
}
- (void)registerForRemoteNotifications
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
@end

View File

@@ -0,0 +1,25 @@
//
// AppDelegate+notification.h
// pushtest
//
// Created by Robert Easterday on 10/26/12.
//
//
#import "AppDelegate.h"
@import UserNotifications;
extern NSString *const pushPluginApplicationDidBecomeActiveNotification;
@interface AppDelegate (notification) <UNUserNotificationCenterDelegate>
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:( void (^)(UIBackgroundFetchResult))completionHandler;
- (void)pushPluginOnApplicationDidBecomeActive:(UIApplication *)application;
- (void)checkUserHasRemoteNotificationsEnabledWithCompletionHandler:(nonnull void (^)(BOOL))completionHandler;
- (id) getCommandInstance:(NSString*)className;
@property (nonatomic, retain) NSDictionary *launchNotification;
@property (nonatomic, retain) NSNumber *coldstart;
@end

View File

@@ -0,0 +1,289 @@
//
// AppDelegate+notification.m
// pushtest
//
// Created by Robert Easterday on 10/26/12.
//
//
#import "AppDelegate+apnsnotification.h"
#import "APNSPushPlugin.h"
#import <objc/runtime.h>
static char launchNotificationKey;
static char coldstartKey;
NSString *const pushPluginApplicationDidBecomeActiveNotification = @"pushPluginApplicationDidBecomeActiveNotification";
@implementation AppDelegate (notification)
- (id) getCommandInstance:(NSString*)className
{
return [self.viewController getCommandInstance:className];
}
// its dangerous to override a method from within a category.
// Instead we will use method swizzling. we set this up in the load call.
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(init);
SEL swizzledSelector = @selector(pushPluginSwizzledInit);
Method original = class_getInstanceMethod(class, originalSelector);
Method swizzled = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzled),
method_getTypeEncoding(swizzled));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(original),
method_getTypeEncoding(original));
} else {
method_exchangeImplementations(original, swizzled);
}
});
}
- (AppDelegate *)pushPluginSwizzledInit
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(pushPluginOnApplicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
// This actually calls the original init method over in AppDelegate. Equivilent to calling super
// on an overrided method, this is not recursive, although it appears that way. neat huh?
return [self pushPluginSwizzledInit];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
[pushHandler didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
[pushHandler didFailToRegisterForRemoteNotificationsWithError:error];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"didReceiveNotification with fetchCompletionHandler");
// app is in the background or inactive, so only call notification callback if this is a silent push
if (application.applicationState != UIApplicationStateActive) {
NSLog(@"app in-active");
// do some convoluted logic to find out if this should be a silent push.
long silent = 0;
id aps = [userInfo objectForKey:@"aps"];
id contentAvailable = [aps objectForKey:@"content-available"];
if ([contentAvailable isKindOfClass:[NSString class]] && [contentAvailable isEqualToString:@"1"]) {
silent = 1;
} else if ([contentAvailable isKindOfClass:[NSNumber class]]) {
silent = [contentAvailable integerValue];
}
if (silent == 1) {
NSLog(@"this should be a silent push");
void (^safeHandler)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult result){
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(result);
});
};
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
if (pushHandler.handlerObj == nil) {
pushHandler.handlerObj = [NSMutableDictionary dictionaryWithCapacity:2];
}
id notId = [userInfo objectForKey:@"notId"];
if (notId != nil) {
NSLog(@"Push Plugin notId %@", notId);
[pushHandler.handlerObj setObject:safeHandler forKey:notId];
} else {
NSLog(@"Push Plugin notId handler");
[pushHandler.handlerObj setObject:safeHandler forKey:@"handler"];
}
pushHandler.notificationMessage = userInfo;
pushHandler.isInline = NO;
[pushHandler notificationReceived];
} else {
NSLog(@"just put it in the shade");
//save it for later
self.launchNotification = userInfo;
completionHandler(UIBackgroundFetchResultNewData);
}
} else {
completionHandler(UIBackgroundFetchResultNoData);
}
}
- (void)checkUserHasRemoteNotificationsEnabledWithCompletionHandler:(nonnull void (^)(BOOL))completionHandler
{
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus)
{
case UNAuthorizationStatusDenied:
case UNAuthorizationStatusNotDetermined:
completionHandler(NO);
break;
case UNAuthorizationStatusAuthorized:
completionHandler(YES);
break;
}
}];
}
- (void)pushPluginOnApplicationDidBecomeActive:(NSNotification *)notification {
NSLog(@"active");
NSString *firstLaunchKey = @"firstLaunchKey";
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"phonegap-plugin-push"];
if (![defaults boolForKey:firstLaunchKey]) {
NSLog(@"application first launch: remove badge icon number");
[defaults setBool:YES forKey:firstLaunchKey];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
UIApplication *application = notification.object;
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
if (pushHandler.clearBadge) {
NSLog(@"PushPlugin clearing badge");
//zero badge
application.applicationIconBadgeNumber = 0;
} else {
NSLog(@"PushPlugin skip clear badge");
}
if (self.launchNotification) {
pushHandler.isInline = NO;
pushHandler.coldstart = [self.coldstart boolValue];
pushHandler.notificationMessage = self.launchNotification;
self.launchNotification = nil;
self.coldstart = [NSNumber numberWithBool:NO];
[pushHandler performSelectorOnMainThread:@selector(notificationReceived) withObject:pushHandler waitUntilDone:NO];
}
[[NSNotificationCenter defaultCenter] postNotificationName:pushPluginApplicationDidBecomeActiveNotification object:nil];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSLog( @"NotificationCenter Handle push from foreground" );
// custom code to handle push while app is in the foreground
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
pushHandler.notificationMessage = notification.request.content.userInfo;
pushHandler.isInline = YES;
[pushHandler notificationReceived];
completionHandler(UNNotificationPresentationOptionNone);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler
{
NSLog(@"Push Plugin didReceiveNotificationResponse: actionIdentifier %@, notification: %@", response.actionIdentifier,
response.notification.request.content.userInfo);
NSMutableDictionary *userInfo = [response.notification.request.content.userInfo mutableCopy];
[userInfo setObject:response.actionIdentifier forKey:@"actionCallback"];
NSLog(@"Push Plugin userInfo %@", userInfo);
switch ([UIApplication sharedApplication].applicationState) {
case UIApplicationStateActive:
{
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
pushHandler.notificationMessage = userInfo;
pushHandler.isInline = NO;
[pushHandler notificationReceived];
completionHandler();
break;
}
case UIApplicationStateInactive:
{
NSLog(@"coldstart");
self.launchNotification = response.notification.request.content.userInfo;
self.coldstart = [NSNumber numberWithBool:YES];
break;
}
case UIApplicationStateBackground:
{
void (^safeHandler)(void) = ^(void){
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler();
});
};
PushPlugin *pushHandler = [self getCommandInstance:@"APNSPushNotification"];
if (pushHandler.handlerObj == nil) {
pushHandler.handlerObj = [NSMutableDictionary dictionaryWithCapacity:2];
}
id notId = [userInfo objectForKey:@"notId"];
if (notId != nil) {
NSLog(@"Push Plugin notId %@", notId);
[pushHandler.handlerObj setObject:safeHandler forKey:notId];
} else {
NSLog(@"Push Plugin notId handler");
[pushHandler.handlerObj setObject:safeHandler forKey:@"handler"];
}
pushHandler.notificationMessage = userInfo;
pushHandler.isInline = NO;
[pushHandler performSelectorOnMainThread:@selector(notificationReceived) withObject:pushHandler waitUntilDone:NO];
}
}
}
// The accessors use an Associative Reference since you can't define a iVar in a category
// http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocAssociativeReferences.html
- (NSMutableArray *)launchNotification
{
return objc_getAssociatedObject(self, &launchNotificationKey);
}
- (void)setLaunchNotification:(NSDictionary *)aDictionary
{
objc_setAssociatedObject(self, &launchNotificationKey, aDictionary, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)coldstart
{
return objc_getAssociatedObject(self, &coldstartKey);
}
- (void)setColdstart:(NSNumber *)aNumber
{
objc_setAssociatedObject(self, &coldstartKey, aNumber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)dealloc
{
self.launchNotification = nil; // clear the association and release the object
self.coldstart = nil;
}
@end

393
www/apnspush.js Normal file
View File

@@ -0,0 +1,393 @@
/**
* This file has been generated by Babel.
*
* DO NOT EDIT IT DIRECTLY
*
* Edit the JS source file src/js/push.js
**/'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/* global cordova:false */
/* globals window */
/*!
* Module dependencies.
*/
var exec = cordova.require('cordova/exec');
var APNSPushNotification = function () {
/**
* APNSPushNotification constructor.
*
* @param {Object} options to initiate Push Notifications.
* @return {APNSPushNotification} instance that can be monitored and cancelled.
*/
function APNSPushNotification(options) {
var _this = this;
_classCallCheck(this, APNSPushNotification);
this.handlers = {
registration: [],
notification: [],
error: []
};
// require options parameter
if (typeof options === 'undefined') {
throw new Error('The options argument is required.');
}
// store the options to this object instance
this.options = options;
// triggered on registration and notification
var success = function success(result) {
if (result && typeof result.registrationId !== 'undefined') {
_this.emit('registration', result);
} else if (result && result.additionalData && typeof result.additionalData.actionCallback !== 'undefined') {
_this.emit(result.additionalData.actionCallback, result);
} else if (result) {
_this.emit('notification', result);
}
};
// triggered on error
var fail = function fail(msg) {
var e = typeof msg === 'string' ? new Error(msg) : msg;
_this.emit('error', e);
};
// wait at least one process tick to allow event subscriptions
setTimeout(function () {
exec(success, fail, 'APNSPushNotification', 'init', [options]);
}, 10);
}
/**
* Unregister from push notifications
*/
_createClass(APNSPushNotification, [{
key: 'unregister',
value: function unregister(successCallback) {
var _this2 = this;
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
var options = arguments[2];
if (typeof errorCallback !== 'function') {
console.log('APNSPushNotification.unregister failure: failure parameter not a function');
return;
}
if (typeof successCallback !== 'function') {
console.log('APNSPushNotification.unregister failure: success callback parameter must be a function');
return;
}
var cleanHandlersAndPassThrough = function cleanHandlersAndPassThrough() {
if (!options) {
_this2.handlers = {
registration: [],
notification: [],
error: []
};
}
successCallback();
};
exec(cleanHandlersAndPassThrough, errorCallback, 'APNSPushNotification', 'unregister', [options]);
}
/**
* subscribe to a topic
* @param {String} topic topic to subscribe
* @param {Function} successCallback success callback
* @param {Function} errorCallback error callback
* @return {void}
*/
}, {
key: 'subscribe',
value: function subscribe(topic, successCallback) {
var errorCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
if (typeof errorCallback !== 'function') {
console.log('APNSPushNotification.subscribe failure: failure parameter not a function');
return;
}
if (typeof successCallback !== 'function') {
console.log('APNSPushNotification.subscribe failure: success callback parameter must be a function');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'subscribe', [topic]);
}
/**
* unsubscribe to a topic
* @param {String} topic topic to unsubscribe
* @param {Function} successCallback success callback
* @param {Function} errorCallback error callback
* @return {void}
*/
}, {
key: 'unsubscribe',
value: function unsubscribe(topic, successCallback) {
var errorCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
if (typeof errorCallback !== 'function') {
console.log('APNSPushNotification.unsubscribe failure: failure parameter not a function');
return;
}
if (typeof successCallback !== 'function') {
console.log('APNSPushNotification.unsubscribe failure: success callback parameter must be a function');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'unsubscribe', [topic]);
}
/**
* Call this to set the application icon badge
*/
}, {
key: 'setApplicationIconBadgeNumber',
value: function setApplicationIconBadgeNumber(successCallback) {
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
var badge = arguments[2];
if (typeof errorCallback !== 'function') {
console.log('APNSPushNotification.setApplicationIconBadgeNumber failure: failure ' + 'parameter not a function');
return;
}
if (typeof successCallback !== 'function') {
console.log('APNSPushNotification.setApplicationIconBadgeNumber failure: success ' + 'callback parameter must be a function');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'setApplicationIconBadgeNumber', [{ badge: badge }]);
}
/**
* Get the application icon badge
*/
}, {
key: 'getApplicationIconBadgeNumber',
value: function getApplicationIconBadgeNumber(successCallback) {
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
if (typeof errorCallback !== 'function') {
console.log('APNSPushNotification.getApplicationIconBadgeNumber failure: failure ' + 'parameter not a function');
return;
}
if (typeof successCallback !== 'function') {
console.log('APNSPushNotification.getApplicationIconBadgeNumber failure: success ' + 'callback parameter must be a function');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'getApplicationIconBadgeNumber', []);
}
/**
* Clear all notifications
*/
}, {
key: 'clearAllNotifications',
value: function clearAllNotifications() {
var successCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
if (typeof errorCallback !== 'function') {
console.log('APNSPushNotification.clearAllNotifications failure: failure parameter not a function');
return;
}
if (typeof successCallback !== 'function') {
console.log('APNSPushNotification.clearAllNotifications failure: success callback ' + 'parameter must be a function');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'clearAllNotifications', []);
}
/**
* Clears notifications that have the ID specified.
* @param {Function} [successCallback] Callback function to be called on success.
* @param {Function} [errorCallback] Callback function to be called when an error is encountered.
* @param {Number} id ID of the notification to be removed.
*/
}, {
key: 'clearNotification',
value: function clearNotification() {
var successCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
var id = arguments[2];
var idNumber = parseInt(id, 10);
if (isNaN(idNumber) || idNumber > Number.MAX_SAFE_INTEGER || idNumber < 0) {
console.log('APNSPushNotification.clearNotification failure: id parameter must' + 'be a valid integer.');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'clearNotification', [idNumber]);
}
/**
* Listen for an event.
*
* The following events are supported:
*
* - registration
* - notification
* - error
*
* @param {String} eventName to subscribe to.
* @param {Function} callback triggered on the event.
*/
}, {
key: 'on',
value: function on(eventName, callback) {
if (!this.handlers.hasOwnProperty(eventName)) {
this.handlers[eventName] = [];
}
this.handlers[eventName].push(callback);
}
/**
* Remove event listener.
*
* @param {String} eventName to match subscription.
* @param {Function} handle function associated with event.
*/
}, {
key: 'off',
value: function off(eventName, handle) {
if (this.handlers.hasOwnProperty(eventName)) {
var handleIndex = this.handlers[eventName].indexOf(handle);
if (handleIndex >= 0) {
this.handlers[eventName].splice(handleIndex, 1);
}
}
}
/**
* Emit an event.
*
* This is intended for internal use only.
*
* @param {String} eventName is the event to trigger.
* @param {*} all arguments are passed to the event listeners.
*
* @return {Boolean} is true when the event is triggered otherwise false.
*/
}, {
key: 'emit',
value: function emit() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var eventName = args.shift();
if (!this.handlers.hasOwnProperty(eventName)) {
return false;
}
for (var i = 0, length = this.handlers[eventName].length; i < length; i++) {
var callback = this.handlers[eventName][i];
if (typeof callback === 'function') {
callback.apply(undefined, args);
} else {
console.log('event handler: ' + eventName + ' must be a function');
}
}
return true;
}
}, {
key: 'finish',
value: function finish() {
var successCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
var errorCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
var id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'handler';
if (typeof successCallback !== 'function') {
console.log('finish failure: success callback parameter must be a function');
return;
}
if (typeof errorCallback !== 'function') {
console.log('finish failure: failure parameter not a function');
return;
}
exec(successCallback, errorCallback, 'APNSPushNotification', 'finish', [id]);
}
}]);
return APNSPushNotification;
}();
/*!
* Push Notification Plugin.
*/
module.exports = {
/**
* Register for Push Notifications.
*
* This method will instantiate a new copy of the APNSPushNotification object
* and start the registration process.
*
* @param {Object} options
* @return {APNSPushNotification} instance
*/
init: function init(options) {
return new APNSPushNotification(options);
},
hasPermission: function hasPermission(successCallback, errorCallback) {
exec(successCallback, errorCallback, 'APNSPushNotification', 'hasPermission', []);
},
createChannel: function createChannel(successCallback, errorCallback, channel) {
exec(successCallback, errorCallback, 'APNSPushNotification', 'createChannel', [channel]);
},
deleteChannel: function deleteChannel(successCallback, errorCallback, channelId) {
exec(successCallback, errorCallback, 'APNSPushNotification', 'deleteChannel', [channelId]);
},
listChannels: function listChannels(successCallback, errorCallback) {
exec(successCallback, errorCallback, 'APNSPushNotification', 'listChannels', []);
},
/**
* APNSPushNotification Object.
*
* Expose the APNSPushNotification object for direct use
* and testing. Typically, you should use the
* .init helper method.
*/
APNSPushNotification: APNSPushNotification
};