前言
最近工作中實(shí)現(xiàn)遠(yuǎn)程推送點(diǎn)擊狀態(tài)欄的提醒,直接進(jìn)入相應(yīng)地詳細(xì)界面的功能摆舟。遇到了問題,解決之后整理出來
第一步: 準(zhǔn)備階段
1. 配置遠(yuǎn)程推送證書
在蘋果開發(fā)者網(wǎng)站bundleId 賬號下,勾選遠(yuǎn)程推送恨诱。并配置遠(yuǎn)程推送證書
截屏2021-10-06 16.39.12.png
2. App工程支持遠(yuǎn)程推送
在 項(xiàng)目Targets->Siging&Capabilities 勾選遠(yuǎn)程推送媳瞪,如下圖所示
截屏2021-10-06 16.13.49.png
3.引入頭文件 :
在AppDelegate.h
文檔中引入頭文件 #import <UserNotifications/UserNotifications.h>
4.遵循協(xié)議代理 :
在AppDelegate.h
文檔中遵循協(xié)議代理 @interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
第二步: 申請權(quán)限,注冊通知
在 AppDelegate.m
中 的代理方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中照宝,添加如下代碼:
if ([OS_VERSON floatValue] >= 10.0) { //iOS 10 later
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) { //用戶點(diǎn)擊允許
dispatch_async(dispatch_get_main_queue(), ^{
[application registerForRemoteNotifications];
});
//[self submitRemotState:@"1"];
}else{ //用戶點(diǎn)擊不允許
//[self submitRemotState:@"0"];
}
}];
// 可以通過 getNotificationSettingsWithCompletionHandler 獲取權(quán)限設(shè)置
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
// NSLog(@"========%@",settings);
}];
}else if ([OS_VERSON floatValue] >= 8.0 &&[OS_VERSON floatValue] < 10.0 ){//iOS 8 - iOS 10系統(tǒng)
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
//注冊遠(yuǎn)端消息通知獲取device token
[application registerForRemoteNotifications];
}else{ //iOS 8.0系統(tǒng)以下
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
}
deviceToken 獲取 和處理
/// 此處需連外網(wǎng)才能觸發(fā)蛇受,觸發(fā)的時機(jī)是每次app啟動時
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
if (![deviceToken isKindOfClass:[NSData class]]) return;
NSString *string1;
//兼容 iOS13 和 xcode 10.2 發(fā)版時候,數(shù)據(jù)格式問題
//該方法可以兼容所有系統(tǒng)厕鹃,已測試12.0可獲取到正確的token值 2020年09月22日 王磊
const unsigned *tokenBytes = [deviceToken bytes];
string1 = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 令牌提交給后臺處理
dispatch_async(queue, ^{
/*
[ApplicationConfigServiceData appPushServer:@"" deviceToken:string1 success:^(id result) {
if ([OS_VERSON floatValue] <10.0) {//低系統(tǒng)手機(jī)需在這里獲取用戶是否授權(quán)狀態(tài)
[self isAgreeRemotion]? [self submitRemotState:@"1"] :[self submitRemotState:@"0"];
}
}];
*/
});
}
第三步: 遠(yuǎn)程推送各代理方法介紹
根據(jù)不同業(yè)務(wù)需求兢仰,處理不同代理方法
UIApplication有兩個關(guān)于接收到遠(yuǎn)程推送的代理:
/*
APP狀態(tài) 消息推送 用戶操作 是否觸發(fā)
Not Running 收到推送消息提示 點(diǎn)擊消息 觸發(fā) didReceiveNotificationResponse
Not Running 收到推送消息提示 點(diǎn)擊APP NO
Background 收到推送消息提示 點(diǎn)擊消息 觸發(fā) didReceiveNotificationResponse
Background 收到推送消息提示 點(diǎn)擊APP NO
Active 可自定義 無 觸發(fā)willPresentNotification
*/
#mark 在后臺接收到遠(yuǎn)程推送消息觸發(fā)(推送的消息數(shù)據(jù)格式必須要有"content-available":1,否則不觸發(fā))
/*
此方法還有一個觸發(fā)時機(jī)剂碴,是app在前臺把将,前提條件是必須有“content-available”:1。
此時忆矛,先觸發(fā)willPresentNotification代理方法察蹲,然后再觸發(fā)此fetchCompletionHandler代理方法
*/
1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
#mark 在前臺接受到遠(yuǎn)程推送消息觸發(fā)
/*
此回調(diào)方法觸發(fā)時機(jī):
1.app 在前臺運(yùn)行,接收到遠(yuǎn)程推送消息時催训,此時通知欄不會有消息提示洽议。可在此回調(diào)方法中定義提醒彈框漫拭。
2.每次app 從前臺通過home鍵進(jìn)入后臺時亚兄,會觸發(fā)此方法。
*/
2.- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
#mark 點(diǎn)擊通知欄消息觸發(fā)
3.- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler