遠程推送解決了當APP處於終止狀態,client與sever斷開時的通訊困境,APNS是蘋果所提供的一套服務。遠程推送要求設備必須保持聯網狀態,若設備處於斷網狀態,這APNS將爲其保留最後一條推送消息,若設備長時間處於斷網狀態,則將再也不爲其保留推送消息。後端
1、APNS的推送機制api
推送機制以下圖所示:服務器
Provider就是咱們本身程序的後臺服務器,APNS是Apple Push Notification Service的縮寫,也就是蘋果的推送服務器。app
上圖能夠分爲三個階段:
第一階段:應用程序的服務器端把要發送的消息、目的、iPhone的標識打包,發給APNS。
第二階段:APNS在自身的已註冊Push服務的iPhone列表中,查找有相應標識的iPhone,並把消息發送到iPhone。
第三階段:iPhone把發來的消息傳遞給相應的應用程序,而且按照設定彈出Push通知。iphone
APNS推送通知的詳細工做流程
下面這張圖是說明APNS推送通知的詳細工做流程:ide
根據圖片咱們能夠歸納一下:
一、應用程序註冊APNS消息推送。
二、iOS從APNS Server獲取devicetoken,應用程序接收device token。
三、應用程序將device token發送給程序的PUSH服務端程序。
四、服務端程序向APNS服務發送消息。
五、APNS服務將消息發送給iPhone應用程序。測試
準備工做
首先要有一臺蘋果的設備,模擬器是不支持推送的,因此你須要一臺iphone,ipod touch或者ipad。網站
咱們的客戶端與蘋果服務器之間和咱們本身的服務器與蘋果服務器之間都須要證書來進行連接。下面咱們來開始進入證書的製做過程。編碼
二.建立本地請求證書文件--CertificateSigningRequest(也就是CSR)spa
一、打開鑰匙串-證書助理-從證書頒發機構請求證書
二、填寫郵箱和名稱(無特殊要求可隨意填寫)-選擇存儲到磁盤
三、選擇繼續-保存至桌面,這時桌面上會有一個CertificateSigningRequest.certSigningRequest的請求文件,也就是咱們說的CSR文件。在咱們生成CSR文件的同時,會在鑰匙串訪問中生成一對祕鑰,名稱爲剛纔咱們填寫的經常使用名(此文件可長期重複使用,只做爲本機器的一個識別做用)
三.開發證書和發佈證書,進入蘋果開發者網站:https://developer.apple.com/
一、依次選擇Account(跳轉到登陸界面) -- Certificates, Identifiers &Profiles -- Certificates
二、選擇當前要設置通知的APP IDs(此處以新建一個APP IDs爲例),選擇上圖右上角"+"號建立一個APPID
三、填寫name以及Bundle ID(Bundle ID須要與Xcode裏項目Bundle ID一致)
四、勾選push notification 並完成提交
五、找到剛建立好的APP IDs,能夠看到下面的通知選項處提示(爲黃色)Configurable,表示證書還沒配置,點擊Edit進行編輯
六、這裏看到推送證書分爲2個版本,一個開發模式,一個生產模式,即咱們在開發測試時使用開發模式證書,發佈上線後採用生產模式證書,兩個都要建立(本次只做開發模式演示,固然建立生產版證書的步驟也是同樣的)
七、Choose File選擇最開始建立在桌面的Request文件(CSR文件)
八、建立證書OK後 下載到本地
九、開發版和生產版證書都建立好後,此時這裏已經都是啓用狀態了(爲綠色)
十、打開下載好的開發模式證書,能夠在鑰匙串中看到,右鍵將該證書導出成.p12格式文件
證書密碼可根據需求填寫(可爲空):
下面要輸入你電腦管理員密碼:
導出的.p12格式文件以下:
接下來終端進入該文件目錄下使用命令把此文件轉成pem格式(由於後端須要上傳pem格式文件驗證)
4、推送證書建立好了,接下來回到蘋果開發者官網,按如下步驟建立Provisioning Profile文件
一、選擇Provisioning Profile
二、選擇該項目APP ID
三、勾選測試受權的設備
四、注意右側的狀態要Active纔是可用的,如果invalid則須要Edit並從新下載一次
五、到此咱們開發模式所須要的證書和描述文件都建立好了
5、進入第三方推送後臺,登錄驗證開發者身份,並建立一個推送應用
一、選擇iOS,並上傳開發版證書(固然若是你同時也建立了生產版證書也能夠上傳驗證)
二、保存後,咱們要用到的即是右側的API KEY
6、項目裏配置第三方推送
一、下載最新的第三方推送SDK,導入到工程,SDK須要如下庫:Foundation.framework、CoreTelephony.framework、libz.dylib、SystemConfiguration.framework,請在工程中添加
二、再次強調要修改Bundle ID與以前建立證書時所填Bundle ID一致
三、在AppDelegate
中導入BPush.h
,並在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
方法中添加以下代碼,並修改apiKey爲剛纔建立應用所得apiKey,推送模式爲開發模式
四、添加3個方法
七.配置證書測試
一、雙擊以前建立好的的TestPush_ProvisioningDev.mobileprovision描述文件,並在Xcode-Targets配置好證書。這一步編譯的時候容易failed,一般檢查以前配置的provisioning文件狀態是否爲Active,若狀態爲Invalid,則需刪除本地provisioning文件,clean,再次從新下載配置
二、真機運行成功後,可看到控制端打印出得到到Device Token,以及APP提示時候開啓通知
8、建立通知測試
一、在第三方推送後臺建立一個通知測試,請選擇開發模式
二、如今咱們就接收到剛纔建立的通知了
9、iOS10 及之前系統的推送註冊比較
iOS10正式版發佈以後,網上各類適配XCode8以及iOS10的文章滿天飛。但對於iOS10適配遠程推送的文章卻很少。iOS10對於推送的修改仍是很是大的,新增了UserNotifications Framework。
一、Capabilities中打開Push Notifications 開關
在XCode7中這裏的開關不打卡,推送也是能夠正常使用的,可是在XCode8中,這裏的開關必需要打開,否則會報錯:
Error Domain=NSCocoaErrorDomain Code=3000 "未找到應用程序的「aps-environment」的受權字符串" UserInfo={NSLocalizedDescription=未找到應用程序的「aps-environment」的受權字符串}
打開後會生成entitlements文件,在這裏能夠設置APS Environment
二、註冊遠程推送通知(獲取deviceToken----包含設備信息和應用信息的一串編碼)
首先引入UserNotifications Framework,
import <UserNotifications/UserNotifications.h>
if
(IOS_VERSION >= 10.0) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(
BOOL
granted, NSError * _Nullable error) {
if
(!error) {
DLog(@
"request authorization succeeded!"
);
}
}];
}
else
{
if
([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
//IOS8,建立UIUserNotificationSettings,並設置消息的顯示類類型
UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:notiSettings];
}
}
三、UNUserNotificationCenterDelegate代理實現
在iOS10中處理推送消息須要實現UNUserNotificationCenterDelegate的兩個方法:
其中第一個方法爲App在前臺的時候收到推送執行的回調方法,第二個爲App在後臺的時候,點擊推送信息,進入App後執行的 回調方法。
之前處理推送,信息是在userInfo參數中,而新方法中代表上看並無這個參數,其實咱們同樣能夠獲取到userInfo,以下:
/// App在前臺時候回調
- (
void
)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(
void
(^)(UNNotificationPresentationOptions))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
[self handleRemoteNotificationForcegroundWithUserInfo:userInfo];
}
/// App在後臺時候點擊推送調用
- (
void
)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(
void
(^)())completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
[self handleRemoteNotificationBackgroundWithUserInfo:userInfo];
}