極光推送點(diǎn)擊消息欄跳轉(zhuǎn)到指定頁(yè)面、設(shè)置標(biāo)簽或別名

上周,完成app新版本的開發(fā)。自從進(jìn)入這版app的開發(fā)就沒(méi)來(lái)更新過(guò)文章了,接下來(lái)會(huì)陸陸續(xù)續(xù)寫一下在這過(guò)程中遇到的問(wèn)題及一些總結(jié)。今天,就先說(shuō)說(shuō)消息推送吧。

推送,大家都不陌生,沒(méi)有推送功能的app估計(jì)是少數(shù)。當(dāng)然,對(duì)于推送介紹的文章也非常多也很仔細(xì),但是真正開發(fā)過(guò)程中,還是會(huì)遇到各種問(wèn)題,接下來(lái)會(huì)和大家談?wù)劶赏扑偷姆椒拔以陂_發(fā)中遇到的問(wèn)題,但愿能給你們開發(fā)中遇到類似的問(wèn)題時(shí)提供一種思路。

在推送過(guò)程我遇到的問(wèn)題主要有:
1.在點(diǎn)擊消息欄進(jìn)入指定頁(yè)面后,頁(yè)面的點(diǎn)擊事件不響應(yīng)
2.點(diǎn)擊消息欄進(jìn)入指定頁(yè)面后,頁(yè)面的導(dǎo)航欄問(wèn)題

其實(shí)這兩個(gè)問(wèn)題,歸根結(jié)底是因?yàn)樘D(zhuǎn)時(shí)選擇的控制器不對(duì)。比如當(dāng)我點(diǎn)擊消息欄時(shí),希望跳轉(zhuǎn)到A頁(yè)面,A中沒(méi)有導(dǎo)航欄。我開始用的是[self.window.rootViewController presentViewController:A animated:YES completion:nil],這時(shí)候跳轉(zhuǎn)到A頁(yè)面后,A頁(yè)面中控件的點(diǎn)擊事件不起作用了,后面發(fā)現(xiàn),是因?yàn)閷蛹?jí)圖不對(duì)。而且用present的話,沒(méi)有導(dǎo)航欄,所以當(dāng)你跳轉(zhuǎn)到指定頁(yè)面A時(shí),如果A頁(yè)面的點(diǎn)擊事件還有跳轉(zhuǎn)到新頁(yè)面B的功能,那么這個(gè)當(dāng)你通過(guò)A push出來(lái)的B頁(yè)面是沒(méi)有導(dǎo)航欄的,而實(shí)際上我們希望的B是有導(dǎo)航欄的。

最后換成了pushViewController的方法。這個(gè)方法的關(guān)鍵是,你得找到當(dāng)前的的VC,比如A頁(yè)面是通過(guò)tabbar的第一個(gè)item中的VC的navpush出來(lái)的,那么這時(shí)候,只要找到tabbar第一個(gè)Item對(duì)應(yīng)的nav中VC,然后用這個(gè)VC的 nav
push出A頁(yè)面,問(wèn)題就可以解決了。

接下來(lái),說(shuō)說(shuō)該如何集成極光推送、如何處理收到通知時(shí)的頁(yè)面跳轉(zhuǎn)問(wèn)題,以及如何設(shè)置標(biāo)簽和別名。

一、處理收到通知時(shí)頁(yè)面跳轉(zhuǎn)問(wèn)題。
1.你需要到極光推送的平臺(tái)上申請(qǐng)appkey,申請(qǐng)的過(guò)程中需要上傳開發(fā)環(huán)境和正式環(huán)境的消息推送證書,所以如果你的app還沒(méi)有消息推送證書,那么你需要到蘋果的開發(fā)者賬號(hào)中申請(qǐng)消息推送證書。如果對(duì)這個(gè)步驟不是很了解的話,可以參照iOS 證書 設(shè)置指南

2.申請(qǐng)好極光推送的appkey后,將下載的SDK拖到自己的工程中,添加相應(yīng)的framework,配置好相關(guān)信息。也可參照官方文檔
iOS SDK 集成指南

