这次优化的主要原因是:前面接入信鸽推送的时候,把相关代码都加到了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];
}
上面代码会报错吗???
解决方案
参考文章