點擊極光推送,實現跳轉,點擊極光推跳轉
說實話,極光推送接觸過好幾遍了,但是每次開發都是實現簡單的展示功能,最近接手的一款app要求只在後台展示,還要實現點擊通知欄跳轉到相應的詳情介面,於是便以為很簡單的開始了,而且還很嗨的那種,以為自己沒問題了(當時自己用的iOS10以上的iPhone)。但是最後測試階段,出現各種問題,各種調試都不行,簡單總結一下當時出現的問題(不過前提條件是已經按照極光官方文檔的要求整合好了,而且用極光的控制台發送訊息通知一切都正常)
1)不同系統的手機,app在後台通知的展示和點擊會走不同的代理方法
比如說iOS8系統下,展示通知和點擊通知都會走這個方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void
(^)(UIBackgroundFetchResult))completionHandler
又比如說iOS10系統下,展示通知居然會走上面的方法,還會在點擊通知的時候走下面這個方法
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
2)前台和後台,也會影響調用不同的代理方法
3)你以為這是最後一個問題,那你就錯了,這是都沒法繼續總結了,總之就是出現毫無規律可言的亂
相信看到這裡,很多人還是不理解,這裡盡量放心,是可以直接忽略跳過前面的。要想實現點擊極光推送去跳轉詳情,主要看下面的這張圖,重點來了!重點來了!重點來了!
上面這張圖是我問了極光的技術人員我的某一個問題之後給我的一個網頁連結裡面的,看到這我真的是悲喜交加,我瞬間精神了。當務之急是立馬聯絡我們項目的後台,確定是否給推送的加了content-available欄位,自己也列印日誌看了一番,果然,在極光的後台推送是沒有content-available欄位,但是我們的php後台給我們iOS這邊加上了這個欄位,後台也回複我他加了。在這裡告訴你,你千萬別信後台說什麼去不掉,改不了這個欄位的鬼話,在極光技術人員的協助下,我複製各種能解決的方法,甚至代碼範例給後台,最後終於還是給我解決了這個問題,終於能看見列印的日誌裡面沒有了content-available欄位,終於看到了曙光。不要以為這就結束了,你這就錯了,還有一個地方得注意,app這邊還得注意前後台,從上面的圖片也是可以看出來的,就是在下面的方法裡面得加一個前台的判斷,不在前台才去實行跳轉的邏輯。最後拿著iOS8,iOS9,iOS10,iOS11的手機各種測試,終於正常了,我只想說上面這個圖我太喜歡了!
下面我把項目裡面相關的極光源碼(包括整合)粘貼出來,小夥伴們可以隨意看看
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ......省略不寫 // Required 註冊通知 我們項目是只支援iOS7以上的裝置 #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1 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) { //categories [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil]; } else { //categories nil [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)#else //categories nil categories:nil]; [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)#endif // Required categories:nil]; } [JPUSHService setupWithOption:launchOptions appKey:@"482c5c296d169dcfbebec15b" channel:@"AppStore" apsForProduction:YES advertisingIdentifier:nil];//自訂訊息需要用到的// NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];// [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil]; //2.1.9版本新增擷取registration id block介面。 [JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) { if(resCode == 0){ NSLog(@"registrationID擷取成功:%@",registrationID); NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:registrationID forKey:JPushRegistrationID]; [defaults synchronize]; } else{ NSLog(@"registrationID擷取失敗,code:%d",resCode); } }]; ......省略不寫 }// 將極光推送得到的deviceToken傳給SDK- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ [JPUSHService registerDeviceToken:deviceToken];}- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Required NSLog(@"iOS6?????"); [JPUSHService handleRemoteNotification:userInfo];}- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfofetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // IOS 7 Support Required if (application.applicationState != UIApplicationStateActive) {//不在前台,必須判斷 [self didJpushJumpToDetail:userInfo]; } [JPUSHService handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData);}//IOS 10 點擊通知走這裡- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { NSLog(@"iOS10以後處理後台點擊訊息通知的代理方法"); // Required NSDictionary *userInfo = response.notification.request.content.userInfo; [self didJpushJumpToDetail:userInfo]; if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { [JPUSHService handleRemoteNotification:userInfo]; } completionHandler(); // 系統要求執行這個方法}//實現點擊通知跳轉到相應的詳情介面- (void)didJpushJumpToDetail:(NSDictionary *)userInfo { NSLog(@"userInfo = %@", userInfo); int t = [[userInfo objectForKey:@"type"] intValue]; if (t == 2) {// 1:即時問答 2:問題廣場 NSString *type= [NSString stringWithFormat:@"%d",t]; if ([userInfo objectForKey:@"qid"] && [userInfo objectForKey:@"waitType"]) {// && [userInfo objectForKey:@"rid"] NSString *qid = [NSString stringWithFormat:@"%d", [[userInfo objectForKey:@"qid"] intValue]]; NSString *rid = [NSString stringWithFormat:@"%d", [[userInfo objectForKey:@"rid"] intValue]]; NSString *waitType = [userInfo objectForKey:@"waitType"];//zhuiwen ques [[NSNotificationCenter defaultCenter]postNotificationName:@"notificationGotoVc" object:nil userInfo:@{@"t":type, @"qid":qid, @"waitType":waitType, @"rid":rid}]; } }else if(t == 1) { NSString *type= [NSString stringWithFormat:@"%d",t]; if ([userInfo objectForKey:@"qid"] && [userInfo objectForKey:@"uid"] && [userInfo objectForKey:@"qtype"]) { NSString *qid = [NSString stringWithFormat:@"%d",[[userInfo objectForKey:@"qid"] intValue]]; NSString *uid = [NSString stringWithFormat:@"%d",[[userInfo objectForKey:@"uid"] intValue]]; NSString *qtype = [NSString stringWithFormat:@"%d",[[userInfo objectForKey:@"qtype"] intValue]]; [[NSNotificationCenter defaultCenter]postNotificationName:@"notificationGotoVc" object:nil userInfo:@{@"t":type, @"qid":qid, @"uid":uid, @"qtype":qtype}]; } }}- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler { NSLog(@"iOS10新增:處理前台收到通知的代理方法"); // Required NSDictionary * userInfo = notification.request.content.userInfo; if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { [JPUSHService handleRemoteNotification:userInfo]; }else { //應用處於前台時的本地推送接受 }//注意:::注釋掉下面這行,則app在前台不會展示頂部通知,如果去掉注釋則是會在頂部展示通知的,根據項目需求而定,我們要求不展示// completionHandler(UNNotificationPresentationOptionAlert); // 需要執行這個方法,選擇是否提醒使用者,有Badge、Sound、Alert三種類型可以選擇設定}