天天看點

IOS Java實作消息推送(APNS)

轉自: http://ytwhw.iteye.com/blog/1744148

Push的原理:

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

IOS Java實作消息推送(APNS)

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

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

上圖可以分為三個階段。

第一階段:Push伺服器應用程式把要發送的消息、目的iPhone的辨別打包,發給APNS。 

第二階段:APNS在自身的已注冊Push服務的iPhone清單中,查找有相應辨別的iPhone,并把消息發到iPhone。 

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

IOS Java實作消息推送(APNS)

從上圖我們可以看到。

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)

IOS Java實作消息推送(APNS)

2、填寫你的郵箱和常用名稱,并選擇儲存到硬碟。

IOS Java實作消息推送(APNS)

點選繼續:

IOS Java實作消息推送(APNS)

這樣就在本地生成了一個PushTest.certSigningRequest檔案。

二、SSL certificate檔案

1、用你付過費的帳号登入到iOS Provisioning Portal,并建立Certificates(已建立可省略),如下圖:

IOS Java實作消息推送(APNS)
IOS Java實作消息推送(APNS)
IOS Java實作消息推送(APNS)
IOS Java實作消息推送(APNS)

 點選Submit

IOS Java實作消息推送(APNS)

 建立Certificate完畢。

2、建立一個App ID

IOS Java實作消息推送(APNS)

 點選New App ID

IOS Java實作消息推送(APNS)

輸入Description,Bundle Identifier,點選Submit,建立App ID完畢。

IOS Java實作消息推送(APNS)

找到建立的App ID 點選右側的Configure:

IOS Java實作消息推送(APNS)

 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:

IOS Java實作消息推送(APNS)

 點選Continue:

IOS Java實作消息推送(APNS)
IOS Java實作消息推送(APNS)

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

IOS Java實作消息推送(APNS)

點選Continue:

IOS Java實作消息推送(APNS)

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

點選Done,你會發現狀态變成了Enabled:

IOS Java實作消息推送(APNS)

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

1、PushTest.certSigningRequest

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

輕按兩下aps_development-6.cer注冊到你的鑰匙串中,這樣你的鑰匙串中就會有

IOS Java實作消息推送(APNS)

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

IOS Java實作消息推送(APNS)

 點選"new profile"為上面建立的APP ID建個profile ,成功之後下載下傳pushtestdescDevprofile.mobileprovision

IOS Java實作消息推送(APNS)

輕按兩下将其加入到xcode 的Provisioning Profiles 中。

四、生成JAVA背景用于連接配接APNS的證書:

打開鑰匙串

IOS Java實作消息推送(APNS)

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

IOS Java實作消息推送(APNS)

導出用于JAVA背景連接配接APNS的P12證書。

IOS Java實作消息推送(APNS)

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

IOS Java實作消息推送(APNS)

 輸入通路鑰匙串的密碼:系統登陸密碼。

IOS Java實作消息推送(APNS)

導出PushTest.p12證書完畢。

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

1、PushTest.certSigningRequest

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

3、pushtestdescDevprofile.mobileprovision

4、PushTest.p12

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

下面開始上代碼:

五、IOS端代碼:

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

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 

    NSString *token = [NSString stringWithFormat:@"%@", deviceToken]; 

    //擷取終端裝置辨別,這個辨別需要通過接口發送到伺服器端,伺服器端推送消息到APNS時需要知道終端的辨別,APNS通過注冊的終端辨別找到終端裝置。

    NSLog(@"My token is:%@", token);   

}  

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {   

    NSString *error_str = [NSString stringWithFormat: @"%@", error];   

    NSLog(@"Failed to get token, error:%@", error_str);   

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

  //判斷是否由遠端消息通知觸發應用程式啟動

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]!=nil) {

        //擷取應用程式消息通知标記數(即小紅圈中的數字)

        int badge = [UIApplication sharedApplication].applicationIconBadgeNumber;

        if (badge>0) {

           //如果應用程式消息通知标記數(即小紅圈中的數字)大于0,清除标記。

            badge--;

          //清除标記。清除小紅圈中數字,小紅圈中數字為0,小紅圈才會消除。

            [UIApplication sharedApplication].applicationIconBadgeNumber = badge;

        }

    }

    //消息推送注冊

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge];

}

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

//處理收到的消息推送

- (void)application:(UIApplication *)application 

didReceiveRemoteNotification:(NSDictionary *)userInfo

{

    //在此處理接收到的消息。

    NSLog(@"Receive remote notification : %@",userInfo);

}

六、JAVA背景代碼:

public static void main(String[] args) throws Exception 

 {

        try

        {

            //從用戶端擷取的deviceToken,在此為了測試簡單,寫固定的一個測試裝置辨別。

           String deviceToken = "df779eda 73258894 5882ec78 3ac7b254 6ebc66fe fa295924 440d34ad 6505f8c4"

            System.out.println("Push Start deviceToken:" + deviceToken);

            //定義消息模式

            PayLoad payLoad = new PayLoad();

            payLoad.addAlert("this is test!");

            payLoad.addBadge(1);//消息推送标記數,小紅圈中顯示的數字。

            payLoad.addSound("default");

            //注冊deviceToken

            PushNotificationManager pushManager = PushNotificationManager.getInstance();

            pushManager.addDevice("iPhone", deviceToken);

            //連接配接APNS

            String host = "gateway.sandbox.push.apple.com";

            //String host = "gateway.push.apple.com";

            int port = 2195;

            String certificatePath = "c:/PushTest.p12";//前面生成的用于JAVA背景連接配接APNS服務的*.p12檔案位置

            String certificatePassword = "123456";//p12檔案密碼。

            pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);

            //發送推送

            Device client = pushManager.getDevice("iPhone");

            System.out.println("推送消息: " + client.getToken()+"\n"+payLoad.toString() +" ");

            pushManager.sendNotification(client, payLoad);

            //停止連接配接APNS

            pushManager.stopConnection();

            //删除deviceToken

            pushManager.removeDevice("iPhone");

            System.out.println("Push End");

        }

        catch (Exception ex)

        {

            ex.printStackTrace();

        }

 }

}

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

以上在Iphone4,IPAD2裝置測試通過,Iphone3g,3gs需要打PushDoctor(推送醫生)更新檔才能測試通過。