IOS 基於APNS消息推送原理與實現(JAVA后台)


Push的原理:

Push 的工作機制可以簡單的概括為下圖



 

圖中,Provider是指某個iPhone軟件的Push服務器,這篇文章我將使用.net作為Provider。

APNS 是Apple Push Notification Service(Apple Push服務器)的縮寫,是蘋果的服務器。

上圖可以分為三個階段。

第一階段:Push服務器應用程序把要發送的消息、目的iPhone的標識打包,發給APNS。 

第二階段:APNS在自身的已注冊Push服務的iPhone列表中,查找有相應標識的iPhone,並把消息發到iPhone。 

第三階段:iPhone把發來的消息傳遞給相應的應用程序, 並且按照設定彈出Push通知。

 



 

從上圖我們可以看到。

1、首先是應用程序注冊消息推送。

2、 IOS跟APNS Server要deviceToken。應用程序接受deviceToken。

3、應用程序將deviceToken發送給PUSH服務端程序。

4、 服務端程序向APNS服務發送消息。

5、APNS服務將消息發送給iPhone應用程序。

無論是iPhone客戶端跟APNS,還是Provider和APNS都需要通過證書進行連接的。下面介紹一下所用到證書的制作。

一、CSR文件

 

1、生成Certificate Signing Request(CSR)

  

 

2、填寫你的郵箱和常用名稱,並選擇保存到硬盤。

 

 

點擊繼續:



 

這樣就在本地生成了一個PushTest.certSigningRequest文件。

 

 

二、SSL certificate文件

 

1、用你付過費的帳號登錄到iOS Provisioning Portal,並創建Certificates(已創建可省略),如下圖:



 

 

 

 點擊Submit

 創建Certificate完畢。

2、新建一個App ID

 點擊New App ID

輸入Description,Bundle Identifier,點擊Submit,新建App ID完畢。

找到新建的App ID 點擊右側的Configure:



 Development Push SSL Certificate ,與Production Push SSL Certificate 區別在於一個是用於開發的推送證書,一個是用於發布產品的推送證書。兩個證書獲取到的終端deviceToken是不一樣的,用兩個證書生成的P12證書用於JAVA后台連接APNS的服務器地址也是不同的,Development Push SSL Certificate 對應連接的服務器地址是:gateway.sandbox.push.apple.com。Production Push SSL Certificate  對應連接的服務器地址是:gateway.push.apple.com。

點擊Development Push SSL Certificate一行后的Configure:

 點擊Continue:




 

選擇前面生成好的PushTest.certSigningRequest文件,點擊Generate,出現如下所示的頁面:



點擊Continue:



 

 點擊Download,下載生成的支持推送服務的證書(命名為:aps_development-6.cer)。

 

點擊Done,你會發現狀態變成了Enabled:

 

到現在為止,我們已經生成了兩個文件:

1、PushTest.certSigningRequest

2、aps_development-6.cer(下載生成的支持推送服務的證書。)

雙擊aps_development-6.cer注冊到你的鑰匙串中,這樣你的鑰匙串中就會有

 

三、准備profile證書,因為推送消息只能在真機上測試,所以要建一個profile證書

 點擊"new profile"為上面新建的APP ID建個profile ,成功之后下載pushtestdescDevprofile.mobileprovision

雙擊將其加入到xcode 的Provisioning Profiles 中。

四、生成JAVA后台用於連接APNS的證書:

打開鑰匙串

 
選中Apple Development IOS Push Services:com.easecom.zhwgpushtestdesc,右鍵將其導出。

導出用於JAVA后台連接APNS的P12證書。

 輸入p12 證書的密碼,本文中我用的是123456。記住這個密碼,JAVA后台使用p12證書的時候要用到。

 輸入訪問鑰匙串的密碼:系統登陸密碼。

導出PushTest.p12證書完畢。

到現在為止,我們已經生成了四個文件:

1、PushTest.certSigningRequest

