騰訊云即時(shí)通訊離線消息集成總結(jié)

前言

最近公司的聊天消息增加一個(gè)離線消息推送的功能,之前因?yàn)榕牌诘膯?wèn)題态辛,只是簡(jiǎn)單的本地通知麸澜,在賬號(hào)離線的狀態(tài)下或者是沒(méi)有開(kāi)啟程序的時(shí)候都不會(huì)收到,所以新加了一下這個(gè)功能奏黑。在做這個(gè)功能的時(shí)候遇到一些小問(wèn)題炊邦,特別在這里分享一下,下面的內(nèi)容大部分都是對(duì)騰訊云通訊文檔的整理和分析熟史。

一馁害,集成步驟:

1,推送原理:

如想要接收APNs離線消息通知蹂匹,需要在騰訊云管理平臺(tái)提交Push證書(shū)碘菜,在客戶端每次登錄時(shí),獲取并通過(guò)API接口上報(bào)Token限寞。詳細(xì)推送原理可參閱:Apple Push Notification Service忍啸。(值得注意的是,推送功能只用于通知用戶履植,如果APP在前臺(tái)计雌,以app內(nèi)消息提示小紅點(diǎn)為主,不會(huì)跳消息提示玫霎,didReceiveRemoteNotification 獲取到的消息由于不可控凿滤,可以忽略。)

2庶近,證書(shū)申請(qǐng)流程

APNs 證書(shū)申請(qǐng)流程可參考文檔:Apple推送證書(shū)申請(qǐng)翁脆。(這里注意iOS10的推送的區(qū)別)。這里有一篇關(guān)于iOS10推送的介紹博客拦盹,可以看一下

3鹃祖,上傳證書(shū)到控制臺(tái)

完成APNs 證書(shū)申請(qǐng)以后,需要把生成的p12證書(shū)上傳到控制臺(tái):


上傳時(shí)有幾個(gè)注意點(diǎn):
1,上傳證書(shū)名最好使用全英文(尤其不能使用括號(hào)等特殊字符)
2,上傳證書(shū)生效時(shí)間為10分鐘左右
3,上傳證書(shū)需要設(shè)置密碼,無(wú)密碼收不到推送(這個(gè)很重要恬口,一定要設(shè)置證書(shū)密碼校读,雖然我也不知道為什么要這么做...)
4,注意生產(chǎn)環(huán)境的選擇,發(fā)布AppStore的證書(shū)需要設(shè)置為生產(chǎn)環(huán)境祖能,否則無(wú)法收到推送
5,上傳的p12證書(shū)必須是自己申請(qǐng)的真實(shí)有效的證書(shū)

4歉秫,客戶端實(shí)現(xiàn)APNs推送 (重點(diǎn)代碼演示)
4.1 步驟:

客戶端要實(shí)現(xiàn)接收APNs推送,需要實(shí)現(xiàn)4個(gè)部分:

向蘋果后臺(tái)請(qǐng)求DeviceToken养铸、
登錄SDK后上傳Token到騰訊云雁芙、
APP進(jìn)入后臺(tái)時(shí)上報(bào)切后臺(tái)事件、
APP進(jìn)入前臺(tái)時(shí)上報(bào)切前臺(tái)事件钞螟。

- (void)replyPushNotificationAuthorization:(UIApplication *)application{
    
    if (IOS10_OR_LATER) {
        //iOS 10 later
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        //必須寫代理兔甘,不然無(wú)法監(jiān)聽(tīng)通知的接收與點(diǎn)擊事件
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge  | UNAuthorizationOptionAlert | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!error && granted) {
                //用戶點(diǎn)擊允許
                NSLog(@"注冊(cè)成功");
            }else{
                //用戶點(diǎn)擊不允許
                NSLog(@"注冊(cè)失敗");
            }
        }];
        // 可以通過(guò) getNotificationSettingsWithCompletionHandler 獲取權(quán)限設(shè)置
        //之前注冊(cè)推送服務(wù),用戶點(diǎn)擊了同意還是不同意鳞滨,以及用戶之后又做了怎樣的更改我們都無(wú)從得知洞焙,現(xiàn)在 apple 開(kāi)放了這個(gè) API,我們可以直接獲取到用戶的設(shè)定信息了拯啦。注意UNNotificationSettings是只讀對(duì)象哦澡匪,不能直接修改!
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            NSLog(@"========%@",settings);
        }];
        
    }else if (IOS8_OR_LATER)
    {
        //iOS 8 - iOS 10系統(tǒng)
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound  categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    //注冊(cè)遠(yuǎn)端消息通知獲取device token
    [application registerForRemoteNotifications];
}

