极光推送集成(八)—— 工程实践

版本记录

版本号 时间
V1.0 2017.07.24

前言

前一篇已经对ios的SDK进行了研究,这一篇结合工程实践进行说明极光推送的使用。
1. 极光推送集成(一)

2. 极光推送集成(二)

3. 极光推送集成(三)

4. 极光推送集成(四)

5. 极光推送集成(五)

6. 极光推送集成(六)

7. 极光推送集成(七)

下面结合工程实践进行说明。

功能实现

前面几篇都是基础理论,这一篇主要就是结合具体工程实践说明一下极光推送。

下面我们就直接看代码吧。

1. AppDelegate中注册和处理主逻辑

1. AppDelegate.m
//头文件
#import "JPUSHService.h"
#import <UserNotifications/UserNotifications.h>
#import <AdSupport/ASIdentifierManager.h>

#pragma mark - Override Base Function

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    [self settingJPush:launchOptions];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
{
    // Required,For systems with less than or equal to iOS6
    [JPUSHService handleRemoteNotification:userInfo];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
{
    //注册 DeviceToken
    [JPUSHService registerDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error 
{
    NSLog(@"极光推送错误信息提示:%@",error.localizedDescription);
}

//收到通知后的处理 iOS7以后的方法 极光推送
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 
{
    NSDictionary *userinfo =[userInfo valueForKey:@"userinfo"];
    NSLog(@"推送通知信息:%@",userInfo);
    
    if(application.applicationState == UIApplicationStateInactive){
        [self showJPushWithDic:userInfo];
    }
    application.applicationIconBadgeNumber =0;
    [JPUSHService handleRemoteNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}

#pragma mark - Object Private Function

- (void) settingJPush:(NSDictionary *)launchOptions  
{
    /*极光推送start*/
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    
    [defaultCenter addObserver:self selector:@selector(networkDidSetup:) name:kJPFNetworkDidSetupNotification object:nil];//建立连接
    [defaultCenter addObserver:self selector:@selector(networkDidClose:) name:kJPFNetworkDidCloseNotification object:nil];//关闭连接
    [defaultCenter addObserver:self selector:@selector(networkDidRegister:) name:kJPFNetworkDidRegisterNotification object:nil];//注册成功
    [defaultCenter addObserver:self selector:@selector(networkDidRegisterFail:) name:kJPFNetworkFailedRegisterNotification object:nil];//注册失败
    [defaultCenter addObserver:self selector:@selector(networkDidLogin:) name:kJPFNetworkDidLoginNotification object:nil];//登录成功
    [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];//自定义消息
    
    NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
        JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
        entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
        [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
    }
    else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                          UIUserNotificationTypeSound |
                                                          UIUserNotificationTypeAlert)
                                              categories:nil];
    }
    else {
        //categories 必须为nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                          UIRemoteNotificationTypeSound |
                                                          UIRemoteNotificationTypeAlert)
                                              categories:nil];
    }
    [JPUSHService setupWithOption:launchOptions appKey:@"您在极光平台注册的appKey"
                          channel:@"Publish channel"
                 apsForProduction:YES
            advertisingIdentifier:advertisingId];

  /*极光推送end*/
}

