推送對(duì)于想在的App來說基本是必備的,但是很多時(shí)候大家可能都是一股腦的寫到Appdelegate類文件中,不能說不好,只是對(duì)于我這樣的強(qiáng)迫癥和外加一點(diǎn)點(diǎn)的懶的人來說,并不喜歡這樣的。出于對(duì)功能模塊化的考慮,特此將推送整體做了一個(gè)封裝。代碼如下:
.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 以上遠(yuǎn)程推送消息回調(diào)
- (void)JPushApplication:(UIApplication *_Nullable)application didReceiveRemoteNotification:(NSDictionary *_Nullable)userInfo fetchCompletionHandler:(void (^_Nullable)(UIBackgroundFetchResult result))completionHandler;
/// iOS 8 遠(yuǎn)程推送消息回調(diào)
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo completionHandler:(void(^_Nullable)())completionHandler;
/// iOS 9 遠(yuǎn)程推送消息回調(diào)
- (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"
//是否為開發(fā)環(huán)境
static BOOL isProduction = FALSE;
@implementation AppDelegate (MEJPush)
#pragma mark - 注冊(cè)推送
- (void)registerRemoteNotification:(NSDictionary *)launchOptions {
if (UI_IS_IOS10_AND_HIGHER) {
//極光推送
//notice: 3.0.0及以后版本注冊(cè)可以這樣寫,也可以繼續(xù)用之前的注冊(cè)方式
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 上線和測(cè)試 分別使用FALSE 和 YES
[JPUSHService setupWithOption:launchOptions
appKey:kJPush_AppKey
channel:kJPush_channel
apsForProduction:isProduction
advertisingIdentifier:nil];
//設(shè)置推送日志
[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 - 監(jiān)聽推送
- (void)JPushApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self registerRemoteNotification:launchOptions];
NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotification) {
NSLog(@"%@",remoteNotification);
[self goToMssageViewControllerWith:launchOptions];
}
// 重新設(shè)置app角標(biāo)
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
// 重新設(shè)置角標(biāo)
[JPUSHService resetBadge];
}
/// 獲得Device Token
- (void)JPushApplication:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"deviceToken---%@",[NSString stringWithFormat:@"%@",deviceToken]);
//極光注冊(cè)設(shè)備
[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 以上遠(yuǎn)程推送消息回調(diào)(不能處理帶有categories的推送消息)
- (void)JPushApplication:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
// 取得 APNs 標(biāo)準(zhǔn)信息內(nèi)容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送顯示的內(nèi)容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge數(shù)量
NSString *sound = [aps valueForKey:@"sound"]; //播放的聲音
// 取得Extras字段內(nèi)容
NSString *customizeField1 = [userInfo valueForKey:@"customizeExtras"]; //服務(wù)端中Extras字段,key是自己定義的
NSLog(@"content =[%@], badge=[%ld], sound=[%@], customize field =[%@]",content,(long)badge,sound,customizeField1);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
/// iOS 8 遠(yuǎn)程推送消息回調(diào)
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo completionHandler:(void(^_Nullable)())completionHandler {
// 取得 APNs 標(biāo)準(zhǔn)信息內(nèi)容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送顯示的內(nèi)容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge數(shù)量
NSString *sound = [aps valueForKey:@"sound"]; //播放的聲音
// 取得Extras字段內(nèi)容
NSString *customizeField1 = [userInfo valueForKey:@"customizeExtras"]; //服務(wù)端中Extras字段,key是自己定義的
NSLog(@"content =[%@], badge=[%ld], sound=[%@], customize field =[%@]",content,(long)badge,sound,customizeField1);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UNNotificationPresentationOptionAlert); // 需要執(zhí)行這個(gè)方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以設(shè)置
}
/// iOS 9 遠(yuǎn)程推送消息回調(diào)
- (void)JPushApplication:(UIApplication *_Nullable)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *_Nullable)userInfo withResponseInfo:(NSDictionary *_Nullable)responseInfo completionHandler:(void(^_Nullable)())completionHandler {
// 取得 APNs 標(biāo)準(zhǔn)信息內(nèi)容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送顯示的內(nèi)容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge數(shù)量
NSString *sound = [aps valueForKey:@"sound"]; //播放的聲音
// 取得Extras字段內(nèi)容
NSString *customizeField1 = [userInfo valueForKey:@"customizeExtras"]; //服務(wù)端中Extras字段,key是自己定義的
NSLog(@"content =[%@], badge=[%ld], sound=[%@], customize field =[%@]",content,(long)badge,sound,customizeField1);
[self goToMssageViewControllerWith:aps];
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UNNotificationPresentationOptionAlert); // 需要執(zhí)行這個(gè)方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以設(shè)置
}
#pragma mark - iOS 10 以上將本地和遠(yuǎn)程推送合而為一,并且增加了接受和點(diǎn)擊事件
/// 接收事件
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
// UNNotificationRequest *request = notification.request; // 收到推送的請(qǐng)求
// UNNotificationContent *content = request.content; // 收到推送的消息內(nèi)容
// NSNumber *badge = content.badge; // 推送消息的角標(biāo)
// NSString *body = content.body; // 推送消息體
// UNNotificationSound *sound = content.sound; // 推送消息的聲音
// NSString *subtitle = content.subtitle; // 推送消息的副標(biāo)題
// NSString *title = content.title; // 推送消息的標(biāo)題
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"iOS10 前臺(tái)收到遠(yuǎn)程通知:%@", userInfo);
[JPUSHService handleRemoteNotification:userInfo];
} else {
// 本地通知
}
completionHandler(UNNotificationPresentationOptionAlert); // 需要執(zhí)行這個(gè)方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以設(shè)置
}
/// 點(diǎn)擊事件
- (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"]; //推送顯示的內(nèi)容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge數(shù)量
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(); // 系統(tǒng)要求執(zhí)行這個(gè)方法
}
#pragma mark - 極光推送監(jiān)聽事件
/// 推送正在連接
- (void)networkIsConnecting:(NSNotification *)notification {
NSLog(@"正在連接 %@", [notification userInfo]);
}
/// 推送建立連接
- (void)networkDidSetup:(NSNotification *)notification {
NSLog(@"建立連接 %@", [notification userInfo]);
}
/// 推送關(guān)閉連接
- (void)networkDidClose:(NSNotification *)notification {
NSLog(@"關(guān)閉連接 %@", [notification userInfo]);
}
/// 推送注冊(cè)成功
- (void)networkDidRegister:(NSNotification *)notification {
NSLog(@"注冊(cè)成功 %@", [notification userInfo]);
}
/// 推送注冊(cè)失敗
- (void)networkFailedRegister:(NSNotification *)notification {
NSLog(@"注冊(cè)失敗 %@", [notification userInfo]);
}
/// 推送登錄成功
- (void)networkDidLogin:(NSNotification *)notification {
NSLog(@"已登錄 %@", [notification userInfo]);
//存儲(chǔ)極光推送的registrationID
[JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
if (resCode != 1011) {
if (registrationID) {
[MELoginInfo saveJpushRegistrationID:[JPUSHService registrationID]];
}
}
}];
}
/// 接收到推送消息 (非遠(yuǎn)程推送消息)
- (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"];//服務(wù)端傳遞的Extras附加字段,key是自己定義的
NSString *message = [NSString stringWithFormat:@"%@, 本次推送的內(nèi)容為:%@", remind, content];
UIAlertController *alterController = [UIAlertController alertControllerWithTitle:@"APNs自定義推送消息" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"確認(rèn)" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
[alterController addAction:alertAction];
[self.window.rootViewController presentViewController:alterController animated:YES completion:nil];
}
//接收到推送消息 (非遠(yuǎn)程推送消息)
- (void)kJPFNetworkDidReceiveMessageNotification:(NSNotification *)notification {
NSLog(@"%@",notification);
}
/// 推送錯(cuò)誤
- (void)serviceError:(NSNotification *)notification {
NSLog(@"極光推送錯(cuò)誤 %@", [notification userInfo]);
}
#pragma mark - 跳轉(zhuǎn)界面
- (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