原文地址:http://www.dapps.net/dev/iphone/ios-push-notification-principle-realization.html
一、消息推送原理:
在實現消息推送之前先提及幾個於推送相關概念,如下圖:
1、 Provider:就是爲指定IOS設備應用程序提供Push的服務器,(如果IOS設備的應用程序是客戶端的話,那麼Provider可以理解爲服務端[消息的發起者]);
2、 APNS:Apple Push Notification Service[蘋果消息推送服務器];
3、 iPhone:用來接收APNS下發下來的消息;
4、 Client App:IOS設備上的應用程序,用來接收iphone傳遞APNS下發的消息到制定的一個客戶端 app[消息的最終響應者];
上圖可以分爲三個階段:
階段一:Provider[服務端]把要發送的消息,目的IOS設備標識打包,發送給APNS;
階段二:APNS在自身的已註冊Push服務的IOS設備列表中,查找有相應標識的IOS設備,並將消息發送到IOS設備;
階段三:IOS設備把發送的消息傳遞給對應的應用程序,並且按照設定彈出Push通知。
具體過程,如下圖:
1、 Provider:就是爲指定IOS設備應用程序提供Push的服務器,(如果IOS設備的應用程序是客戶端的話,那麼Provider可以理解爲服務端[消息的發起者]);
2、 APNS:Apple Push Notification Service[蘋果消息推送服務器];
3、 iPhone:用來接收APNS下發下來的消息;
4、 Client App:IOS設備上的應用程序,用來接收iphone傳遞APNS下發的消息到制定的一個客戶端 app[消息的最終響應者];
上圖可以分爲三個階段:
階段一:Provider[服務端]把要發送的消息,目的IOS設備標識打包,發送給APNS;
階段二:APNS在自身的已註冊Push服務的IOS設備列表中,查找有相應標識的IOS設備,並將消息發送到IOS設備;
階段三:IOS設備把發送的消息傳遞給對應的應用程序,並且按照設定彈出Push通知。
具體過程,如下圖:
1、 [Client App]註冊消息推送;
2、 [Client App]跟[APNS Service]要deviceToken, Client App接收deviceToken;
3、 [Client App]將deviceToken發送給[Provider]Push服務端程序;
4、 當Push服務端程序滿足發送消息條件了,[Provider]向[APNS Service]發送消息;
5、 [APNS Service]將消息發送給[Client App].
2、 [Client App]跟[APNS Service]要deviceToken, Client App接收deviceToken;
3、 [Client App]將deviceToken發送給[Provider]Push服務端程序;
4、 當Push服務端程序滿足發送消息條件了,[Provider]向[APNS Service]發送消息;
5、 [APNS Service]將消息發送給[Client App].
二、消息推送實現:
1、 生成*.certSigningRequest文件,步驟如下:
[MacBookà應用程序à實用工具à鑰匙串訪問à證書助手à從證書機構求證書?à證書信息(用戶電子郵箱地址{填寫您的郵箱,如:[email protected]},常用名稱{任意,如:PushDemo},請求是:{單選,選擇‘存儲到磁盤’})à繼續à保存],這時會在您指定的地方生成你指定的文件,默認爲CertificateSigningRequest.certSigningRequest文件,這裏命名爲:PushDemo.certSigningRequest.在此*.certSigningRequest已經生成,具體操作步驟如下面兩張圖所示。
[MacBookà應用程序à實用工具à鑰匙串訪問à證書助手à從證書機構求證書?à證書信息(用戶電子郵箱地址{填寫您的郵箱,如:[email protected]},常用名稱{任意,如:PushDemo},請求是:{單選,選擇‘存儲到磁盤’})à繼續à保存],這時會在您指定的地方生成你指定的文件,默認爲CertificateSigningRequest.certSigningRequest文件,這裏命名爲:PushDemo.certSigningRequest.在此*.certSigningRequest已經生成,具體操作步驟如下面兩張圖所示。
如果生成成功,則會在[鑰匙串訪問|登錄|密鑰]欄目中列出與*.certSigningRequest關聯的密鑰,這裏是PushDemo,如下圖所示:
2、 新建一個App ID(在蘋果開發者賬號中配置)
(1) 登錄iOS Dev Center,登錄成功後,點擊(iOS Provisioning Portal對應鏈接),如下圖所示:
2、 新建一個App ID(在蘋果開發者賬號中配置)
(1) 登錄iOS Dev Center,登錄成功後,點擊(iOS Provisioning Portal對應鏈接),如下圖所示:
(2) 創建New App ID[App IDsàManageàNew App ID]( Description{填寫您對此App ID 的描述,如:iShop},Bundle Seed ID(App ID Prefix){選擇綁定App ID前綴,如:默認選擇Generate New},Bundle Identifier(App ID Suffix){填寫綁定App ID後綴,如:com.yourcorp.iShop}),如下圖所示:
這樣就會生成下面這條記錄,如下圖所示:
(3) 配置上一步中生成的App ID,讓其支持消息推送[點擊2-6中的Configureà選中Enable for Apple Push Notification serviceà點擊Configure],如下圖所示:
(4) Generate a Certificate Signing Request(生成部署請求認證)[點擊上圖中的2ConfigureàContinueà步驟1生成的*certSigningRequest文件(這裏是iShop. certSigningRequest)à Generateà生成完成後將其下載下來,命名爲:aps_developer_identity.cer],雙擊aps_developer_identity.cer證書{將證書與密鑰關聯,並將證書導入到MacBook中},如下圖所示:
(5) 創建Development Provisioning Profiles[開發許可配置文件](Provisioning| Development|New Profile),具體操作流程如下圖所示:
點擊上圖中Submit,生成Development Provisioning Profiles[開發許可配置文件],這裏是:iShopDevprofile.mobileprovision如下圖所示:
這樣就會生成下面這條記錄,如下圖所示:
(3) 配置上一步中生成的App ID,讓其支持消息推送[點擊2-6中的Configureà選中Enable for Apple Push Notification serviceà點擊Configure],如下圖所示:
(4) Generate a Certificate Signing Request(生成部署請求認證)[點擊上圖中的2ConfigureàContinueà步驟1生成的*certSigningRequest文件(這裏是iShop. certSigningRequest)à Generateà生成完成後將其下載下來,命名爲:aps_developer_identity.cer],雙擊aps_developer_identity.cer證書{將證書與密鑰關聯,並將證書導入到MacBook中},如下圖所示:
(5) 創建Development Provisioning Profiles[開發許可配置文件](Provisioning| Development|New Profile),具體操作流程如下圖所示:
點擊上圖中Submit,生成Development Provisioning Profiles[開發許可配置文件],這裏是:iShopDevprofile.mobileprovision如下圖所示:
下載此開發許可證書(用於聯機調試)。
總結,到現在爲止,我們已經生成:A:*.certSigningRequest文件(在步驟(4)中使用,用於生成證書B)、B: aps_developer_identity.cer證書(在Provider[Push服務器]服務端應用使用)、C:*..mobileprovision開發許可配置文件(在Client App客戶端應用聯機調試使用)。
總結,到現在爲止,我們已經生成:A:*.certSigningRequest文件(在步驟(4)中使用,用於生成證書B)、B: aps_developer_identity.cer證書(在Provider[Push服務器]服務端應用使用)、C:*..mobileprovision開發許可配置文件(在Client App客戶端應用聯機調試使用)。
至此,消息推送的配置已經全部完成,接下來的工作就是編寫Provider[Push服務器]服務端應用和Client App客戶端應用的程序。
三、Provider服務端的實現
在這裏只是簡單講述Provider服務端(JAVA實現)步驟如下:
(1) 製作Provider服務端所需要的*.p12文件:
在上面的實現的(4) 部分的圖所展示的密鑰、證書,我們並沒有使用到它,那麼爲什麼要展示出來呢,猜猜是爲什麼?爲製作*.p12文件?哈哈,您猜對了,下面我們就利用它來製作*.p12文件,步驟:([MacBookà應用程序à實用工具à鑰匙串訪問[鑰匙串:登錄,種類:證書]à選擇剛剛生成的證書(Apple Development IOS Services:*******)à菜單à文件à導出項目…à[存儲爲:任意文件名(如:iPush),文件格式:默認(個人信息交換(.p12))]à輸入密碼以進行導出[密碼:任意,驗證:與密碼同一]à輸入MACBook登錄密碼à允許à最終生成。
在上面的實現的(4) 部分的圖所展示的密鑰、證書,我們並沒有使用到它,那麼爲什麼要展示出來呢,猜猜是爲什麼?爲製作*.p12文件?哈哈,您猜對了,下面我們就利用它來製作*.p12文件,步驟:([MacBookà應用程序à實用工具à鑰匙串訪問[鑰匙串:登錄,種類:證書]à選擇剛剛生成的證書(Apple Development IOS Services:*******)à菜單à文件à導出項目…à[存儲爲:任意文件名(如:iPush),文件格式:默認(個人信息交換(.p12))]à輸入密碼以進行導出[密碼:任意,驗證:與密碼同一]à輸入MACBook登錄密碼à允許à最終生成。
關鍵步驟如下圖:
(2) 編寫Client App客戶端的關鍵代碼,如下:
(2) 編寫Client App客戶端的關鍵代碼,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]bounds]] autorelease]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; //消息推送支持的類型 UIRemoteNotificationType types = (UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert); //註冊消息推送 [[UIApplication sharedApplication]registerForRemoteNotificationTypes:types]; return YES; } //獲取DeviceToken成功 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"DeviceToken: {%@}",deviceToken); //這裏進行的操作,是將Device Token發送到服務端 } //註冊消息推送失敗 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"Register Remote Notifications error:{%@}",[errorlocalizedDescription]); } //處理收到的消息推送 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"Receive remote notification : %@",userInfo); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"溫馨提示" message:@"推送成功!" delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil]; [alert show]; [alert release]; } |
(3)編寫Provider服務端關鍵代碼,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import javapns.back.PushNotificationManager; import javapns.back.SSLConnectionHelper; import javapns.data.Device; import javapns.data.PayLoad; public class MainSend { public static void main(String[] args) throws Exception { try { //從客戶端獲取的deviceToken String deviceToken = "3a20764942e9cb4c4f6249274f12891946bed26131b686b8aa95322faff0ad46"; System.out.println("Push Start deviceToken:" + deviceToken); //定義消息模式 PayLoad payLoad = new PayLoad(); payLoad.addAlert("消息推送測試!"); payLoad.addBadge(4); payLoad.addSound("default"); //註冊deviceToken PushNotificationManager pushManager = PushNotificationManager.getInstance(); pushManager.addDevice("iPhone", deviceToken); //連接APNS String host = "gateway.sandbox.push.apple.com"; int port = 2195; String path = "/Users/iMilo/Work.localized/iShop/project/service/iPush/"; String certificatePath = (path + "src/ipush/iPush.p12"); //certificatePath 步驟一中生成的*.p12文件位置 String certificatePassword = "Love24mm"; pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12); //發送推送 Device client = pushManager.getDevice("iPhone"); pushManager.sendNotification(client, payLoad); //停止連接APNS pushManager.stopConnection(); //刪除deviceToken pushManager.removeDevice("iPhone"); System.out.println("Push End"); } catch (Exception ex) { ex.printStackTrace(); } } } |
注意:如果Provider服務端爲Objective-C實現的話,就不需要*.p12證書。