個推配置參考個推文檔 http://docs.getui.com/mobile/ios/overview/
個推官方技術(shù)人員說明:
iOS的消息是分兩部分的:一部分是走APNS的通知欄, 另一部分是走我們通道的透傳消息 ;這兩部分是服務(wù)端推送代碼里面你們的人員會設(shè)定好的奕筐,分別是兩個不同的方法 离赫,如果消息下發(fā)的時候芭逝,你客戶端是在后臺的(也就是客戶端是離線)那么會收到APNS的通知;透傳消息就進離線了渊胸,只有你下次在線的時候 (也就是下次應(yīng)用到前臺的時候)才會下發(fā)下來旬盯。 如果下發(fā)的時候應(yīng)用是在前臺的,那這樣的話客戶端就直接收到透傳消息了翎猛,APNS那部分消息就不會下發(fā)了胖翰。
app沒啟動,或者在后臺切厘,或者鎖屏萨咳,都是離線狀態(tài),你推送透傳時疫稿,首先走的是蘋果的apns通道培他,此時會收到apn通知,點開通知遗座,進入應(yīng)用舀凛,app就在線了,就會走個推通道途蒋,下發(fā)透傳消息
補充說明:
在個推后臺推送消息有任務(wù)中和任務(wù)停止操作的區(qū)別猛遍,如下圖:
圖片.png
根據(jù)上圖中的操作,測試結(jié)果如下:
在個推后臺推送消息,收到推送消息后續(xù)操作
- App在前臺時懊烤,走透傳消息
- App在后臺時梯醒,任務(wù)中,點AppIcon喚起App奸晴,走透傳消息
- App在后臺時冤馏,任務(wù)中,點推送消息喚起App寄啼,同時走透傳消息和APNS
- App在后臺時逮光,任務(wù)中,點通知欄消息喚起App墩划,同時走透傳消息和APNS
- App在后臺時涕刚,任務(wù)停止爱谁,點AppIcon喚起App蝌矛,收不到推送消息
- App在后臺時帆焕,任務(wù)停止卖毁,點擊推送消息喚起App,走APNS
- App在后臺時掠手,任務(wù)停止费坊,點擊通知欄消息喚起App事格,走APNS
- App未啟動時氢卡,任務(wù)中锈至,點擊AppIcon啟動App,走透傳消息
- App未啟動時译秦,任務(wù)中峡捡,點擊推送消息啟動App,同時走透傳消息和APNS
- App未啟動時筑悴,任務(wù)中们拙,點擊通知欄推送消息啟動App,同時走透傳消息和APNS
- App未啟動時阁吝,任務(wù)停止砚婆,點擊AppIcon啟動App,收不到推送消息
- App未啟動時突勇,任務(wù)停止装盯,點擊推送消息啟動App,走APNS
- App未啟動時与境,任務(wù)停止,點擊通知欄消息啟動App猖吴,走APNS
在服務(wù)端推送消息摔刁,收到推送消息后續(xù)操作(相當(dāng)于在個推后臺任務(wù)中操作)
- App在前臺時,走透傳消息
- App在后臺時海蔽,點擊AppIcon喚起App共屈,走透傳消息
- App在后臺時绑谣,點擊推送消息喚起App,同時走透傳消息和APNS
- App在后臺時拗引,點擊通知欄推送消息喚起App借宵,同時走透傳消息和APNS
- App未啟動時,點擊AppIcon啟動App矾削,走透傳消息
- App未啟動時壤玫,點擊推送消息啟動App,同時走透傳消息和APNS
- App未啟動時哼凯,點擊通知欄消息啟動App欲间,同時走透傳消息和APNS
iOS10以上用新API實現(xiàn)
1.注冊個推
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 個推
[GeTuiSdk startSdkWithAppId:GetuiAppId appKey:GetuiAppKey appSecret:GetuiAppSecret delegate:self];
// 注冊APNS
[self registerUserNotification];
// 是否允許SDK 后臺運行(這個一定要設(shè)置,否則后臺apns不會執(zhí)行)
[GeTuiSdk runBackgroundEnable:true];
return YES;
}
2.注冊用戶通知
/** 注冊用戶通知 */
- (void)registerUserNotification
{
/*
注冊通知(推送)
申請App需要接受來自服務(wù)商提供推送消息
*/
if (@available(iOS 10.0, *)) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
[self showNoticeAlert];
}
}];
// 注冊通知
[[UIApplication sharedApplication] registerForRemoteNotifications];
}else {
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
// 定義用戶通知類型(Remote.遠程 - Badge.標(biāo)記 Alert.提示 Sound.聲音)
UIUserNotificationType types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
// 定義用戶通知設(shè)置
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
// 注冊用戶通知 - 根據(jù)用戶通知設(shè)置
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
if ([[UIApplication sharedApplication] currentUserNotificationSettings].types == UIUserNotificationTypeNone) {
[self showNoticeAlert];
}
}
}
}
#pragma mark - iOS 10以下注冊通知
/** 已登記用戶通知 */
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
// 注冊遠程通知(推送)
[application registerForRemoteNotifications];
}
3.遠程通知(推送)回調(diào)
#pragma mark - 遠程通知(推送)回調(diào)
/** 遠程通知注冊成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// [3]:向個推服務(wù)器注冊deviceToken 為了方便開發(fā)者断部,建議使用新方法
[GeTuiSdk registerDeviceTokenData:deviceToken];
NSLog(@"\n>>>[DeviceToken(NSData)]: %@\n\n", deviceToken);
}
4.GeTuiSdkdelegate 注冊回調(diào)猎贴,獲取CID信息
#pragma mark - GeTuiSdkdelegate 注冊回調(diào),獲取CID信息
/** SDK啟動成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
//個推SDK已注冊蝴光,返回clientId
NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId);
}
/** SDK遇到錯誤回調(diào) */
- (void)GeTuiSdkDidOccurError:(NSError *)error {
//個推錯誤報告她渴,集成步驟發(fā)生的任何錯誤都在這里通知,如果集成后蔑祟,無法正常收到消息趁耗,查看這里的通知。
NSLog(@"\n>>>[GexinSdk error]:%@\n\n", [error localizedDescription]);
}
5.GeTuiSdkdelegate 透傳消息回調(diào)
/** SDK收到透傳消息回調(diào) */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
// [4]: 收到個推消息
NSString *payloadMsg = nil;
NSDictionary *payloadDict = nil;
if (payloadData) {
payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding];
NSData *data = [[NSData alloc] initWithData:[payloadMsg dataUsingEncoding:NSUTF8StringEncoding]];
payloadDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
}
if (payloadDict == nil) {
return;
}
//isAPNS 針對同時走APNS和透傳消息時在APNS代理方法中處理做瞪,透傳消息不做處理
if (self.isAPNS) {
self.isAPNS = NO;
return;
}
NSDictionary *userInfo = [payloadDict dictionaryValueForKey:@"message"];
NSString *string = [userInfo stringValueForKey:@"schema"];
NSString *title = [payloadDict stringValueForKey:@"title"];
NSString *message = [payloadDict stringValueForKey:@"content"];
NSString *type = [payloadDict stringValueForKey:@"type"];
// offLine 為YES時表示是離線消息
// 離線消息并且非營銷類的消息不做彈窗處理
// operation 營銷類push消息
if (offLine && ![type isEqualToString:@"operation"]) {
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (string.length == 0 || [string isEqualToString:StringToastNone]) {
[UIAlertController alertViewController:title message:message cancelActionTitle:@"我知道了" otherActionTitle:nil cancelBlock:nil otherBlock:nil];
}else {
[UIAlertController alertViewController:title message:message cancelActionTitle:@"取消" otherActionTitle:@"前往" cancelBlock:nil otherBlock:^(UIAlertAction *action) {
[HSQSchema openURLSpmExtern:string];
}];
}
});
}
4.APNS回調(diào)
#pragma mark - iOS 10以下處理
/** APP已經(jīng)接收到“遠程”通知(推送) - 透傳推送消息 */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
// 處理APN对粪,用來標(biāo)識同時走APNS和透傳消息時只處理APNS時
self.isAPNS = true;
// 跳轉(zhuǎn)處理
[self dealwithAPNSMessage:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
#pragma mark - UNUserNotificationCenterDelegate iOS 10以上(包括iOS 10)處理
//App在后臺運行及程序退出殺死 會調(diào)用的方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
// 處理APN,用來標(biāo)識同時走APNS和透傳消息時只處理APNS時
self.isAPNS = YES;
// 遠程推送消息
if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSDictionary *userInfo = response.notification.request.content.userInfo;
// 跳轉(zhuǎn)處理
[self dealwithAPNSMessage:userInfo];
}
completionHandler();
}