/**
 *  在AppDelegate的回調(diào)中會(huì)返回DeviceToken褒链,需要在登錄后上報(bào)給騰訊云后臺(tái)
/**

-(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    [[IMAPlatform sharedInstance] configOnAppRegistAPNSWithDeviceToken:deviceToken];
}

上傳Token到騰訊云請(qǐng)參考如下代碼唁情,填寫參數(shù)時(shí)busiId需要和控制臺(tái)分配的證書(shū)ID保持一致:

- (void)configOnAppRegistAPNSWithDeviceToken:(NSData *)deviceToken
{
    DebugLog(@"didRegisterForRemoteNotificationsWithDeviceToken:%ld", (unsigned long)deviceToken.length);
    NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
    [[TIMManager sharedInstance] log:TIM_LOG_INFO tag:@"SetToken" msg:[NSString stringWithFormat:@"My Token is :%@", token]];
    TIMTokenParam *param = [[TIMTokenParam alloc] init];

/* 用戶自己到蘋果注冊(cè)開(kāi)發(fā)者證書(shū),在開(kāi)發(fā)者賬號(hào)中下載并生成證書(shū)(p12文件)甫匹,將生成的p12文件傳到騰訊證書(shū)管理控制臺(tái)甸鸟,控制臺(tái)會(huì)自動(dòng)生成一個(gè)證書(shū)id,將證書(shū)id傳入一下busiId參數(shù)中赛惩。*/
#if kAppStoreVersion

// AppStore版本
#if DEBUG
    param.busiId = 2383;
#else
    param.busiId = 2382;
#endif

#else
    //企業(yè)證書(shū)id
    param.busiId = 2516;
#endif

    [param setToken:deviceToken];

//    [[TIMManager sharedInstance] setToken:param];
    [[TIMManager sharedInstance] setToken:param succ:^{

        NSLog(@"-----> 上傳token成功 ");
    } fail:^(int code, NSString *msg) {
        NSLog(@"-----> 上傳token失敗 ");
    }];
}

注意這里有個(gè)問(wèn)題:這個(gè)上傳token的步驟必須要在sdk登陸成功之后哀墓,才能進(jìn)行。所以我之前這個(gè)步驟都是寫在sdk登陸成功之后的回調(diào)中...

上報(bào)切后臺(tái)事件請(qǐng)參考如下代碼:(下面的這個(gè)接口成功喷兼,才能收到推送)

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    __block UIBackgroundTaskIdentifier bgTaskID;
    bgTaskID = [application beginBackgroundTaskWithExpirationHandler:^ {

        //不管有沒(méi)有完成,結(jié)束background_task任務(wù)
        [application endBackgroundTask: bgTaskID];
        bgTaskID = UIBackgroundTaskInvalid;
    }];

    [[IMAPlatform sharedInstance] configOnAppEnterBackground];
}

- (void)configOnAppEnterBackground
{
    NSUInteger unReadCount = [[IMAPlatform sharedInstance].conversationMgr unReadMessageCount];
    [UIApplication sharedApplication].applicationIconBadgeNumber = unReadCount;

    TIMBackgroundParam  *param = [[TIMBackgroundParam alloc] init];
    [param setC2cUnread:(int)unReadCount];

    [[TIMManager sharedInstance] doBackground:param succ:^() {
        DebugLog(@"doBackgroud Succ");
    } fail:^(int code, NSString * err) {
        DebugLog(@"Fail: %d->%@", code, err);
    }];
}

上報(bào)切前臺(tái)事件請(qǐng)參考如下代碼:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
   [[TIMManager sharedInstance] doForeground:^() {
           DebugLog(@"doForegroud Succ");
     } fail:^(int code, NSString * err) {
           DebugLog(@"Fail: %d->%@", code, err);
     }];
}
5后雷,推送格式
5.1 通用推送規(guī)則

對(duì)于單聊消息季惯,APNs推送規(guī)則為:

昵稱:內(nèi)容

其中昵稱是發(fā)送方用戶昵稱,如果未設(shè)置昵稱臀突,則只顯示內(nèi)容勉抓。
對(duì)于群聊消息,APNs 推送規(guī)則為:

名稱(群名):內(nèi)容

其中名稱為群名片或者發(fā)送者昵稱候学,優(yōu)先級(jí)為 群名片 > 群名藕筋。

5.2 不同類型消息推送規(guī)則

PNs 推送內(nèi)容部分為消息體中各個(gè)Elem內(nèi)容組合:

文本Elem:直接顯示內(nèi)容
語(yǔ)音Elem:顯示 [語(yǔ)音]
文件Elem:顯示 [文件]
圖片Elem:顯示 [圖片]
自定義Elem:顯示desc字段內(nèi)容
例如:
一條消息中包含 文本Elem和圖片Elem,文本內(nèi)容為Test梳码,最終顯示的內(nèi)容為: Test[圖片]
另外一條消息中內(nèi)容為空隐圾,則不進(jìn)行下發(fā)伍掀,例如如果消息中只有自定義Elem,并且desc為空暇藏,則不進(jìn)行下發(fā)蜜笤;

