這次優化的主要原因是:前面接入信鴿推送的時候,把相關代碼都加到了AppDelegate中,現在個人感覺AppDelegate中的代碼太多了。。。想着寫個分類把推送相關的代碼整理到一起。
-
分類文件創建Category
爲AppDelegate創建分類,如下圖:
-
AppDelegate+XGPush.h文件中聲明方法
#import "AppDelegate.h"
@interface AppDelegate (XGPush)
/**
XGPush 註冊
@param launchOptions 啓動項
*/
-(void)registerXGPush:(NSDictionary *)launchOptions;
@end
-
AppDelegate+XGPush.m文件中方法實現
#import "AppDelegate+XGPush.h"
#import <objc/runtime.h>
#import "CircularProgressView.h"
//信鴿推送
#import "XGPush.h"
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
#import <UserNotifications/UserNotifications.h>
#endif
//static NSInteger XGAccessId = xg_access_id;
//static NSString *XGAccessKey = xg_access_key;
@interface AppDelegate ()<UNUserNotificationCenterDelegate,XGPushDelegate>
@property (nonatomic, assign) BOOL isLaunchedByNotification;
@end
@implementation AppDelegate (XGPush)
-(void)registerXGPush:(NSDictionary *)launchOptions{
[self registerAPNS];
//註冊信鴿推送
//開啓debug模式
[[XGPush defaultManager] setEnableDebug:YES];
//初始化信鴿
[[XGPush defaultManager] startXGWithAppID:xg_access_id appKey:xg_access_key delegate:self];
[[XGPush defaultManager] setXgApplicationBadgeNumber:0];
[[XGPush defaultManager] reportXGNotificationInfo:launchOptions];
// 判斷程序是不是由推送打開,由推送打開的話,這裏進入(App未打開是收到推送消息)
// 程序未啓動,退出狀態
// 這個時候收到推送消息,無論是點擊推送消息啓動應用還是點擊了應用圖標啓動了應用,都會調用
//- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
// (nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
//這個方法來啓動程序,兩者區別在於點擊推送消息啓動應用會把推送的消息userInfo通過launchOptions參數傳遞過來
//可以通過這個參數是否爲空來判斷程序是否是點擊推送消息啓動了應用。launchOptions有幾個key:
//UIApplicationLaunchOptionsRemoteNotificationKey返回一個遠程推送的userInfo字典類型參數;
//UIApplicationLaunchOptionsLocalNotificationKey返回一個UILocalNotification對象;
//還有別的,大家可以google下。得到了遠程推送的字典,就可以根據需求做處理了。
if (launchOptions) {
self.isLaunchedByNotification = YES;
NSDictionary *pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
[self performSelector:@selector(receiveRemoteNotificationWithUserInfo:) withObject:pushNotificationKey afterDelay:1.0];
}
}
/**
註冊蘋果推送通知服務
*/
-(void)registerAPNS{
if (iOS_SystemVersion < 8.0) {
//iOS7註冊推送通知
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound) ];
}else if (iOS_SystemVersion < 10.0 && iOS_SystemVersion >= 8.0){
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}else{
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
}
}];
[[UIApplication sharedApplication] registerForRemoteNotifications];
#endif
}
}
/**
@param dict 接收到的推送消息
*/
-(void)receiveRemoteNotificationWithUserInfo:(NSDictionary *)dict{
NSLog(@"receiveRemoteNotificationWithUserInfo description===>%@",dict);
//具體業務處理。。。。
}
#pragma mark - Delegate
/**
1,遠程通知註冊成功代理方法
註冊 deviceToken
*/
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken{
NSString *XGPushtokenStr = [[XGPushTokenManager defaultTokenManager] deviceTokenString];
[self uploadTokenString:XGPushtokenStr];
}
/**
在iOS10 以前 收到推送分爲下面兩種形式,如果有方法1,方法2,方法1就不會執行
*/
//iOS 3-10
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
NSLog(@"%s======》",__func__);
NSString *zero =[[[userInfo objectForKey:@"aps"] objectForKey:@"alert"] objectForKey:@"body"];
if (application.applicationState == UIApplicationStateActive) {
[self showAlertViewWithTitle:@"新消息提示" Message:zero ConfirmTitle:@"確定" CancelTitle:nil];
}
[self receiveRemoteNotificationWithUserInfo:userInfo];
}
/**
iOS7 +
iOS10之前,接收遠程通知時,不管在前臺、後臺還是程序殺死都會調用此方法
在前臺,App內展示alert
在後臺,點擊彈框,進入App
*/
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"%s",__func__);
NSLog(@"[XGDemo] receive slient Notification");
NSLog(@"[XGDemo] userinfo %@", userInfo);
NSString *zero =[[[userInfo objectForKey:@"aps"] objectForKey:@"alert"] objectForKey:@"body"];
if (application.applicationState == UIApplicationStateActive) {
//iOS10之前,在前臺時用自定義AlertView展示消息
[self showAlertViewWithTitle:@"新消息提示" Message:zero ConfirmTitle:@"確定" CancelTitle:nil];
[self receiveRemoteNotificationWithUserInfo:userInfo];
}else {
[self receiveRemoteNotificationWithUserInfo:userInfo];
}
//iOS 9.x 及以前,需要在 UIApplicationDelegate 的回調方法(如下)中調用上報數據的接口
[[XGPush defaultManager] reportXGNotificationInfo:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
/**
iOS 10 新增 API
iOS 10 會走新 API, iOS 10 以前會走到老 API
App 在前臺彈通知需要調用這個接口
*/
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
- (void)xgPushUserNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
[[XGPush defaultManager] reportXGNotificationInfo:notification.request.content.userInfo];
//可設置是否在應用內彈出通知
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}
#endif
/**
iOS 10 新增 API
iOS 10 會走新 API, iOS 10 以前會走到老 API
App 用戶點擊通知
App 用戶選擇通知中的行爲
App 用戶在通知中心清除消息
無論本地推送還是遠程推送都會走這個回調
*/
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
- (void)xgPushUserNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSLog(@"%s",__func__);
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
NSLog(@"Userinfo %@",response.notification.request.content.userInfo);
//處理接收到的消息
[self receiveRemoteNotificationWithUserInfo:response.notification.request.content.userInfo];
[[XGPush defaultManager] reportXGNotificationResponse:response];
completionHandler();
}
#endif
-
AppDelegate.m文件中調用
在AppDelegate中方法調用下面方法:
-(void)registerXGPush:(NSDictionary *)launchOptions;
#import "AppDelegate.h"
#import "TCGuideViewController.h"
//引入頭文件
#import "AppDelegate+XGPush.h"
@interface AppDelegate ()<UINavigationControllerDelegate>
@property (nonatomic, assign) BOOL isLaunchedByNotification;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window =[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
#pragma mark -廣告頁
[[AdvertisementManager defauleShowAdvertisementView] setAdvertisementView];
//信鴿推送
[self registerXGPush:launchOptions];
return YES;
}
注意:在Categary中,用@property 形式聲明屬性,然後在實現的類中可以用成員變量直接訪問屬性的值???
AppDelegate+XGPush.h
#import "AppDelegate.h"
@interface AppDelegate (XGPush)
//推送
//聲明屬性
@property (nonatomic, strong) UIView *aKeyPushView;
@property (nonatomic, strong) UILabel *timeLabel;
@property (nonatomic, strong) NSTimer *appTimer;
@property (nonatomic, assign) NSInteger appTimes;
/**
XGPush 註冊
@param launchOptions 啓動項
*/
-(void)registerXGPush:(NSDictionary *)launchOptions;
@end
AppDelegate+XGPush.m
-(void)createUI{
self.aKeyPushView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
_aKeyPushView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
[self.view addSubview:_aKeyPushView];
}
上面代碼會報錯嗎???
解決方案
參考文章