這篇文章我同事總結(jié)的, 感謝茗莢小草, 以下為原文.
- 參考了: iOS推送小結(jié)
- 本文內(nèi)容包含:
iOS 7 - 基本的通知推送
iOS 8 - 通知+自定義button
iOS 9 - 通知+自定義button+快捷回復(fù)
使用Houston在本地調(diào)試遠(yuǎn)程通知
安裝houston
gem install houston
安裝完之后
apn push "<19904e80 0ab7f3e7 bc59ba36 3fda26f3 f4c69568 81cecc7f 4c675143 ba6fc83d>" -c /Users/bjhl/Desktop/apppush_for_CRM/apple_push_notification.pem -m "hello" -b "15" -d key=CRM -y actionCategory
-c 指定.pem文件的地址蛤织,-m 通知的文本內(nèi)容 夭拌,-b 角標(biāo)的數(shù)量台汇, -y category的標(biāo)識(shí)符
要發(fā)送靜默通知即纲,.pem 文件之后,只添加-n 即可谭网。-n 代表content-availabel
"<>"中的string為deviceToken汪厨。
在使用之前首先需要準(zhǔn)備好pem證書(shū)文件
- pem文件由鑰匙串中的Push Services證書(shū)和它的私鑰文件導(dǎo)出的p12文件轉(zhuǎn)化的來(lái)的。
- 在鑰匙串中同時(shí)選中Push Services證書(shū)和它的私鑰文件蜻底,右鍵導(dǎo)出為cert.p12文件骄崩,
- 使用下面的命令,將p12文件轉(zhuǎn)化為applepushnotification.pem文件
openssl pkcs12 -in cert.p12 -out applepushnotification.pem -nodes -clcerts
- 有了pem文件就可以開(kāi)始在終端測(cè)試遠(yuǎn)程通知了薄辅,pem文件在鏈接APNS時(shí)需要使用要拂。
Push Services證書(shū)
- 首先需要生成一個(gè)certSigningRequest(CSR)文件
- 打開(kāi)應(yīng)用程序中的“鑰匙串訪問(wèn)”軟件,從菜單中選擇 “鑰匙串訪問(wèn)”-》“證書(shū)助理”-》“從證書(shū)頒發(fā)機(jī)構(gòu)請(qǐng)求證書(shū)”站楚,郵箱和名稱(chēng)填寫(xiě)脱惰,然后選擇保存到磁盤(pán),就可以在本地生成一個(gè)CertificateSigningRequest.certSigningRequest文件.
- developer.apple.com窿春,在App IDs列表找到CRM的拉一,進(jìn)入編輯,勾選Push Notifications旧乞。打開(kāi)推送服務(wù)蔚润。
- 生成推送證書(shū).cer文件。用于生產(chǎn)服務(wù)端需要的文件.pem尺栖。
- 勾選Push Notification之后嫡纠,出現(xiàn)一個(gè)列表,用來(lái)Manage and generate your certificates below延赌。對(duì)應(yīng)著生成Development SSL Certificate和Production SSL Certificate除盏。選擇Development SSL Certificate的create Certificate。
- 首先會(huì)提示你需要一個(gè)CSR文件挫以。就是第一步中使用鑰匙串生成的文件者蠕,上傳,continue掐松,continue踱侣,就可以下載一個(gè)aps_development.cer文件。保存到本地
- 雙擊該文件大磺,鑰匙串中就會(huì)出現(xiàn)一個(gè)Apple Development IOS push services證書(shū)泻仙。
- 之后就可以進(jìn)行準(zhǔn)備pem文件操作了。
上述準(zhǔn)備工作做好之后量没,xcode運(yùn)行
通過(guò)didRegisterForRemoteNotificationsWithDeviceToken 獲取deviceToken
- 可能出現(xiàn)didFailToRegisterForRemoteNotificationsWithError: error = Code=3000 "未找到應(yīng)用程序的“aps-environment”的授權(quán)字符串" ;
- 需要檢查xcode 的TARGETS-capabilities 打開(kāi)Push Notifications開(kāi)關(guān)玉转。
- 打開(kāi)Push Notifications開(kāi)關(guān)
app處理接收到的通知
根據(jù)收到通知時(shí),app的不同狀態(tài)殴蹄,app的處理方式不同
- app不在運(yùn)行狀態(tài)究抓。推送通知顯示猾担,當(dāng)用戶(hù)點(diǎn)擊通知,app的
- application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
方法會(huì)被調(diào)用刺下,通知內(nèi)容通過(guò)launchOptions參數(shù)的形式被傳遞并處理 - app運(yùn)行在前臺(tái)绑嘹。推送通知不會(huì)被顯示,app收到通知后會(huì)立即調(diào)用方法
-application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
- app在運(yùn)行狀態(tài)橘茉,且不在前臺(tái)工腋,用戶(hù)點(diǎn)擊通知,app進(jìn)入前臺(tái)畅卓,調(diào)起方法
- application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
image
iOS7中通知的代理方法
- application:didReceiveLocalNotification:(iOS 4.0–10.0Deprecated)
- application:didReceiveRemoteNotification:(app在前臺(tái)時(shí)才會(huì)調(diào)用, iOS 3.0–10.0Deprecated)
- application:didReceiveRemoteNotification:fetchCompletionHandler:(當(dāng)收到遠(yuǎn)程推送擅腰,該方法會(huì)被調(diào)用,iOS 7.0+)
iOS8中推送代理方法只有兩個(gè):
- application:handleActionWithIdentifier:forRemoteNotification:completionHandler:(iOS 8.0–10.0Deprecated)
- application:handleActionWithIdentifier:forLocalNotification:completionHandler:(iOS 8.0–10.0Deprecated)
iOS8中方法中的idenfier參數(shù)就對(duì)應(yīng)著不同的action的唯一標(biāo)識(shí),用戶(hù)點(diǎn)擊通知上任何一個(gè)自定義的action之后翁潘,都會(huì)調(diào)用此方法
iOS 10中推送:
UNUserNotificationCenterDelegate
可交互的通知
iOS8擁有了全新的通知中心趁冈,有全新的通知機(jī)制。當(dāng)屏幕頂部收到推送時(shí)只需要往下拉拜马,就能看到快速操作界面渗勘,并不需要進(jìn)入該應(yīng)用才能操作。在鎖屏界面俩莽,對(duì)于推送項(xiàng)目也可以快速處理旺坠。基本上就是讓用戶(hù)盡量在不離開(kāi)當(dāng)前頁(yè)面的前提下處理推送信息扮超,再次提高處理效率取刃。
app不在前臺(tái)時(shí),出現(xiàn)推送通知瞒津,下拉或者3D touch 該通知都可以出現(xiàn)自定義的操作蝉衣。
一般的遠(yuǎn)程推送消息 payload最大為2kb括尸,256字節(jié)巷蚪,超過(guò)該限制,APNS拒絕轉(zhuǎn)發(fā)濒翻。
payload實(shí)際是一個(gè)JSON字典
- payload中主要的aps字典部分能做到
- 展示一個(gè)通知消息給用戶(hù)
- 展示app的角標(biāo)屁柏,
- 播放一段聲音
- 靜默通知, 比如悄悄升級(jí)
- 需要content-availabel=1,不能包括alert,sound,badge
- 調(diào)起方法application:didReceiveRemoteNotification:fetchCompletionHandler:
- 需要檢查xcode 的targets->capabilities,勾選Background Modes中的Remote notifications
- aps數(shù)據(jù)部分的key:value,(其中的key是有apple定義的)
- alert:內(nèi)容可以使簡(jiǎn)單的string有送,也可以是Dictionary
- badge:app的角標(biāo)
- sound:聲音文件的名字string淌喻,然后在app的bundle中去尋找
- content-availabel:數(shù)字,為1表示靜默通知
- category:string,根據(jù)字符串去app中匹配自定義的一組action
初始化
要使用自定義的action雀摘,需要先判斷當(dāng)前系統(tǒng)為8.0+裸删,再使用UIUserNotificationSettings,UIMutableUserNotificationCategory阵赠,UIMutableUserNotificationAction涯塔,自定義通知的操作肌稻。
- 初始化多個(gè)action
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
//UIUserNotificationActivationModeBackground 不會(huì)調(diào)起app到前臺(tái),在后臺(tái)處理
//UIUserNotificationActivationModeForeground 點(diǎn)擊該按鈕時(shí)啟動(dòng)app到前臺(tái),且當(dāng)前模式下setAuthenticationRequired默認(rèn)為YES匕荸,
[action1 setActivationMode:UIUserNotificationActivationModeBackground];
[action1 setTitle:@"Background"];//展示在通知上的title
[action1 setIdentifier:@"action1"];//action的唯一標(biāo)識(shí)
[action1 setDestructive:YES];//當(dāng)前操作按鈕為紅色
[action1 setAuthenticationRequired:YES];//需要解鎖與否
……
action2, action3, action4, action5, action6, action7
- 使用一組action初始化UIMutableUserNotificationCategory
UIMutableUserNotificationCategory *actionCategory = [[UIMutableUserNotificationCategory alloc] init];
[actionCategory setIdentifier:@"actionCategory"];//這組動(dòng)作的標(biāo)識(shí)爹谭,同后臺(tái)約定
[actionCategory setActions:@[action1, action2, action3, action4, action5, action6, action7] forContext:UIUserNotificationActionContextDefault];
//使用UIUserNotificationActionContextDefault沒(méi)有action數(shù)目限制,但是action過(guò)多屏幕太短也無(wú)力……榛搔,UIUserNotificationActionContextMinimal不展示action
- 使用category初始化UIUserNotificationSettings ,注冊(cè)遠(yuǎn)程通知
NSSet *category = [NSSet setWithObject:actionCategory];
UIUserNotificationType types = (UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:category];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
iOS8以下的系統(tǒng)诺凡,注冊(cè)遠(yuǎn)程通知:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
- 遠(yuǎn)程通知的處理
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"application:didReceiveRemoteNotification:fetchCompletionHandler");
//TODO:對(duì)遠(yuǎn)程通知的處理
if(completionHandler) {
completionHandler(UIBackgroundFetchResultNoData);
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
NSLog(@"handleActionWithIdentifier:forRemoteNotification");
//TODO:對(duì)遠(yuǎn)程通知的處理,用戶(hù)tap了identifier匹配的action之后的操作
if(completionHandler) {
completionHandler();
}
}
通知中心的快速回復(fù) iOS 9.0–10.0Deprecated
以上為點(diǎn)擊通知的按鈕践惑,進(jìn)行操作腹泌,iOS9增加了一個(gè)供用戶(hù)快速回復(fù)的Category類(lèi)型
UIUserNotificationActionBehaviorTextInput(iOS 9.0–10.0Deprecated)
- 快捷輸入action的初始化
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {
//iOS 支持在通知中心快速回復(fù)輸入文字
UIMutableUserNotificationAction *inputAction = [[UIMutableUserNotificationAction alloc] init];
inputAction.behavior = UIUserNotificationActionBehaviorTextInput;
inputAction.activationMode = UIUserNotificationActivationModeBackground;
[inputAction setTitle:@"inputAction"];
[inputAction setIdentifier:@"inputAction"];
[inputAction setDestructive:NO];
//設(shè)置發(fā)送鍵的title
inputAction.parameters = @{UIUserNotificationTextInputActionButtonTitleKey:@"哇塞"};
}
- 對(duì)于快捷輸入的action,需要使用
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler;
方法中的responseInfo中的UIUserNotificationActionResponseTypedTextKey
對(duì)應(yīng)的value
來(lái)獲取輸入的文字童本。