iOS個推推送,推送跳轉(zhuǎn)及紅點角標

最近因為公司的業(yè)務需求,對推送做了相應的修改。因為之前用的是極光的推送,對于推送也沒有太多的要求,來消息就在通知欄展示,有角標展示即可。可是因為最近需求變更,對于推送需求也有了詳細的要求。這也讓我從新來review遍關(guān)于推送方面的知識。尤其是iOS10之后,推送的細分化,有了更多的認識。特在此做一個總結(jié)。
這里不再對原理進行闡述。
一、遠程推送
iphone在接受到遠端推送的通知,打開App后,程序會運行appDelegate的代理,這里分三種狀態(tài)
1.APP在未運行,已殺死進程的狀態(tài),遠程推送過來消息
2.APP在已運行,但APP未在前臺,就是在后臺,APP展示的不是此時的這個程序,這個時候,遠程推送過來消息
3.APP已運行,此時程序在前臺,就是我們正在玩我們的APP時,遠程推送過來消息
此時我們點擊通知欄消息后,在AppDelegate.m文件中相應的代理(代碼中對應的是個推的一些特殊跳轉(zhuǎn)處理):
1.1下面是對應1這種情況,app首次打開會進入這個方法:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //獲取 APNs(通知) 推送內(nèi)容(app未啟動時接受推送消息)
    //推送的信息會含在launchOption的字典內(nèi),取出后,分析其對應的key值
    NSDictionary *remoteDic = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
    if (remoteDic)
    {
       //這里因為個推平臺有一個所謂的透傳消息,從平臺推送過來和我們自己服務器搭建后臺推送的時候有所不同,所以做了處理,以防止后面做跳轉(zhuǎn)崩潰
        NSString *url = nil;
        if ([remoteDic objectForKey:@"payload"])
        {
            NSString *payloadStr = [remoteDic objectForKey:@"payload"];
            NSDictionary *payload = [NSString zhGetJSONSerializationObjectFormString:payloadStr];
            url = [payload objectForKey:@"url"];
        }
        else
        {
            url = [remoteDic objectForKey:@"url"];
        }
      //這里寫自己的跳轉(zhuǎn)
        [WYUserDefaultManager setDidFinishLaunchRemoteNoti:url];
    }
}

1.2這里對應2的情況,因為iOS10的原因所以,需要在兩個方法里都寫

//在iOS 10 以前,為處理 APNs 通知點擊事件,統(tǒng)計有效用戶點擊數(shù),需在AppDelegate.m里的didReceiveRemoteNotification回調(diào)方法中調(diào)用個推SDK統(tǒng)計接口
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // 將收到的APNs信息傳給個推統(tǒng)計
    [GeTuiSdk handleRemoteNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
    
    //推送后臺跳轉(zhuǎn)
    if (application.applicationState == UIApplicationStateActive) {
        NSLog(@"active");
        //程序當前正處于前臺
    }
    else if(application.applicationState == UIApplicationStateInactive)
    {
        [GeTuiSdk setBadge:0];
        NSLog(@"inactive");
        //程序處于后臺
        [self jumpPage:userInfo];
    }
}

//  iOS 10: 點擊通知進入App時觸發(fā),在該方法內(nèi)統(tǒng)計有效用戶點擊數(shù)
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    
    NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo);
    // [ GTSdk ]:將收到的APNs信息傳給個推統(tǒng)計
    [GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo];
    completionHandler();
    [GeTuiSdk setBadge:0];
    //iOS10以上,點擊通知欄推送跳轉(zhuǎn)
    NSDictionary *dic = response.notification.request.content.userInfo;
    [self jumpPage:dic];
}

1.3第三種情況,這里要說下關(guān)于個推的透傳功能,個推的透傳功能說是為了補充APN的不穩(wěn)定的。但是在使用中,個推其實推送的到達率也并不是100%,而因為早期對個推透傳功能的理解不太深入,尤其是在線和離線的消息推送,走了不少坑?,F(xiàn)在先說下在app開啟運行的時候,程序會運行下面這個代理

- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
    //收到個推消息
    NSString *payloadMsg = nil;
    if (payloadData) {
        payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding];
    }
    
    NSString *msg = [NSString stringWithFormat:@"taskId=%@,messageId:%@,payloadMsg:%@%@",taskId,msgId, payloadMsg,offLine ? @"<離線消息>" : @""];
    NSLog(@"\n>>>[GexinSdk ReceivePayload]:%@\n\n", msg);
    

    NSData *jsonData = [payloadMsg dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
    
    NSString *type = [[dic objectForKey:@"extra"] objectForKey:@"type"];
    //不是離線消息處理   
    if (!offLine)
    {
    }
}

上面是當app不在前臺的時候個推處于離線狀態(tài),app走APNS過來的。對于個推而言,當點擊推送的通知欄,打開app都會走上面的代碼,但由于app開啟后,個推平臺有可能未能連接,會出現(xiàn)推送不出來,或者有時候一下好多條。所以,我對個推這個離線的隊列感到不可信。所以,在離線的時候走APNS,因此這樣寫的推送相關(guān)的代碼。

二、紅點,角標,通知欄
對于個推,角標是由+ (void)setBadge:(NSUInteger)value這個方法來設置的,而這個角標就是在個推平臺計數(shù)的角標,所以當使用+1的時候,如果不把這個角標設置的話,角標都會+1的,所以當再次來推送的時候,會在原有的基礎上+1,不會從0開始計數(shù),所以,要在每個點擊通知欄后的代理方法里對個推的角標設置

[GeTuiSdk setBadge:0];

而如果想把app圖標角標清除,需要用

[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];

但是使用這個的話,通知欄也會完全清除掉。當然如果你需要清除所有通知欄,可以使用這個方法,但是我們要求的是要保留通知欄,可點擊app不是點擊通知欄的時候,角標清除。查看了許多網(wǎng)上的大家的處理方式,最后使用本地推送的折中方式來解決。
在app進入從后臺變?yōu)榍芭_的時候啟動一條本地推送,并設置角標為-1,緊接著馬上取消本地推送。

- (void)applicationDidBecomeActive:(UIApplication *)application {
    //設置推送紅點取消
    //1.設置本地推送
    UILocalNotification *localNote = [[UILocalNotification alloc] init];
    localNote.applicationIconBadgeNumber = -1;
    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
    [[UIApplication sharedApplication] cancelLocalNotification:localNote];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,765評論 25 709
  • 極光推送: 1.JPush當前版本是1.8.2,其SDK的開發(fā)除了正常的功能完善和擴展外也緊隨蘋果官方的步伐,SD...
    Isspace閱讀 6,873評論 10 16
  • 許多集成的步驟個推官網(wǎng)都有了,這里只寫關(guān)于推送的遠程推送和本地通知的步驟和代碼。APP在后臺時:走蘋果的APNS通...
    AllureJM閱讀 2,954評論 1 9
  • 最近一段時間工作量比較大, 抽不出時間來整理博客, 趁今天任務量較小的時候整理下關(guān)于環(huán)信推送的問題, 介紹. 集成...
    imGeek閱讀 2,834評論 1 3
  • 《一》 這世上最美的遇見 你的出現(xiàn),恰逢其時 《二》 喜歡晨光,也喜歡夕陽 喜歡你的明朗,也喜歡你的憂傷 《三》 ...
    小洋妮閱讀 315評論 0 0

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