JPushPlugin.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. //
  2. // PushTalkPlugin.m
  3. // PushTalk
  4. //
  5. // Created by zhangqinghe on 13-12-13.
  6. //
  7. //
  8. #import "JPushPlugin.h"
  9. #import "JPUSHService.h"
  10. #import <UIKit/UIKit.h>
  11. #import <AdSupport/AdSupport.h>
  12. #import <UserNotifications/UserNotifications.h>
  13. #import "AppDelegate+JPush.h"
  14. static NSString *const JP_APP_KEY = @"APP_KEY";
  15. static NSString *const JP_APP_CHANNEL = @"CHANNEL";
  16. static NSString *const JP_APP_ISPRODUCTION = @"IsProduction";
  17. static NSString *const JP_APP_ISIDFA = @"IsIDFA";
  18. static NSString *const JPushConfigFileName = @"PushConfig";
  19. static NSDictionary *_launchOptions = nil;
  20. #define WEAK_SELF(weakSelf) __weak __typeof(&*self)weakSelf = self;
  21. @implementation NSDictionary (JPush)
  22. -(NSString*)toJsonString{
  23. NSError *error;
  24. NSData *data = [NSJSONSerialization dataWithJSONObject:self options:0 error:&error];
  25. NSString *jsonString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
  26. return jsonString;
  27. }
  28. @end
  29. @implementation NSString (JPush)
  30. -(NSDictionary*)toDictionary{
  31. NSError *error;
  32. NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
  33. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
  34. return dict;
  35. }
  36. @end
  37. @interface JPushPlugin()
  38. @end
  39. @implementation JPushPlugin
  40. #pragma mark- 外部接口
  41. -(void)stopPush:(CDVInvokedUrlCommand*)command{
  42. [[UIApplication sharedApplication]unregisterForRemoteNotifications];
  43. }
  44. -(void)resumePush:(CDVInvokedUrlCommand*)command{
  45. [JPushPlugin registerForRemoteNotification];
  46. }
  47. -(void)isPushStopped:(CDVInvokedUrlCommand*)command{
  48. NSNumber *result;
  49. if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
  50. result = @(0);
  51. }else{
  52. result = @(1);
  53. }
  54. [self handleResultWithValue:result command:command];
  55. }
  56. -(void)initial:(CDVInvokedUrlCommand*)command{
  57. //do nithng,because Cordova plugin use lazy load mode.
  58. }
  59. #ifdef __CORDOVA_4_0_0
  60. - (void)pluginInitialize {
  61. NSLog(@"### pluginInitialize ");
  62. [self initNotifications];
  63. }
  64. #else
  65. - (CDVPlugin*)initWithWebView:(UIWebView*)theWebView{
  66. NSLog(@"### initWithWebView ");
  67. if (self=[super initWithWebView:theWebView]) {
  68. [self initNotifications];
  69. }
  70. return self;
  71. }
  72. #endif
  73. -(void)initNotifications {
  74. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  75. [defaultCenter addObserver:self
  76. selector:@selector(networkDidReceiveMessage:)
  77. name:kJPFNetworkDidReceiveMessageNotification
  78. object:nil];
  79. [defaultCenter addObserver:self
  80. selector:@selector(networkDidReceiveNotification:)
  81. name:kJPushPluginReceiveNotification
  82. object:nil];
  83. [defaultCenter addObserver:self
  84. selector:@selector(networkDidReceiveNotification:)
  85. name:kJPushPluginiOS10ForegroundReceiveNotification
  86. object:nil];
  87. [defaultCenter addObserver:self
  88. selector:@selector(networkDidReceiveNotification:)
  89. name:kJPushPluginiOS10ClickNotification
  90. object:nil];
  91. if (_launchOptions) {
  92. NSDictionary *userInfo = [_launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
  93. if ([userInfo count] >0) {
  94. dispatch_async(dispatch_get_main_queue(), ^{
  95. [self.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireDocumentEvent('jpush.openNotification',%@)",[userInfo toJsonString]]];
  96. });
  97. }
  98. }
  99. }
  100. -(void)setTagsWithAlias:(CDVInvokedUrlCommand*)command{
  101. NSArray *arguments = command.arguments;
  102. NSString *alias;
  103. NSArray *tags;
  104. if (!arguments || [arguments count] < 2) {
  105. NSLog(@"#### setTagsWithAlias param is less");
  106. return ;
  107. }else{
  108. alias = arguments[0];
  109. tags = arguments[1];
  110. }
  111. NSLog(@"#### setTagsWithAlias alias is %@, tags is %@",alias,tags);
  112. [JPUSHService setTags:[NSSet setWithArray:tags]
  113. alias:alias
  114. callbackSelector:@selector(tagsWithAliasCallback:tags:alias:)
  115. object:self];
  116. }
  117. -(void)setTags:(CDVInvokedUrlCommand *)command{
  118. NSArray *tags = command.arguments;
  119. NSLog(@"#### setTags %@",tags);
  120. [JPUSHService setTags:[NSSet setWithArray:tags]
  121. callbackSelector:@selector(tagsWithAliasCallback:tags:alias:)
  122. object:self];
  123. }
  124. -(void)setAlias:(CDVInvokedUrlCommand *)command{
  125. NSLog(@"#### setAlias %@",command.arguments);
  126. [JPUSHService setAlias:command.arguments[0]
  127. callbackSelector:@selector(tagsWithAliasCallback:tags:alias:)
  128. object:self];
  129. }
  130. -(void)getRegistrationID:(CDVInvokedUrlCommand*)command{
  131. NSString* registrationID = [JPUSHService registrationID];
  132. NSLog(@"### getRegistrationID %@",registrationID);
  133. [self handleResultWithValue:registrationID command:command];
  134. }
  135. -(void)startLogPageView:(CDVInvokedUrlCommand*)command{
  136. NSArray *arguments = command.arguments;
  137. if (!arguments || [arguments count] < 1) {
  138. NSLog(@"startLogPageView argument error");
  139. return ;
  140. }
  141. NSString * pageName = arguments[0];
  142. if (pageName) {
  143. [JPUSHService startLogPageView:pageName];
  144. }
  145. }
  146. -(void)stopLogPageView:(CDVInvokedUrlCommand*)command{
  147. NSArray *arguments = command.arguments;
  148. if (!arguments || [arguments count] < 1) {
  149. NSLog(@"stopLogPageView argument error");
  150. return ;
  151. }
  152. NSString * pageName = arguments[0];
  153. if (pageName) {
  154. [JPUSHService stopLogPageView:pageName];
  155. }
  156. }
  157. -(void)beginLogPageView:(CDVInvokedUrlCommand*)command{
  158. NSArray *arguments = command.arguments;
  159. if (!arguments || [arguments count] < 2) {
  160. NSLog(@"beginLogPageView argument error");
  161. return ;
  162. }
  163. NSString * pageName = arguments[0];
  164. int duration = [arguments[0] intValue];
  165. if (pageName) {
  166. [JPUSHService beginLogPageView:pageName duration:duration];
  167. }
  168. }
  169. -(void)setBadge:(CDVInvokedUrlCommand*)command{
  170. NSArray *argument = command.arguments;
  171. if ([argument count] < 1) {
  172. NSLog(@"setBadge argument error!");
  173. return;
  174. }
  175. NSNumber *badge = argument[0];
  176. [JPUSHService setBadge:[badge intValue]];
  177. }
  178. -(void)resetBadge:(CDVInvokedUrlCommand*)command{
  179. [JPUSHService resetBadge];
  180. }
  181. -(void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command{
  182. //
  183. NSArray *argument = command.arguments;
  184. if ([argument count] < 1) {
  185. NSLog(@"setBadge argument error!");
  186. return;
  187. }
  188. NSNumber *badge = [argument objectAtIndex:0];
  189. [UIApplication sharedApplication].applicationIconBadgeNumber = [badge intValue];
  190. }
  191. -(void)getApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command {
  192. NSInteger num = [UIApplication sharedApplication].applicationIconBadgeNumber;
  193. NSNumber *number = [NSNumber numberWithInteger:num];
  194. [self handleResultWithValue:number command:command];
  195. }
  196. -(void)setDebugModeFromIos:(CDVInvokedUrlCommand*)command{
  197. [JPUSHService setDebugMode];
  198. }
  199. -(void)setLogOFF:(CDVInvokedUrlCommand*)command{
  200. [JPUSHService setLogOFF];
  201. }
  202. -(void)crashLogON:(CDVInvokedUrlCommand*)command{
  203. [JPUSHService crashLogON];
  204. }
  205. -(void)setLocalNotification:(CDVInvokedUrlCommand*)command{
  206. NSArray *arguments = command.arguments;
  207. NSDate *date = arguments[0] == [NSNull null] ? nil : [NSDate dateWithTimeIntervalSinceNow:[((NSString*)arguments[0]) intValue]];
  208. NSString *alertBody = arguments[1] == [NSNull null] ? nil : (NSString*)arguments[1];
  209. int badge = arguments[2] == [NSNull null] ? 0 : [(NSString*)arguments[2] intValue];
  210. NSString *idKey = arguments[3] == [NSNull null] ? nil : (NSString*)arguments[3];
  211. NSDictionary *dict = arguments[4] == [NSNull null] ? nil : (NSDictionary*)arguments[4];
  212. [JPUSHService setLocalNotification:date alertBody:alertBody badge:badge alertAction:nil identifierKey:idKey userInfo:dict soundName:nil];
  213. }
  214. -(void)deleteLocalNotificationWithIdentifierKey:(CDVInvokedUrlCommand*)command{
  215. NSString *identifier = [command argumentAtIndex:0];
  216. if ([UIDevice currentDevice].systemVersion.floatValue >= 10.0) {
  217. JPushNotificationIdentifier *jpid = [JPushNotificationIdentifier new];
  218. jpid.identifiers = @[identifier];
  219. [JPUSHService removeNotification:jpid];
  220. }else{
  221. [JPUSHService deleteLocalNotificationWithIdentifierKey:identifier];
  222. }
  223. }
  224. -(void)clearAllLocalNotifications:(CDVInvokedUrlCommand*)command{
  225. [JPUSHService clearAllLocalNotifications];
  226. }
  227. -(void)setLocation:(CDVInvokedUrlCommand*)command{
  228. [JPUSHService setLatitude:[((NSString*)command.arguments[0]) doubleValue] longitude:[((NSString*)command.arguments[1]) doubleValue]];
  229. }
  230. -(void)getUserNotificationSettings:(CDVInvokedUrlCommand*)command{
  231. if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
  232. UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  233. WEAK_SELF(weakSelf);
  234. [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
  235. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
  236. dict[@"authorizationStatus"] = @(settings.authorizationStatus);
  237. dict[@"soundSetting"] = @(settings.soundSetting);
  238. dict[@"badgeSetting"] = @(settings.badgeSetting);
  239. dict[@"alertSetting"] = @(settings.alertSetting);
  240. dict[@"notificationCenterSetting"] = @(settings.notificationCenterSetting);
  241. dict[@"lockScreenSetting"] = @(settings.lockScreenSetting);
  242. dict[@"carPlaySetting"] = @(settings.carPlaySetting);
  243. dict[@"alertStyle"] = @(settings.alertStyle);
  244. [weakSelf handleResultWithValue:dict command:command];
  245. }];
  246. }else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  247. UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
  248. UIUserNotificationType type = settings.types;
  249. NSNumber *number = [NSNumber numberWithInteger:type];
  250. [self handleResultWithValue:number command:command];
  251. }else{
  252. UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
  253. NSNumber *number = [NSNumber numberWithInteger:type];
  254. [self handleResultWithValue:number command:command];
  255. }
  256. }
  257. #pragma mark - ios 10 APIs
  258. -(void)addDismissActions:(CDVInvokedUrlCommand*)command{
  259. [self addActions:command dismiss:YES];
  260. }
  261. -(void)addNotificationActions:(CDVInvokedUrlCommand*)command{
  262. [self addActions:command dismiss:NO];
  263. }
  264. -(void)addActions:(CDVInvokedUrlCommand*)command dismiss:(BOOL)dimiss{
  265. NSArray *actionsData = [command argumentAtIndex:0];
  266. NSString *categoryId = [command argumentAtIndex:1];
  267. NSMutableArray *actions = [NSMutableArray array];
  268. for (NSDictionary *dict in actionsData) {
  269. NSString *title = dict[@"title"];
  270. NSString *identifier = dict[@"identifier"];
  271. NSString *option = dict[@"option"];
  272. NSString *type = dict[@"type"];
  273. if ([type isEqualToString:@"textInput"]) {
  274. NSString *textInputButtonTitle = dict[@"textInputButtonTitle"];
  275. NSString *textInputPlaceholder = dict[@"textInputPlaceholder"];
  276. UNTextInputNotificationAction *inputAction = [UNTextInputNotificationAction actionWithIdentifier:identifier title:title options:option.integerValue textInputButtonTitle:textInputButtonTitle textInputPlaceholder:textInputPlaceholder];
  277. [actions addObject:inputAction];
  278. }else{
  279. UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:title title:title options:option.integerValue];
  280. [actions addObject:action];
  281. }
  282. }
  283. UNNotificationCategory *category;
  284. if (dimiss) {
  285. category = [UNNotificationCategory categoryWithIdentifier:categoryId actions:actions intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
  286. }else{
  287. category = [UNNotificationCategory categoryWithIdentifier:categoryId actions:actions intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
  288. }
  289. [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:category]];
  290. }
  291. #pragma mark - 内部方法
  292. +(void)setLaunchOptions:(NSDictionary *)theLaunchOptions{
  293. _launchOptions = theLaunchOptions;
  294. [JPUSHService setDebugMode];
  295. [JPushPlugin registerForRemoteNotification];
  296. //read appkey and channel from PushConfig.plist
  297. NSString *plistPath = [[NSBundle mainBundle] pathForResource:JPushConfigFileName ofType:@"plist"];
  298. if (plistPath == nil) {
  299. NSLog(@"error: PushConfig.plist not found");
  300. assert(0);
  301. }
  302. NSMutableDictionary *plistData = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
  303. NSString * appkey = [plistData valueForKey:JP_APP_KEY];
  304. NSString * channel = [plistData valueForKey:JP_APP_CHANNEL];
  305. NSNumber * isProduction = [plistData valueForKey:JP_APP_ISPRODUCTION];
  306. NSNumber *isIDFA = [plistData valueForKey:JP_APP_ISIDFA];
  307. NSString *advertisingId = nil;
  308. if(isIDFA){
  309. advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
  310. }
  311. [JPUSHService setupWithOption:_launchOptions
  312. appKey:appkey
  313. channel:channel
  314. apsForProduction:[isProduction boolValue]
  315. advertisingIdentifier:advertisingId];
  316. }
  317. +(void)registerForRemoteNotification{
  318. [(AppDelegate*)[UIApplication sharedApplication].delegate registerForIos10RemoteNotification];
  319. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  320. //可以添加自定义categories
  321. [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
  322. UIUserNotificationTypeSound |
  323. UIUserNotificationTypeAlert)
  324. categories:nil];
  325. } else if([[UIDevice currentDevice].systemVersion floatValue] < 8.0){
  326. //categories 必须为nil
  327. [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
  328. UIRemoteNotificationTypeSound |
  329. UIRemoteNotificationTypeAlert)
  330. categories:nil];
  331. }
  332. }
  333. #pragma mark 将参数返回给js
  334. -(void)handleResultWithValue:(id)value command:(CDVInvokedUrlCommand*)command{
  335. CDVPluginResult *result = nil;
  336. CDVCommandStatus status = CDVCommandStatus_OK;
  337. if ([value isKindOfClass:[NSString class]]) {
  338. value = [value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  339. } else if ([value isKindOfClass:[NSNull class]]) {
  340. value = nil;
  341. }
  342. if ([value isKindOfClass:[NSObject class]]) {
  343. result = [CDVPluginResult resultWithStatus:status messageAsString:value];//NSObject 类型都可以
  344. } else {
  345. NSLog(@"Cordova callback block returned unrecognized type: %@", NSStringFromClass([value class]));
  346. result = nil;
  347. }
  348. if (!result) {
  349. result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
  350. }
  351. [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
  352. }
  353. #pragma mark 设置标签及别名回调
  354. -(void)tagsWithAliasCallback:(int)resultCode tags:(NSSet *)tags alias:(NSString *)alias{
  355. NSDictionary *dict = @{@"resultCode":[NSNumber numberWithInt:resultCode],
  356. @"tags" :tags == nil ? [NSNull null] : [tags allObjects],
  357. @"alias" :alias == nil ? [NSNull null] : alias
  358. };
  359. dispatch_async(dispatch_get_main_queue(), ^{
  360. [self.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireDocumentEvent('jpush.setTagsWithAlias',%@)",[dict toJsonString]]];
  361. });
  362. }
  363. - (void)networkDidReceiveMessage:(NSNotification *)notification {
  364. if (notification) {
  365. dispatch_async(dispatch_get_main_queue(), ^{
  366. [self.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireDocumentEvent('jpush.receiveMessage',%@)",[notification.userInfo toJsonString]]];
  367. [self.commandDelegate evalJs:[NSString stringWithFormat:@"window.plugins.jPushPlugin.receiveMessageIniOSCallback('%@')",[notification.userInfo toJsonString]]];
  368. });
  369. }
  370. }
  371. -(void)networkDidReceiveNotification:(NSNotification *)notification{
  372. NSError *error;
  373. NSDictionary *userInfo = [notification object];
  374. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userInfo options:0 error:&error];
  375. NSString *jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
  376. switch ([UIApplication sharedApplication].applicationState) {
  377. case UIApplicationStateActive:{
  378. //前台收到
  379. dispatch_async(dispatch_get_main_queue(), ^{
  380. [self.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireDocumentEvent('jpush.receiveNotification',%@)",jsonString]];
  381. });
  382. break;
  383. }
  384. case UIApplicationStateInactive:{
  385. //后台点击
  386. dispatch_async(dispatch_get_main_queue(), ^{
  387. [self.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireDocumentEvent('jpush.openNotification',%@)",jsonString]];
  388. });
  389. break;
  390. }
  391. case UIApplicationStateBackground:{
  392. //后台收到
  393. dispatch_async(dispatch_get_main_queue(), ^{
  394. [self.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireDocumentEvent('jpush.backgoundNotification',%@)",jsonString]];
  395. });
  396. break;
  397. }
  398. default:
  399. //do nothing
  400. break;
  401. }
  402. }
  403. @end