3.在 AppDelegate.m引入

#import "JPUSHService.h"
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif```
 
在` - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`中注冊(cè)極光推送
  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    [self initRootViewController];

if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
    //iOS10以上
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
}else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
    //iOS8以上可以添加自定義categories
    [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                      UIUserNotificationTypeSound |
                                                      UIUserNotificationTypeAlert)
                                          categories:nil];
}
else {
    //iOS8以下categories 必須為nil
    [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                      UIRemoteNotificationTypeSound |
                                                      UIRemoteNotificationTypeAlert)
                                          categories:nil];
}
BOOL isProduction = NO;// NO為開發(fā)環(huán)境,YES為生產(chǎn)環(huán)境

//Required(2.1.5版本的SDK新增的注冊(cè)方法,改成可上報(bào)IDFA,如果沒(méi)有使用IDFA直接傳nil
[JPUSHService setupWithOption:launchOptions appKey:@"你的極光推送appkey"
                      channel:nil
             apsForProduction:isProduction
        advertisingIdentifier:nil];

//2.1.9版本新增獲取registration id block接口。可以獲取registrationID
[JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
    if(resCode == 0){
        NSLog(@"registrationID獲取成功:%@",registrationID);
        
    }
    else{
        NSLog(@"registrationID獲取失敗,code:%d",resCode);
    }
}];


return YES;

}


注冊(cè)deviceToken

pragma mark--注冊(cè)devicetoken

  • (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    [JPUSHService registerDeviceToken:deviceToken];
    }

收到通知時(shí)的處理 ,這里需要注意一下,iOS10收到通知時(shí)的方法和iOS10以前的不一樣  
  • (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [JPUSHService handleRemoteNotification:userInfo];

    completionHandler(UIBackgroundFetchResultNewData);

    if (_application.applicationState == UIApplicationStateActive) {
    //程序運(yùn)行時(shí)收到通知,先彈出消息框

      [self getPushMessageAtStateActive:userInfo];
    

    }

    else{
    //程序已經(jīng)關(guān)閉或者在后臺(tái)運(yùn)行
    [self pushToViewControllerWhenClickPushMessageWith:userInfo];

    }

    [application setApplicationIconBadgeNumber:0];

    [JPUSHService handleRemoteNotification:userInfo];

    completionHandler(UIBackgroundFetchResultNewData);
    }

ifdef NSFoundationVersionNumber_iOS_9_x_Max

pragma mark- JPUSHRegisterDelegate

-(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)容


if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    [JPUSHService handleRemoteNotification:userInfo];
    
    
    if (_application.applicationState == UIApplicationStateActive) {
        //程序運(yùn)行時(shí)收到通知,先彈出消息框
      
        [self getPushMessageAtStateActive:userInfo];
        
    }

    else{
     
        [self pushToViewControllerWhenClickPushMessageWith:userInfo];
    }
    
}
// 需要執(zhí)行這個(gè)方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以設(shè)置
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);

}
//
-(void)jpushNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
[[NSUserDefaults standardUserDefaults] setObject:@"Inactive" forKey:@"applicationState"];

if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    [JPUSHService handleRemoteNotification:userInfo];
    
    
    if (_application.applicationState == UIApplicationStateActive) {
        //程序運(yùn)行時(shí)收到通知,先彈出消息框
        [self getPushMessageAtStateActive:userInfo];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationState" object:@"0"];
        
    }
    
    else{
        
        [self pushToViewControllerWhenClickPushMessageWith:userInfo];
    }
    
}
completionHandler();  // 系統(tǒng)要求執(zhí)行這個(gè)方法

}

endif

如果在程序運(yùn)行時(shí)收到通知,這時(shí)消息欄不會(huì)顯示通知,所以如果想讓用戶收到通知的話,應(yīng)該是給用戶一個(gè)彈框提醒,告訴用戶有消息通知,當(dāng)用戶點(diǎn)擊提示框中的確認(rèn)查看按鈕時(shí),跳轉(zhuǎn)到指定的頁(yè)面

pragma mark -- 程序運(yùn)行時(shí)收到通知

-(void)getPushMessageAtStateActive:(NSDictionary *)pushMessageDic{

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@""
                                                                             message:[[pushMessageDic objectForKey:@"aps"]objectForKey:@"alert"]
                                                                      preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"查看"
                                                          style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                                                              
                                                              [self pushToViewControllerWhenClickPushMessageWith:pushMessageDic];
                                                          }];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消"
                                                           style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                                                               
                                                           }];

    [alertController addAction:confirmAction];
    [alertController addAction:cancelAction];
    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];

}

跳轉(zhuǎn)到指定頁(yè)面的方法。跳轉(zhuǎn)到指定頁(yè)面的話,可能會(huì)需要某些參數(shù),這時(shí)可以根后臺(tái)商定,根據(jù)參數(shù)跳轉(zhuǎn)到相應(yīng)的頁(yè)面,同時(shí)也讓后臺(tái)把你需要的參數(shù)返回來(lái)。比如我和后臺(tái)商定根據(jù)“pageType”這個(gè)參數(shù)確定跳轉(zhuǎn)的頁(yè)面。如果是跳轉(zhuǎn)到次級(jí)頁(yè)面,這里重要的是要找到正確的viewcontroller,用controller的nav進(jìn)行push新頁(yè)面。比如我的DetailViewController是用tabar的第一個(gè)item中的FirstViewController的nav進(jìn)行push出來(lái)的,那么,當(dāng)我點(diǎn)擊通知消息想到跳轉(zhuǎn)到DetailViewController,只要找到FirstViewController就可以了。

-(void)pushToViewControllerWhenClickPushMessageWith:(NSDictionary*)msgDic{

NSUserDefaults*pushJudge = [NSUserDefaults standardUserDefaults];

        if ([[msgDic objectForKey:@"pageType"] integerValue]==0){

// 跳轉(zhuǎn)到第一個(gè)tabbarItem,這時(shí)直接設(shè)置 UITabBarController的selectedIndex屬性就可以

         self.tabController.selectedIndex = 0;
            
        }else if ([[msgDic objectForKey:@"pageType"] integerValue]==1){
            
            //跳轉(zhuǎn)到第二個(gè)tabbarItem
      
            self.tabController.selectedIndex = 1;
          
            
        }else if ([[msgDic objectForKey:@"pageType"] integerValue]==2){
            //跳轉(zhuǎn)到第三個(gè)tabbarItem
            

            self.tabController.selectedIndex = 2;
            
        }else if ([[msgDic objectForKey:@"pageType"] integerValue]==3){
            //詳情,這是從跳轉(zhuǎn)到第一個(gè)tabbarItem跳轉(zhuǎn)過(guò)去的,所以我們可以先讓tabController.selectedIndex =0;然后找到VC的nav。
            
            self.tabController.selectedIndex =0;
            DetailViewController * VC = [[DetailViewController alloc]init];
            [VC setHidesBottomBarWhenPushed:YES];
        //因?yàn)槲矣昧巳饺羵?cè)滑手勢(shì),所以要找的是第一個(gè)tabbarController中的viewController的JTNavigationController ,接著再找JTNavigationController 里面的jt_viewControllers.lastObject,這樣就可以找到FirstViewController了,然后跳轉(zhuǎn)的時(shí)候就和正常的跳轉(zhuǎn)一樣了
            JTNavigationController *nav=(JTNavigationController *)self.tabController.viewControllers[0];
            UIViewController *vc=(UIViewController*)nav.jt_viewControllers.lastObject;
            
            [vc.navigationController pushViewController:VC animated:NO];
            
        }else {

        }

}


二、如何設(shè)置標(biāo)簽或者別名
消息推送,有時(shí)候只想推送給指定的人或者指定的版本,那么這時(shí)候我們就需要對(duì)設(shè)備設(shè)置標(biāo)簽或者別名了,這樣推送的時(shí)候可以根據(jù)標(biāo)簽或者別名推送給指定的用戶

  • (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];

    //標(biāo)簽
    __autoreleasing NSMutableSet *tags = [NSMutableSet set];
    //設(shè)置了IOS_ALL的標(biāo)簽,當(dāng)推送時(shí)選了IOS_ALL這標(biāo)簽,那么只要裝了這個(gè)app并且允許消息推送的用戶就都能收到通知
    [self setTags:&tags addTag:@"IOS_ALL"];

    NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    //根據(jù)版本號(hào)設(shè)置了IOSXX的標(biāo)簽,當(dāng)推送時(shí)選了IOS2.1這標(biāo)簽,那么只要裝了這個(gè)app并且允許消息推送的2.1版本的用戶就都能收到通知

    [self setTags:&tags addTag:[NSString stringWithFormat:@"IOS%@",version]];

    if (_isLogin==YES) {
    //根據(jù)版本號(hào)設(shè)置了LoginUesr的標(biāo)簽,當(dāng)推送時(shí)選了LoginUesr這標(biāo)簽,那么只要裝了這個(gè)app并且允許消息推送的所有登錄用戶就都能收到通知
    [self setTags:&tags addTag:@"LoginUesr"];
    }else{

    }

    //別名,根據(jù)用戶的UID去設(shè)置別名,那么可以指定的推送給某些用戶
    __autoreleasing NSString *alias ;

    if (_userUID!= nil) {
    alias =[NSString stringWithFormat:@"%@",_userUID];

}
[self analyseInput:&alias tags:&tags];

[JPUSHService setTags:tags alias:alias callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];

}

  • (void)tagsAliasCallback:(int)iResCode
    tags:(NSSet *)tags
    alias:(NSString *)alias {
    NSString *callbackString =
    [NSString stringWithFormat:@"%d, \ntags: %@, \nalias: %@\n", iResCode,
    [self logSet:tags], alias];

    NSLog(@"TagsAlias回調(diào):%@", callbackString);
    }

  • (NSString *)logSet:(NSSet *)dic {
    if (![dic count]) {
    return nil;
    }
    NSString *tempStr1 =
    [[dic description] stringByReplacingOccurrencesOfString:@"\u"
    withString:@"\U"];
    NSString *tempStr2 =
    [tempStr1 stringByReplacingOccurrencesOfString:@""" withString:@"\""];
    NSString *tempStr3 =
    [[@""" stringByAppendingString:tempStr2] stringByAppendingString:@"""];
    NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding];
    NSString *str =
    [NSPropertyListSerialization propertyListFromData:tempData
    mutabilityOption:NSPropertyListImmutable
    format:NULL
    errorDescription:NULL];
    return str;
    }

pragma mark--設(shè)置推送的標(biāo)簽及別名

  • (void)setTags:(NSMutableSet **)tags addTag:(NSString *)tag {

    [*tags addObject:tag];
    }

  • (void)analyseInput:(NSString **)alias tags:(NSSet *)tags {
    // alias analyse
    if (![
    alias length]) {
    // ignore alias
    alias = nil;
    }
    // tags analyse
    if (![
    tags count]) {
    tags = nil;
    } else {
    __block int emptyStringCount = 0;
    [
    tags enumerateObjectsUsingBlock:^(NSString *tag, BOOL *stop) {
    if ([tag isEqualToString:@""]) {
    emptyStringCount++;
    } else {
    emptyStringCount = 0;
    stop = YES;
    }
    }];
    if (emptyStringCount == [
    tags count]) {
    *tags = nil;
    }
    }
    }

當(dāng)用戶退出登錄的時(shí)候可以重置別名,不然設(shè)備還是會(huì)收到通知

[JPUSHService setAlias:@"" callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];


以上就是對(duì)于極光推送的簡(jiǎn)單介紹,如有問(wèn)題歡迎指出或留言。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容