推送对于想在的App来说基本是必备的,但是很多时候大家可能都是一股脑的写到Appdelegate类文件中,不能说不好,只是对于我这样的强迫症和外加一点点的懒的人来说,并不喜欢这样的。出于对功能模块化的考虑,特此将推送整体做了一个封装。代码如下:
.h中
#import "AppDelegate.h"
@interface AppDelegate (MEJPush) <JPUSHRegisterDelegate>
- (void)JPushApplication:(UIApplication *_Nullable)application didFinishLaunchingWithOptions:(NSDictionary *_Nullable)launchOptions;
/// 获得Device Token
- (void)JPushApplication:(UIApplication *_Nullable)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *_Nullable)deviceToken;
/// 获得Device Token失败
- (void)JPushApplication:(UIApplication *_Nullable)application didFailToRegisterForRemoteNotificationsWithError:(NSError *_Nullable)error;
/// iOS 7 以上远程推送消息回调
- (void)JPushApplication:(UIApplication *_Nullable)application didReceiveRemoteNotification:(NSDictionary *_Nullable)userInfo fetchCompletionHandler:(void (^_Nullable)(UIBackgroundFetchResult result))completionHandler;
/// iOS 8 远程推送消息回调
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo completionHandler:(void(^_Nullable)())completionHandler;
/// iOS 9 远程推送消息回调
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo withResponseInfo:(NSDictionary *_Nullable)responseInfo completionHandler:(void(^_Nullable)())completionHandler;
@end
.m中
#import "AppDelegate+MEJPush.h"
#import "MessageManageViewController.h"
//是否为开发环境
static BOOL isProduction = FALSE;
@implementation AppDelegate (MEJPush)
#pragma mark - 注册推送
- (void)registerRemoteNotification:(NSDictionary *)launchOptions {
if (UI_IS_IOS10_AND_HIGHER) {
//极光推送
//notice: 3.0.0及以后版本注册可以这样写,也可以继续用之前的注册方式
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
} else if (UI_IS_IOS8_AND_HIGHER) {
//可以添加自定义categories
[JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert)
categories:nil];
}
#warning TODO 上线和测试 分别使用FALSE 和 YES
[JPUSHService setupWithOption:launchOptions
appKey:kJPush_AppKey
channel:kJPush_channel
apsForProduction:isProduction
advertisingIdentifier:nil];
//设置推送日志
[JPUSHService setDebugMode];
// 极光推送添加观察者
NSNotificationCenter *defaultCenter1 = [NSNotificationCenter defaultCenter];
[defaultCenter1 addObserver:self
selector:@selector(networkIsConnecting:)
name:kJPFNetworkIsConnectingNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(networkDidSetup:)
name:kJPFNetworkDidSetupNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(networkDidClose:)
name:kJPFNetworkDidCloseNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(networkDidRegister:)
name:kJPFNetworkDidRegisterNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(networkFailedRegister:)
name:kJPFNetworkFailedRegisterNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(networkDidLogin:)
name:kJPFNetworkDidLoginNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(networkDidReceiveMessage:)
name:kJPFNetworkDidReceiveMessageNotification
object:nil];
[defaultCenter1 addObserver:self
selector:@selector(serviceError:)
name:kJPFServiceErrorNotification
object:nil];
}
#pragma mark - 监听推送
- (void)JPushApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self registerRemoteNotification:launchOptions];
NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotification) {
NSLog(@"%@",remoteNotification);
[self goToMssageViewControllerWith:launchOptions];
}
// 重新设置app角标
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
// 重新设置角标
[JPUSHService resetBadge];
}
/// 获得Device Token
- (void)JPushApplication:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"deviceToken---%@",[NSString stringWithFormat:@"%@",deviceToken]);
//极光注册设备
[JPUSHService registerDeviceToken:deviceToken];
}
/// 获得Device Token失败
- (void)JPushApplication:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
/// iOS 7 以上远程推送消息回调(不能处理带有categories的推送消息)
- (void)JPushApplication:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
// 取得 APNs 标准信息内容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量
NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
// 取得Extras字段内容
NSString *customizeField1 = [userInfo valueForKey:@"customizeExtras"]; //服务端中Extras字段,key是自己定义的
NSLog(@"content =[%@], badge=[%ld], sound=[%@], customize field =[%@]",content,(long)badge,sound,customizeField1);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
/// iOS 8 远程推送消息回调
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo completionHandler:(void(^_Nullable)())completionHandler {
// 取得 APNs 标准信息内容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量
NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
// 取得Extras字段内容
NSString *customizeField1 = [userInfo valueForKey:@"customizeExtras"]; //服务端中Extras字段,key是自己定义的
NSLog(@"content =[%@], badge=[%ld], sound=[%@], customize field =[%@]",content,(long)badge,sound,customizeField1);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
/// iOS 9 远程推送消息回调
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo withResponseInfo:(NSDictionary *_Nullable)responseInfo completionHandler:(void(^_Nullable)())completionHandler {
// 取得 APNs 标准信息内容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量
NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
// 取得Extras字段内容
NSString *customizeField1 = [userInfo valueForKey:@"customizeExtras"]; //服务端中Extras字段,key是自己定义的
NSLog(@"content =[%@], badge=[%ld], sound=[%@], customize field =[%@]",content,(long)badge,sound,customizeField1);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
#pragma mark - iOS 10 以上将本地和远程推送合而为一,并且增加了接受和点击事件
/// 接收事件
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
// UNNotificationRequest *request = notification.request; // 收到推送的请求
// UNNotificationContent *content = request.content; // 收到推送的消息内容
// NSNumber *badge = content.badge; // 推送消息的角标
// NSString *body = content.body; // 推送消息体
// UNNotificationSound *sound = content.sound; // 推送消息的声音
// NSString *subtitle = content.subtitle; // 推送消息的副标题
// NSString *title = content.title; // 推送消息的标题
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"iOS10 前台收到远程通知:%@", userInfo);
[JPUSHService handleRemoteNotification:userInfo];
} else {
// 本地通知
}
completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
/// 点击事件
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler: (void (^)())completionHandler {
// Required
NSDictionary *userInfo = response.notification.request.content.userInfo;
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSDictionary *content = [aps valueForKey:@"alert"]; //推送显示的内容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量
NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"content =[%@], badge=[%ld], sound=[%@]",content,(long)badge,sound);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
} else {
// 本地通知
}
completionHandler(); // 系统要求执行这个方法
}
#pragma mark - 极光推送监听事件
/// 推送正在连接
- (void)networkIsConnecting:(NSNotification *)notification {
NSLog(@"正在连接 %@", [notification userInfo]);
}
/// 推送建立连接
- (void)networkDidSetup:(NSNotification *)notification {
NSLog(@"建立连接 %@", [notification userInfo]);
}
/// 推送关闭连接
- (void)networkDidClose:(NSNotification *)notification {
NSLog(@"关闭连接 %@", [notification userInfo]);
}
/// 推送注册成功
- (void)networkDidRegister:(NSNotification *)notification {
NSLog(@"注册成功 %@", [notification userInfo]);
}
/// 推送注册失败
- (void)networkFailedRegister:(NSNotification *)notification {
NSLog(@"注册失败 %@", [notification userInfo]);
}
/// 推送登录成功
- (void)networkDidLogin:(NSNotification *)notification {
NSLog(@"已登录 %@", [notification userInfo]);
//存储极光推送的registrationID
[JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
if (resCode != 1011) {
if (registrationID) {
[MELoginInfo saveJpushRegistrationID:[JPUSHService registrationID]];
}
}
}];
}
/// 接收到推送消息 (非远程推送消息)
- (void)networkDidReceiveMessage:(NSNotification *)notification {
NSLog(@"收到消息(非APNS) %@", [notification userInfo]);
NSDictionary * userInfo = [notification userInfo];
NSString *content = [userInfo valueForKey:@"content"];
NSDictionary *extras = [userInfo valueForKey:@"extras"];
NSString *remind = [extras objectForKey:@"extras"];//服务端传递的Extras附加字段,key是自己定义的
NSString *message = [NSString stringWithFormat:@"%@, 本次推送的内容为:%@", remind, content];
UIAlertController *alterController = [UIAlertController alertControllerWithTitle:@"APNs自定义推送消息" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
[alterController addAction:alertAction];
[self.window.rootViewController presentViewController:alterController animated:YES completion:nil];
}
//接收到推送消息 (非远程推送消息)
- (void)kJPFNetworkDidReceiveMessageNotification:(NSNotification *)notification {
NSLog(@"%@",notification);
}
/// 推送错误
- (void)serviceError:(NSNotification *)notification {
NSLog(@"极光推送错误 %@", [notification userInfo]);
}
#pragma mark - 跳转界面
- (void)goToMssageViewControllerWith:(NSDictionary *)userInfo {
if (userInfo.count > 0) {
[MELoginInfo saveJpushReceiveData:userInfo];
NSString *isPush = [userInfo objectForKey:@"isPush"];
if ([isPush isEqualToString:@"1"]) {
[self displayLoginViewControllerWithIdentifier:@"MessageManage_VC"];
}
}
}
#pragma mark - 加载storyboard控制器的公共方法(未登录界面)
- (void)displayLoginViewControllerWithIdentifier:(NSString *)identifier {
UINavigationController *nav = [[UIStoryboard storyboardWithName:@"Mine" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:identifier];
[self.window.rootViewController presentViewController:nav animated:YES completion:nil];
}
@end