首先痹仙,按照個(gè)推SDK集成指南配置好一個(gè)完整的工程是尔。或者直接下載現(xiàn)有工程(需要修改bundle identifier开仰、kGtAppId嗜历、kGtAppKey、kGtAppSecret)抖所。
** 如有錯(cuò)誤和待完善的地方梨州,還請指正。 **
新建推送:
本文將介紹對(duì)推送消息的兩種處理方式田轧。
在接收到推送消息時(shí)暴匠,分為3種情況,本文還將后兩者細(xì)分為兩種情況:
- APP處于前臺(tái)
1.1 APP接收到推送后推送后首先彈出一個(gè)Alert提示是否跳轉(zhuǎn)頁面 - APP處于后臺(tái)
2.1 點(diǎn)擊通知欄使APP進(jìn)入前臺(tái)后傻粘,直接跳轉(zhuǎn)頁面
2.2 點(diǎn)擊icon圖標(biāo)使APP進(jìn)入前臺(tái)后每窖,不作操作 - APP處于關(guān)閉狀態(tài)
3.1 點(diǎn)擊通知欄啟動(dòng)APP,直接跳轉(zhuǎn)頁面
3.2 點(diǎn)擊icon圖標(biāo)啟動(dòng)APP弦悉,不作操作
方式一:
首先為AppDelegate添加一個(gè)屬性窒典,
// 用來判斷是否是通過點(diǎn)擊通知欄開啟(喚醒)APP
@property (nonatomic) BOOL isLaunchedByNotification;
當(dāng)通過點(diǎn)擊通知欄來啟動(dòng)或喚醒APP時(shí),會(huì)調(diào)用didReceiveRemoteNotification:
方法稽莉,在該方法里將isLaunchedByNotification
的值置為YES:
/** APP已經(jīng)接收到“遠(yuǎn)程”通知(推送) - 透傳推送消息 */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
// 當(dāng)APP處于后臺(tái)或者關(guān)閉狀態(tài)瀑志,點(diǎn)擊通知欄就會(huì)先走這個(gè)方法,再使得個(gè)推SDK收到透傳消息回調(diào)
// 處理APNs代碼污秆,通過userInfo可以取到推送的信息(包括內(nèi)容劈猪,角標(biāo),自定義參數(shù)等)良拼。如果需要彈窗等其他操作战得,則需要自行編碼。
NSLog(@"\n>>>APP已經(jīng)接收到“遠(yuǎn)程”通知(推送)[Receive RemoteNotification - Background Fetch]:%@\n\n",userInfo);
completionHandler(UIBackgroundFetchResultNewData);
self.isLaunchedByNotification = YES;
}
然后會(huì)調(diào)用以下方法(當(dāng)APP處于前臺(tái)時(shí)會(huì)直接調(diào)用此方法)庸推,其中payloadData的值轉(zhuǎn)為NSString對(duì)象即為圖2中的消息內(nèi)容里的JSON數(shù)據(jù):
/** SDK收到透傳消息回調(diào) */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
// 收到個(gè)推消息
NSString *payloadMsg = nil;
if (payloadData) {
payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes
length:payloadData.length
encoding:NSUTF8StringEncoding];
}
// 當(dāng)app不在前臺(tái)時(shí)常侦,接收到的推送消息offLine值均為YES
// 判斷app是否是點(diǎn)擊通知欄消息進(jìn)行喚醒或開啟
// 如果是點(diǎn)擊icon圖標(biāo)使得app進(jìn)入前臺(tái)浇冰,則不做操作,并且同一條推送通知聋亡,此方法只執(zhí)行一次
if (offLine) {
// 離線消息湖饱,說明app接收推送時(shí)不在前臺(tái)
if (self.isLaunchedByNotification) {
// app是通過點(diǎn)擊通知欄進(jìn)入前臺(tái)
[[NSNotificationCenter defaultCenter] postNotificationName:kNOTIFICATION_PUSH object:nil userInfo:@{kNOTIFICATION_PUSH : payloadMsg}];
self.isLaunchedByNotification = NO;
} else {
// app是通過點(diǎn)擊icon進(jìn)入前臺(tái),在這里不做操作
}
} else if(!self.isLaunchedByNotification) {
// app已經(jīng)處于前臺(tái)杀捻,提示框提示
[[NSNotificationCenter defaultCenter] postNotificationName:kNOTIFICATION_ALERT object:nil userInfo:@{kNOTIFICATION_ALERT : payloadMsg}];
}elf.isLaunchedByNotification = NO;
}
}
2.2和3.2情況下的問題
這兩種情況下井厌,如果用戶不點(diǎn)擊通知欄而是點(diǎn)擊桌面icon圖標(biāo)啟動(dòng)或喚起APP,會(huì)直接調(diào)用GeTuiSdkDidReceivePayloadData:
方法致讥,根據(jù)本文的方式處理的話確實(shí)不會(huì)有任何操作仅仆,但是通知欄的消息仍然存在,如果再次點(diǎn)擊通知欄消息垢袱,仍會(huì)調(diào)動(dòng)didReceiveRemoteNotification:
方法墓拜,但是不會(huì)再調(diào)用GeTuiSdkDidReceivePayloadData:
方法,這樣的話isLaunchedByNotification
的值會(huì)被置為YES请契,而且無法再被置為NO咳榜。
解決辦法:在app進(jìn)入前臺(tái)后通過將Badge角標(biāo)置為0來移除通知欄信息,代碼如下:
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 這里的寫法是為了在app進(jìn)入前臺(tái)后爽锥,清除通知欄消息
NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
badge = badge == 1 ? 2 : 1;
// 這里經(jīng)過兩次賦值才可以移除通知欄消息
[UIApplication sharedApplication].applicationIconBadgeNumber = badge;
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
// // 下面這個(gè)方法只有Badge角標(biāo)不為0時(shí)才執(zhí)行涌韩,如果個(gè)推推送時(shí)Badge為0,那么不會(huì)走下面的方法
// if (badge) {
//
// badge = badge == 1 ? 2 : 1;
// [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
// [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
// }
}
方式二:
這種方式默認(rèn)在通過點(diǎn)擊icon使app進(jìn)入前臺(tái)時(shí)不做操作氯夷。
當(dāng)通過點(diǎn)擊通知欄來啟動(dòng)或喚醒APP時(shí)臣樱,會(huì)調(diào)用didReceiveRemoteNotification:
方法,接收到的推送內(nèi)容包含在userInfo
參數(shù)里腮考,可以在此方法里對(duì)推送消息進(jìn)行操作:
/** APP已經(jīng)接收到“遠(yuǎn)程”通知(推送) - 透傳推送消息 */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
// 當(dāng)APP處于后臺(tái)或者關(guān)閉狀態(tài)雇毫,點(diǎn)擊通知欄就會(huì)先走這個(gè)方法,再使得個(gè)推SDK收到透傳消息回調(diào)
// 處理APNs代碼踩蔚,通過userInfo可以取到推送的信息(包括內(nèi)容棚放,角標(biāo),自定義參數(shù)等)馅闽。如果需要彈窗等其他操作飘蚯,則需要自行編碼。
NSLog(@"\n>>>APP已經(jīng)接收到“遠(yuǎn)程”通知(推送)[Receive RemoteNotification - Background Fetch]:%@\n\n",userInfo);
completionHandler(UIBackgroundFetchResultNewData);
// app是通過點(diǎn)擊通知欄進(jìn)入前臺(tái)
[[NSNotificationCenter defaultCenter] postNotificationName:kNOTIFICATION_PUSH object:nil userInfo:@{kNOTIFICATION_PUSH : payloadMsg}];
}
同時(shí)捞蛋,由于系統(tǒng)方法調(diào)用完成后孝冒,個(gè)推仍會(huì)調(diào)用一次GeTuiSdkDidReceivePayloadData:
方法,需要在GeTuiSdkDidReceivePayloadData:
方法里判斷當(dāng)前消息是否為offLine離線消息拟杉,如果是離線消息則不做任何處理:
/** SDK收到透傳消息回調(diào) */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
// 收到個(gè)推消息
NSString *payloadMsg = nil;
if (payloadData) {
payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes
length:payloadData.length
encoding:NSUTF8StringEncoding];
}
// 當(dāng)app在前臺(tái)時(shí),接收到的推送消息offLine值均為NO
// 對(duì)于離線消息量承,這里不做操作
if (!offLine) {
// app已經(jīng)處于前臺(tái)搬设,提示框提示
[[NSNotificationCenter defaultCenter] postNotificationName:kNOTIFICATION_ALERT object:nil userInfo:@{kNOTIFICATION_ALERT : payloadMsg}];
}
}
對(duì)于角標(biāo)的處理可以參考方式一中的處理方法穴店。