這里不用關(guān)心是否托管賬號(hào)還是獨(dú)立賬號(hào),只要設(shè)置了昵稱或者群名推送消息就會(huì)帶上盐碱。

5.3多APP支持

對(duì)于需要多APP互通的場(chǎng)景把兔,可在多個(gè)APP中寫同一個(gè)sdkappid,可實(shí)現(xiàn)消息互通瓮顽,由于多個(gè)APP推送證書(shū)不同县好,所以需要在控制臺(tái)上提交多個(gè)證書(shū),每個(gè)證書(shū)在IM通訊云上生成一個(gè)編號(hào)暖混,可參考 3.1 Token 上報(bào) 設(shè)置證書(shū)聘惦,并提供當(dāng)前證書(shū)的編號(hào)。

6, 推送聲音
6.1 設(shè)置自己的推送聲音

不同用戶可能想使用不通的推送聲音儒恋,sdk提供了設(shè)置用戶聲音的接口善绎,可實(shí)現(xiàn)單聊聲音、群組聲音诫尽、音視頻(暫不支持)聲音的設(shè)置禀酱,也可在用戶級(jí)別設(shè)置是否接收推送。

 *  APNs 配置
 */
@interface TIMAPNSConfig : NSObject
/**
 *  是否開(kāi)啟推送:0-不進(jìn)行設(shè)置 1-開(kāi)啟推送 2-關(guān)閉推送
 */
@property(nonatomic,assign) uint32_t openPush;
/**
 *  C2C消息聲音,不設(shè)置傳入nil
 */
@property(nonatomic,retain) NSString * c2cSound;

/**
 *  Group消息聲音,不設(shè)置傳入nil
 */
@property(nonatomic,retain) NSString * groupSound;

/**
 *  Video聲音,不設(shè)置傳入nil
 */
@property(nonatomic,retain) NSString * videoSound;

@end

@interface TIMManager : NSObject

/**
 *  設(shè)置APNS配置
 *
 *  @param config APNS配置
 *  @param succ   成功回調(diào)
 *  @param fail   失敗回調(diào)
 *
 *  @return 0 成功
 */
-(int) setAPNS:(TIMAPNSConfig*)config succ:(TIMSucc)succ fail:(TIMFail)fail;

@end

參數(shù)說(shuō)明:

參數(shù) 說(shuō)明
config 設(shè)置配置
openPush : 是否開(kāi)啟推送 0-不進(jìn)行設(shè)置 1-開(kāi)啟推送 2-關(guān)閉推送
c2cSound : 單聊聲音牧嫉,文件名
groupSound : 群組聲音剂跟,文件名
videoSound : 音視頻邀請(qǐng)聲音,文件名
succ 成功回調(diào)
fail 失敗回調(diào)

6.2 獲取自己的推送聲音

界面展示如果需要獲取推送聲音酣藻,可使用 getAPNSConfig 獲取曹洽,此接口每次都從服務(wù)器同步數(shù)據(jù),不會(huì)進(jìn)行本地緩存辽剧。

@interface TIMManager : NSObject

/**
 *  獲取APNS配置
 *
 *  @param succ 成功回調(diào)送淆,返回配置信息
 *  @param fail 失敗回調(diào)
 *
 *  @return 0 成功
 */
-(int) getAPNSConfig:(TIMAPNSConfigSucc)succ fail:(TIMFail)fail;

@end

參數(shù)說(shuō)明:

參數(shù) 說(shuō)明
succ 成功回調(diào),返回 TIMAPNSConfig 結(jié)構(gòu)體
fail 失敗回調(diào)

6.3 每條離線推送屬性

如果需要定制每條消息的展示文本怕轿、擴(kuò)展字段偷崩、提示音、是否推送屬性撞羽,可以在消息設(shè)置TIMOfflinePushInfo阐斜,此條消息在推送時(shí),會(huì)替換用戶原有的默認(rèn)屬性诀紊≮顺觯可實(shí)現(xiàn)每條消息定制化推送。填入kIOSOfflinePushNoSound到sound屬性時(shí)接收端強(qiáng)制為靜音提示

/**
 填入sound字段表示接收時(shí)不會(huì)播放聲音
 */
extern NSString * const kIOSOfflinePushNoSound;

@interface TIMAndroidOfflinePushConfig : NSObject
/**
 *  離線推送時(shí)展示標(biāo)簽
 */
@property(nonatomic,retain) NSString * title;
/**
 *  Android離線Push時(shí)聲音字段信息
 */
@property(nonatomic,retain) NSString * sound;
/**
 *  離線推送時(shí)通知形式
 */
