-
Notifications
You must be signed in to change notification settings - Fork 29
/
LocalNotification.m
executable file
·282 lines (233 loc) · 12.8 KB
/
LocalNotification.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
//
// LocalNotification.m
// Phonegap LocalNotification Plugin
// Copyright (c) Greg Allen 2011
// MIT Licensed
/**
* Updates
* @author Ally Ogilvie
* @Wizcorp Inc. [ Incorporated Wizards ] 2014
* @file LocalNotification.m for Cordova
*
*/
#import "LocalNotification.h"
#import "WizDebugLog.h"
@implementation LocalNotification
static BOOL launchedWithNotification = NO;
static UILocalNotification *localNotification = nil;
#pragma - Class Methods
+ (void)load {
// Register for didFinishLaunching notifications in class load method so that
// this class can observe launch events. Do this here because this needs to be
// registered before the AppDelegate's application:didFinishLaunchingWithOptions:
// method finishes executing. A class's load method gets invoked before
// application:didFinishLaunchingWithOptions is invoked (even if the plugin is
// not loaded/invoked in the JavaScript).
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didFinishLaunching:)
name:UIApplicationDidFinishLaunchingNotification
object:nil];
// Register for willTerminate notifications here so that we can observer terminate
// events and unregister observing launch notifications. This isn't strictly
// required (and may not be called according to the docs).
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(willTerminate:)
name:UIApplicationWillTerminateNotification
object:nil];
}
+ (void)didFinishLaunching:(NSNotification *)notification {
// This code will be called immediately after application:didFinishLaunchingWithOptions:.
NSDictionary *launchOptions = [notification userInfo];
UILocalNotification *localNotif = [launchOptions objectForKey: @"UIApplicationLaunchOptionsLocalNotificationKey"];
if (localNotif) {
launchedWithNotification = YES;
localNotification = localNotif;
[localNotification retain];
} else {
launchedWithNotification = NO;
}
}
+ (void)willTerminate:(NSNotification *)notification {
// Stop the class from observing all notification center notifications.
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Release the notification
[localNotification release];
}
#pragma - Instance Methods
- (void)dealloc {
self.notificationQueue = nil;
// Stop the instance from observing all notification center notifications.
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
-(CDVPlugin *)initWithWebView:(UIWebView *)theWebView {
self = (LocalNotification *)[super initWithWebView:theWebView];
// initiate empty Notification Queue
self.notificationQueue = [[NSMutableDictionary alloc ] init];
// Check if iOS 8, then request notification permissions
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:
[UIUserNotificationSettings settingsForTypes:
(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound) categories:NULL]];
}
// Register the instance to observe CDVLocalNotification notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(notificationReceived:)
name:CDVLocalNotification
object:nil];
// Register the instance to observe didEnterBackground notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(emptyNotificationQueue:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
// Register the instance to observe willResignActive notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(emptyNotificationQueue:)
name:UIApplicationWillResignActiveNotification
object:nil];
return self;
}
- (void)ready:(CDVInvokedUrlCommand *)command {
if ( launchedWithNotification ) {
NSNotification *notification = [NSNotification notificationWithName:CDVLocalNotification
object:localNotification];
[self notificationReceived:notification];
}
}
- (void)addNotification:(CDVInvokedUrlCommand *)command {
// Check current user notification settings on iOS8
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *una = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (una.types != (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)) {
// We cannot send a notification, the user has blocked notifications
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"USER_DISABLED"];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
return;
}
}
NSDictionary *options = [command.arguments objectAtIndex:1];
int seconds = [[options objectForKey:@"seconds"] intValue];
NSString *msg = [options objectForKey:@"message"];
NSString *action = @"View";
NSString *notificationId = [NSString stringWithFormat:@"%@", [command.arguments objectAtIndex:0]];
NSInteger badge = [[options objectForKey:@"badge"] intValue];
bool hasAction = TRUE;
NSTimeInterval secondedDate = ([[NSDate date] timeIntervalSince1970] + seconds);
NSDate *date = [NSDate dateWithTimeIntervalSince1970:secondedDate];
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.fireDate = date;
notif.hasAction = hasAction;
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = ([msg isEqualToString:@""])?nil:msg;
notif.alertAction = action;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = badge;
NSDictionary *userDict = [NSDictionary dictionaryWithObject:notificationId
forKey:@"notificationId"];
notif.userInfo = userDict;
// check for existing notification with same id?
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *notification in notifications) {
NSString *notId = [notification.userInfo objectForKey:@"notificationId"];
if ([notificationId isEqualToString:notId]) {
// it is the same so cancel it
WizLog(@"Notification Canceled: %@", notificationId);
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
// now schedule new one
NSLog(@"Notification Set: %@ (ID: %@, Badge: %i)", date , notificationId, badge);
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
[notif release];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
- (void)queueNotification:(CDVInvokedUrlCommand*)command {
// Check current user notification settings on iOS8
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *una = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (una.types != (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)) {
// We cannot send a notification, the user has blocked notifications
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"USER_DISABLED"];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
return;
}
}
WizLog(@"[queueNotification] ------- adding notification to queue ");
NSDictionary *options = [command.arguments objectAtIndex:1];
// store notifications in notificationQueue dictionary
NSString *notificationId = [NSString stringWithFormat:@"%@", [command.arguments objectAtIndex:0]];
[self.notificationQueue setObject:options forKey:notificationId];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
- (void)notificationReceived:(NSNotification *)notification {
NSString *active;
if (launchedWithNotification) {
active = @"false";
launchedWithNotification = NO;
[localNotification release];
localNotification = nil;
} else if ( [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive ) {
active = @"true";
} else {
active = @"false";
}
NSString *jsString = [NSString stringWithFormat:@"cordova.fireDocumentEvent('receivedLocalNotification', \
{ active : %@, notificationId : \'%@\' })", active, [[notification.object userInfo] objectForKey:@"notificationId"]];
NSLog(@"CALLING JAVASCRIPT METHOD: %@", jsString);
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
- (void)emptyNotificationQueue:(NSNotification *)notification {
LocalNotification *_localNotification = [[LocalNotification alloc] init];
// Add all notifications from the notificationQueue dictionary and empty it
for (NSString *key in self.notificationQueue) {
NSMutableDictionary *notificationDict = [[NSMutableDictionary alloc] initWithDictionary:[self.notificationQueue objectForKey:key]];
NSArray *notificationArray = [[NSArray alloc] initWithObjects:key, notificationDict, nil];
WizLog(@"Notification in queue adding : %@", notificationArray);
CDVInvokedUrlCommand *cmd = [[CDVInvokedUrlCommand alloc] initWithArguments:notificationArray callbackId:@"" className:@"LocalNotification" methodName:@"addNotification"];
[_localNotification addNotification:cmd];
[cmd release];
[notificationArray release];
[notificationDict release];
}
// empty it
[self.notificationQueue removeAllObjects];
[_localNotification release];
}
- (void)cancelNotification:(CDVInvokedUrlCommand *)command {
if ([command.arguments count] >0) {
NSString *notificationId = [NSString stringWithFormat:@"%@", [command.arguments objectAtIndex:0]];
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *notification in notifications) {
NSString *notId = [notification.userInfo objectForKey:@"notificationId"];
if ([notificationId isEqualToString:notId]) {
WizLog(@"Notification Canceled: %@", notificationId);
[[UIApplication sharedApplication] cancelLocalNotification:notification];
} else {
WizLog(@"Notification id: %@ - NOT FOUND in: %@",notificationId, notification.userInfo);
}
}
} else {
WizLog(@"Notification Canceled not enough params. Missing ID");
}
}
- (void)cancelAllNotifications:(CDVInvokedUrlCommand *)command {
WizLog(@"All Notifications cancelled");
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
- (void)getApplicationBadge:(CDVInvokedUrlCommand *)command {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsInt:[UIApplication sharedApplication].applicationIconBadgeNumber];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
- (void)setApplicationBadge:(CDVInvokedUrlCommand *)command {
NSNumber *value = [command.arguments objectAtIndex:0];
[UIApplication sharedApplication].applicationIconBadgeNumber = [value integerValue];
// Invoke callback method if it was specified.
if ( ![command.callbackId isEqualToString:@"INVALID"] ) {
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
}
@end