- (void)showJPushWithDic:(NSDictionary *)dic
{
    JJBannerModel *bannerModel = [JJBannerModel modelWithDictionary:dic];
    UIViewController *root_VC = self.window.rootViewController;
    if ([root_VC.className isEqualToString:[JJmianTabBarVC className]]) {
        JJmianTabBarVC *tabbarVC = (JJmianTabBarVC *)root_VC;
        UIViewController *selected_VC = tabbarVC.selectedViewController;
        if ([selected_VC isKindOfClass:[UINavigationController class]]) {
            UINavigationController *cus_VC = (UINavigationController*)selected_VC;
            NSArray *navs = cus_VC.viewControllers;
            for (UIViewController *Main_VC in navs) {
                if (([Main_VC.className isEqualToString:[JJLivelistController className]])||([Main_VC.className isEqualToString:[JJVideoAlbumVC className]]) || ([Main_VC.className isEqualToString:[JJShortVideoVC className]])) {
                    UIViewController *next_VC = nil;
                    if ([Main_VC.className isEqualToString:[JJLivelistController className]]) {
                        next_VC = (JJLivelistController*)Main_VC;
                    }
                    else if ([Main_VC.className isEqualToString:[JJShortVideoVC className]]) {
                        next_VC = (JJShortVideoVC*)Main_VC;
                    } 
                   else if ([Main_VC.className isEqualToString:[JJVideoAlbumVC className]]){
                        next_VC = (JJVideoAlbumVC*)Main_VC;
                    }
                    if (bannerModel.jumpType.integerValue == 3 || bannerModel.jumpType.integerValue == 7 || bannerModel.jumpType.integerValue == 8) {
                        if ([[JJConfig myProfile].token isEqualToString:kYoukeToken]) {
                            [[NSNotificationCenter defaultCenter] postNotificationName:kTokenExpired object:nil];
                            return;
                        }
                    }
                    if (bannerModel.jumpType.integerValue == 1) {//普通url
                        JJActiveViewController *nextVC = [[JJActiveViewController alloc] init];
                        nextVC.request = [NSURLRequest requestWithURL:[NSURL URLWithString:bannerModel.jumpUrl]];
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 2) {//广告url
                        JJActiveViewController *nextVC = [[JJActiveViewController alloc] init];
                        nextVC.request = [NSURLRequest requestWithURL:[NSURL URLWithString:bannerModel.jumpUrl]];
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 3) {//小组
                        JJShortVideoTeamMainZoneVC *nextVC = [[JJShortVideoTeamMainZoneVC alloc] init];
                        nextVC.groupId = bannerModel.jumpToId;
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 4) {//短视频
                        JJShortVideoVodVC *nextVC = [[JJShortVideoVodVC alloc] init];
                        JJShortVideoModel *shortVideoModel = [[JJShortVideoModel alloc] init];
                        shortVideoModel.shortVideoId = bannerModel.jumpToId.integerValue;
                        nextVC.model = shortVideoModel;
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 5) {//直播
                        JJLivePlayVC *nextVC = [[JJLivePlayVC alloc] init];
                        JJLiveModel *model = [[JJLiveModel alloc] init];
                        model.albumId = bannerModel.albumId;
                        model.programPlayId = bannerModel.jumpToId;
                        nextVC.model = model;
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } else if (bannerModel.jumpType.integerValue == 6) {//点播
                        JJLiveVodVC *nextVC = [[JJLiveVodVC alloc] init];
                        JJLiveModel *model = [[JJLiveModel alloc] init];
                        model.albumId = bannerModel.albumId;
                        model.programPlayId = bannerModel.jumpToId;
                        nextVC.model = model;
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 7) {//用户主页
                        JJPersonInfoDisplayVC *nextVC = [[JJPersonInfoDisplayVC alloc] init];
                        nextVC.userId = bannerModel.jumpToId.integerValue;
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 8) {//钱包
                        JJRechargeViewController *nextVC = [[JJRechargeViewController alloc] init];
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    } 
                    else if (bannerModel.jumpType.integerValue == 9) {//排行榜
                        JJRankingController *nextVC = [[JJRankingController alloc] init];
                        [next_VC.navigationController pushViewController:nextVC animated:YES];
                    }
                }
            }
        }
    }
}

#pragma mark - Action && Notificaticon

- (void)networkDidSetup:(NSNotification *)notification 
{
    NSLog(@"已连接");
}

- (void)networkDidClose:(NSNotification *)notification 
{
    NSLog(@"关闭连接。。。");
}

- (void)networkDidRegister:(NSNotification *)notification 
{
    NSLog(@"已注册");
}
- (void)networkDidRegisterFail:(NSNotification *)notification 
{
    NSLog(@"注册失败");
}

- (void)networkDidLogin:(NSNotification *)notification 
{
    NSLog(@"已登录");
}

- (void)networkDidReceiveMessage:(NSNotification *)notification 
{
    DDLogDebug(@"自定义消息");
}

#pragma mark - JPUSHRegisterDelegate

// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler 
{
    // Required
    NSDictionary * userInfo = notification.request.content.userInfo;
    
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
}

// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler 
{
    NSDictionary * userInfo_all = response.notification.request.content.userInfo;
    NSDictionary *userInfo =[userInfo_all valueForKey:@"userinfo"];
    
    UIApplication *application = [UIApplication sharedApplication];
    if(application.applicationState == UIApplicationStateInactive){
        [self showJPushWithDic:userInfo_all];
    } 
    else if (application.applicationState == UIApplicationStateBackground) {
        [self showJPushWithDic:userInfo_all];
    } 
    else {
        NSLog(@"hout");
    }

    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    completionHandler();  // 系统要求执行这个方法
}

上面对信息的展示都集中在下面这两个代理方法中。

@protocol JPUSHRegisterDelegate <NSObject>

/*
 * @brief handle UserNotifications.framework [willPresentNotification:withCompletionHandler:]
 * @param center [UNUserNotificationCenter currentNotificationCenter] 新特性用户通知中心
 * @param notification 前台得到的的通知对象
 * @param completionHandler 该callback中的options 请使用UNNotificationPresentationOptions
 */
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger options))completionHandler;


![u=3361423803,1933817347&fm=26&gp=0.jpg](http://upload-images.jianshu.io/upload_images/3691932-b5d08f6a44b7c6a6.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
/*
 * @brief handle UserNotifications.framework [didReceiveNotificationResponse:withCompletionHandler:]
 * @param center [UNUserNotificationCenter currentNotificationCenter] 新特性用户通知中心
 * @param response 通知响应对象
 * @param completionHandler
 */
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler;

@end

2. 忘记密码重新找回成功后登陆

在忘记密码找回成功重新登录加上以下逻辑。

 NSString *aliasStr = [NSString stringWithFormat:@"%@PUSH",[ZBConfig getOwnID]];
 [JPUSHService setAlias:aliasStr callbackSelector:nil object:nil];

3. 在三方登录和手机号登录成功处添加极光别名设置

NSString *aliasStr = [NSString stringWithFormat:@"%@PUSH",[ZBConfig getOwnID]];
[JPUSHService setAlias:aliasStr callbackSelector:nil object:nil];

4. 主页面

#import "JJmianTabBarVC.h"

[JPUSHService setAlias:@"" callbackSelector:nil object:nil];

5. 退出登录逻辑

[JPUSHService setAlias:@"" callbackSelector:nil object:nil];


关闭和打开推送

前面对极光推送在项目中的集成进行了说明,下面我们就要看一下相关的关闭和打开推送,很多app的设置中心都有打开和关闭推送。

首先我们得定义一个属性作为开关的标志位。

@property (nonatomic, assign) BOOL isOn;

在视图将要显示的时候,获取系统中推送的状态,并给isOn属性赋值,初始化,方便获取开关的状态。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    self.navigationController.navigationBarHidden = YES;
    
    UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
    if (UIUserNotificationTypeNone == setting.types) {
        self.isOn = NO;
    }
    else {
        self.isOn = YES;
    }
}

接着就是在代理方法中- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath中,响应点击方法,去设置中心关闭或者打开推送。

//响应开关的点击方法
 case 1:
            {
                //打开消息推送
                NSLog(@"消息推送");
                
                if (!self.isOn) {
                    //打开消息推送
                    [self showAlertViewWithMessage:@"确定要开启推送消息?"];
                }
                else {
                    //关闭消息推送
                    [self showAlertViewWithMessage:@"确定要关闭推送消息?"];
                }
            }

//是否开启推送的提示框

- (void)showAlertViewWithMessage:(NSString *)message
{
    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *ensureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        //去开启或者关闭推送状态
        [self changePushCondtion];
    }];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        //去开启或者关闭推送状态
        return;
    }];
    
    [alertVC addAction:ensureAction];
    [alertVC addAction:cancelAction];
    
    [self presentViewController:alertVC animated:YES completion:nil];
}

//去设置中心开启或者关闭极光状态

- (void)changePushCondtion
{
    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    [[UIApplication sharedApplication] openURL:url];
}

下面我们看实现效果。

推送开关
提示框
去个人中心设置
关闭推送状态
返回个人中心更新状态

后记

极光推送逻辑就这么些,希望可以帮助大家,有关极光集成方面的深层次挖掘和常见bug,我会继续和大家分享。

秦时明月
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容