@property(nonatomic,assign) TIMAndroidOfflinePushNotifyMode notifyMode;

@end

@interface TIMIOSOfflinePushConfig : NSObject
/**
 *  離線Push時(shí)聲音字段信息
 */
@property(nonatomic,retain) NSString * sound;
/**
 *  忽略badge計(jì)數(shù)
 */
@property(nonatomic,assign) BOOL ignoreBadge;
@end

@interface TIMOfflinePushInfo : NSObject
/**
 *  自定義消息描述信息狼牺,做離線Push時(shí)文本展示
 */
@property(nonatomic,retain) NSString * desc;
/**
 *  離線Push時(shí)擴(kuò)展字段信息
 */
@property(nonatomic,retain) NSString * ext;
/**
 *  推送規(guī)則標(biāo)志
 */
@property(nonatomic,assign) TIMOfflinePushFlag pushFlag;
/**
 *  iOS離線推送配置
 */
@property(nonatomic,retain) TIMIOSOfflinePushConfig * iosConfig;
/**
  Android離線推送配置
 */
@property(nonatomic,retain) TIMAndroidOfflinePushConfig * androidConfig;
@end

上面的配置一定要在每條發(fā)送的message中配置一下断盛,要不然是不會(huì)接收到推送消息的。(就是因?yàn)楣δ苁窍茸龅慕穸梗扑褪呛蠹拥睦虿猓鞍姹镜膕dk相關(guān)的字段廢棄了颜骤,所以沒(méi)有配置,卡在了這里很多時(shí)間捣卤,確實(shí)需要檢討一下)

好了忍抽,差不多就是這么多了。本人的簡(jiǎn)書(shū)博客大部分都是項(xiàng)目中的遇到的自己遇到的一些問(wèn)題董朝,或者是自己無(wú)聊寫的一些小東西鸠项,沒(méi)有什么特別厲害的東西。把博客當(dāng)做是日記一樣寫出來(lái)子姜,主要是為了提高一下自己語(yǔ)言組織能力和問(wèn)題記錄的目的祟绊。。哥捕。牧抽。

大家加油!RWQ锸妗!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凫佛,一起剝皮案震驚了整個(gè)濱河市讲坎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌愧薛,老刑警劉巖晨炕,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異毫炉,居然都是意外死亡瓮栗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門碘箍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)遵馆,“玉大人,你說(shuō)我怎么就攤上這事丰榴。” “怎么了秆撮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵四濒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)盗蟆,這世上最難降的妖魔是什么戈二? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮喳资,結(jié)果婚禮上觉吭,老公的妹妹穿的比我還像新娘。我一直安慰自己仆邓,他們只是感情好鲜滩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著节值,像睡著了一般徙硅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搞疗,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天嗓蘑,我揣著相機(jī)與錄音,去河邊找鬼匿乃。 笑死桩皿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幢炸。 我是一名探鬼主播泄隔,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼阳懂!你這毒婦竟也來(lái)了梅尤?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤岩调,失蹤者是張志新(化名)和其女友劉穎巷燥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體号枕,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缰揪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葱淳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钝腺。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赞厕,靈堂內(nèi)的尸體忽然破棺而出艳狐,到底是詐尸還是另有隱情,我是刑警寧澤皿桑,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布毫目,位于F島的核電站蔬啡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏镀虐。R本人自食惡果不足惜箱蟆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刮便。 院中可真熱鬧空猜,春花似錦、人聲如沸恨旱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)窖杀。三九已至漓摩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間入客,已是汗流浹背管毙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桌硫,地道東北人夭咬。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像铆隘,于是被迫代替她去往敵國(guó)和親卓舵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 點(diǎn)擊查看原文 Web SDK 開(kāi)發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,761評(píng)論 0 15
  • 不同版本極光推送SDK集成各有差異膀钠,集成時(shí)一定要注意版本號(hào)掏湾,樓主已將博文更新成最新的SDK JPush v3.0....
    i順頌時(shí)宜閱讀 7,862評(píng)論 37 170
  • 1)項(xiàng)目里面不需要環(huán)信SDK的太多功能,只是想要聊天和好友功能肿嘲,其他都不用融击,那SDK一定要總是跟著更新么? a.環(huán)...
    DefaultYuan閱讀 26,558評(píng)論 17 59
  • 極光推送: 1.JPush當(dāng)前版本是1.8.2雳窟,其SDK的開(kāi)發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋果官方的步伐尊浪,SD...
    Isspace閱讀 6,719評(píng)論 10 16
  • ** Tips:** 不同版本極光推送SDK集成各有差異,各位童鞋在集成時(shí)一定要注意版本號(hào)封救,本人集成的是基于 極光...
    anyurchao閱讀 2,418評(píng)論 3 26