|
| 1 | +// |
| 2 | +// PushNotification.m |
| 3 | +// |
| 4 | +// Created by Olivier Louvignes on 06/05/12. |
| 5 | +// Inspired by Urban Airship Inc orphaned PushNotification phonegap plugin. |
| 6 | +// |
| 7 | +// Copyright 2012 Olivier Louvignes. All rights reserved. |
| 8 | +// MIT Licensed |
| 9 | + |
| 10 | +#import "PushNotification.h" |
| 11 | +#ifdef CORDOVA_FRAMEWORK |
| 12 | + #import <Cordova/JSONKit.h> |
| 13 | +#else |
| 14 | + #import "JSONKit.h" |
| 15 | +#endif |
| 16 | + |
| 17 | +@implementation PushNotification |
| 18 | + |
| 19 | +@synthesize callbackID; |
| 20 | +@synthesize pendingNotifications = _pendingNotifications; |
| 21 | + |
| 22 | +- (NSMutableArray*)pendingNotifications { |
| 23 | + if(_pendingNotifications == nil) { |
| 24 | + _pendingNotifications = [[NSMutableArray alloc] init]; |
| 25 | + } |
| 26 | + return _pendingNotifications; |
| 27 | +} |
| 28 | + |
| 29 | +- (void)registerDevice:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options { |
| 30 | + //NSLog(@"registerDevice:%@\n withDict:%@", arguments, options); |
| 31 | + |
| 32 | + // The first argument in the arguments parameter is the callbackID. |
| 33 | + // We use this to send data back to the successCallback or failureCallback |
| 34 | + // through PluginResult. |
| 35 | + self.callbackID = [arguments pop]; |
| 36 | + |
| 37 | + UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeNone; |
| 38 | + if ([options objectForKey:@"badge"]) { |
| 39 | + notificationTypes |= UIRemoteNotificationTypeBadge; |
| 40 | + } |
| 41 | + if ([options objectForKey:@"sound"]) { |
| 42 | + notificationTypes |= UIRemoteNotificationTypeSound; |
| 43 | + } |
| 44 | + if ([options objectForKey:@"alert"]) { |
| 45 | + notificationTypes |= UIRemoteNotificationTypeAlert; |
| 46 | + } |
| 47 | + |
| 48 | + if (notificationTypes == UIRemoteNotificationTypeNone) |
| 49 | + NSLog(@"PushNotification.registerDevice: Push notification type is set to none"); |
| 50 | + |
| 51 | + //[[UIApplication sharedApplication] unregisterForRemoteNotifications]; |
| 52 | + [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes]; |
| 53 | + |
| 54 | +} |
| 55 | + |
| 56 | +- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { |
| 57 | + //NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken:%@", deviceToken); |
| 58 | + |
| 59 | + NSString *token = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""] |
| 60 | + stringByReplacingOccurrencesOfString:@">" withString:@""] |
| 61 | + stringByReplacingOccurrencesOfString: @" " withString: @""]; |
| 62 | + |
| 63 | + NSMutableDictionary *results = [PushNotification getRemoteNotificationStatus]; |
| 64 | + [results setValue:token forKey:@"deviceToken"]; |
| 65 | + |
| 66 | + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:results]; |
| 67 | + [self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]]; |
| 68 | +} |
| 69 | + |
| 70 | +- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError*)error { |
| 71 | + //NSLog(@"didFailToRegisterForRemoteNotificationsWithError:%@", error); |
| 72 | + |
| 73 | + NSMutableDictionary *results = [NSMutableDictionary dictionary]; |
| 74 | + [results setValue:[NSString stringWithFormat:@"%@", error] forKey:@"error"]; |
| 75 | + |
| 76 | + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:results]; |
| 77 | + [self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]]; |
| 78 | +} |
| 79 | + |
| 80 | +- (void)didReceiveRemoteNotification:(NSDictionary*)userInfo { |
| 81 | + //NSLog(@"didReceiveRemoteNotification:%@", userInfo); |
| 82 | + |
| 83 | + NSString *jsStatement = [NSString stringWithFormat:@"window.plugins.pushNotification.notificationCallback(%@);", [userInfo JSONString]]; |
| 84 | + [self writeJavascript:jsStatement]; |
| 85 | +} |
| 86 | + |
| 87 | +- (void)getPendingNotifications:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options { |
| 88 | + //NSLog(@"getPendingNotifications:%@\n withDict:%@", arguments, options); |
| 89 | + |
| 90 | + // The first argument in the arguments parameter is the callbackID. |
| 91 | + // We use this to send data back to the successCallback or failureCallback |
| 92 | + // through PluginResult. |
| 93 | + self.callbackID = [arguments pop]; |
| 94 | + |
| 95 | + NSMutableDictionary *results = [NSMutableDictionary dictionary]; |
| 96 | + [results setValue:self.pendingNotifications forKey:@"notifications"]; |
| 97 | + |
| 98 | + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:results]; |
| 99 | + [self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]]; |
| 100 | + |
| 101 | + [self.pendingNotifications removeAllObjects]; |
| 102 | +} |
| 103 | + |
| 104 | ++ (NSMutableDictionary*)getRemoteNotificationStatus { |
| 105 | + |
| 106 | + NSMutableDictionary *results = [NSMutableDictionary dictionary]; |
| 107 | + |
| 108 | + NSUInteger type = 0; |
| 109 | + // Set the defaults to disabled unless we find otherwise... |
| 110 | + NSString *pushBadge = @"0"; |
| 111 | + NSString *pushAlert = @"0"; |
| 112 | + NSString *pushSound = @"0"; |
| 113 | + |
| 114 | +#if !TARGET_IPHONE_SIMULATOR |
| 115 | + |
| 116 | + // Check what Notifications the user has turned on. We registered for all three, but they may have manually disabled some or all of them. |
| 117 | + type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; |
| 118 | + |
| 119 | + // Check what Registered Types are turned on. This is a bit tricky since if two are enabled, and one is off, it will return a number 2... not telling you which |
| 120 | + // one is actually disabled. So we are literally checking to see if rnTypes matches what is turned on, instead of by number. The "tricky" part is that the |
| 121 | + // single notification types will only match if they are the ONLY one enabled. Likewise, when we are checking for a pair of notifications, it will only be |
| 122 | + // true if those two notifications are on. This is why the code is written this way |
| 123 | + if(type == UIRemoteNotificationTypeBadge){ |
| 124 | + pushBadge = @"1"; |
| 125 | + } |
| 126 | + else if(type == UIRemoteNotificationTypeAlert) { |
| 127 | + pushAlert = @"1"; |
| 128 | + } |
| 129 | + else if(type == UIRemoteNotificationTypeSound) { |
| 130 | + pushSound = @"1"; |
| 131 | + } |
| 132 | + else if(type == ( UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)) { |
| 133 | + pushBadge = @"1"; |
| 134 | + pushAlert = @"1"; |
| 135 | + } |
| 136 | + else if(type == ( UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)) { |
| 137 | + pushBadge = @"1"; |
| 138 | + pushSound = @"1"; |
| 139 | + } |
| 140 | + else if(type == ( UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)) { |
| 141 | + pushAlert = @"1"; |
| 142 | + pushSound = @"1"; |
| 143 | + } |
| 144 | + else if(type == ( UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)) { |
| 145 | + pushBadge = @"1"; |
| 146 | + pushAlert = @"1"; |
| 147 | + pushSound = @"1"; |
| 148 | + } |
| 149 | + |
| 150 | +#endif |
| 151 | + |
| 152 | + // Affect results |
| 153 | + [results setValue:[NSString stringWithFormat:@"%d", type] forKey:@"type"]; |
| 154 | + [results setValue:[NSString stringWithFormat:@"%d", type != UIRemoteNotificationTypeNone] forKey:@"enabled"]; |
| 155 | + [results setValue:pushBadge forKey:@"pushBadge"]; |
| 156 | + [results setValue:pushAlert forKey:@"pushAlert"]; |
| 157 | + [results setValue:pushSound forKey:@"pushSound"]; |
| 158 | + |
| 159 | + return results; |
| 160 | + |
| 161 | +} |
| 162 | + |
| 163 | +- (void)getRemoteNotificationStatus:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options { |
| 164 | + //NSLog(@"getRemoteNotificationStatus:%@\n withDict:%@", arguments, options); |
| 165 | + |
| 166 | + // The first argument in the arguments parameter is the callbackID. |
| 167 | + // We use this to send data back to the successCallback or failureCallback |
| 168 | + // through PluginResult. |
| 169 | + self.callbackID = [arguments pop]; |
| 170 | + |
| 171 | + NSMutableDictionary *results = [PushNotification getRemoteNotificationStatus]; |
| 172 | + |
| 173 | + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:results]; |
| 174 | + [self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]]; |
| 175 | +} |
| 176 | + |
| 177 | +- (void)setApplicationIconBadgeNumber:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options { |
| 178 | + //NSLog(@"setApplicationIconBadgeNumber:%@\n withDict:%@", arguments, options); |
| 179 | + |
| 180 | + // The first argument in the arguments parameter is the callbackID. |
| 181 | + // We use this to send data back to the successCallback or failureCallback |
| 182 | + // through PluginResult. |
| 183 | + self.callbackID = [arguments pop]; |
| 184 | + |
| 185 | + int badge = [[options objectForKey:@"badge"] intValue] ?: 0; |
| 186 | + [[UIApplication sharedApplication] setApplicationIconBadgeNumber:badge]; |
| 187 | + |
| 188 | + NSMutableDictionary *results = [NSMutableDictionary dictionary]; |
| 189 | + [results setValue:[NSNumber numberWithInt:badge] forKey:@"badge"]; |
| 190 | + [results setValue:[NSNumber numberWithInt:1] forKey:@"success"]; |
| 191 | + |
| 192 | + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:results]; |
| 193 | + [self writeJavascript:[pluginResult toSuccessCallbackString:self.callbackID]]; |
| 194 | +} |
| 195 | + |
| 196 | +- (void) dealloc { |
| 197 | + [_pendingNotifications dealloc]; |
| 198 | + [super dealloc]; |
| 199 | +} |
| 200 | + |
| 201 | +@end |
0 commit comments