2、aps_development-6.cer(下載生成的支持推送服務的證書。)

3、pushtestdescDevprofile.mobileprovision
4、PushTest.p12

至此IOS消息推送(JAVA后台)證書全部制作完畢。

下面開始上代碼:

五、IOS端代碼:

1、首先在項目的AppDelegate.m中加入以下兩個代理方法

 1 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
 2     NSString *token = [NSString stringWithFormat:@"%@", deviceToken]; 
 3 
 4     //獲取終端設備標識,這個標識需要通過接口發送到服務器端,服務器端推送消息到APNS時需要知道終端的標識,APNS通過注冊的終端標識找到終端設備。
 5     NSLog(@"My token is:%@", token);   
 6 }  
 7 
 8 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {   
 9     NSString *error_str = [NSString stringWithFormat: @"%@", error];   
10     NSLog(@"Failed to get token, error:%@", error_str);   
11 } 

 

2、在AppDelegate.m的(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中加入注冊消息通知推送能力;加入當應用程序處於未啟動狀態時,判斷是否由遠程消息通知觸發;加入清除消息推送通知標記。

 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 2 {
 3 
 4   //判斷是否由遠程消息通知觸發應用程序啟動
 5 
 6     if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]!=nil) {
 7 
 8         //獲取應用程序消息通知標記數(即小紅圈中的數字)
 9 
10         int badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
11         if (badge>0) {
12 
13            //如果應用程序消息通知標記數(即小紅圈中的數字)大於0,清除標記。
14 
15             badge--;
16 
17           //清除標記。清除小紅圈中數字,小紅圈中數字為0,小紅圈才會消除。
18             [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
19         }
20     }
21 
22     //消息推送注冊
23     [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge];
24 
25 }

3、在項目AppDelegate.m中加入消息接收處理代理方法。

1 //處理收到的消息推送
2 - (void)application:(UIApplication *)application 
3 didReceiveRemoteNotification:(NSDictionary *)userInfo
4 {
5 
6     //在此處理接收到的消息。
7     NSLog(@"Receive remote notification : %@",userInfo);
8 }

六、JAVA后台代碼:

 1 public static void main(String[] args) throws Exception 
 2  {
 3         try
 4         {
 5             //從客戶端獲取的deviceToken,在此為了測試簡單,寫固定的一個測試設備標識。
 6            String deviceToken = "df779eda 73258894 5882ec78 3ac7b254 6ebc66fe fa295924 440d34ad 6505f8c4"
 7 
 8             System.out.println("Push Start deviceToken:" + deviceToken);
 9             //定義消息模式
10             PayLoad payLoad = new PayLoad();
11             payLoad.addAlert("this is test!");
12             payLoad.addBadge(1);//消息推送標記數,小紅圈中顯示的數字。
13             payLoad.addSound("default");
14             //注冊deviceToken
15             PushNotificationManager pushManager = PushNotificationManager.getInstance();
16             pushManager.addDevice("iPhone", deviceToken);
17             //連接APNS
18             String host = "gateway.sandbox.push.apple.com";
19             //String host = "gateway.push.apple.com";
20             int port = 2195;
21 
22             String certificatePath = "c:/PushTest.p12";//前面生成的用於JAVA后台連接APNS服務的*.p12文件位置
23             String certificatePassword = "123456";//p12文件密碼。
24             pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
25             //發送推送
26             Device client = pushManager.getDevice("iPhone");
27             System.out.println("推送消息: " + client.getToken()+"\n"+payLoad.toString() +" ");
28             pushManager.sendNotification(client, payLoad);
29             //停止連接APNS
30             pushManager.stopConnection();
31             //刪除deviceToken
32             pushManager.removeDevice("iPhone");
33             System.out.println("Push End");
34         }
35         catch (Exception ex)
36         {
37             ex.printStackTrace();
38         }
39  }
40 }

至此大功告成,測試通過。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM