APNs 推送通知

APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。

上图可以分为三个阶段。

第一阶段:Push服务器应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。 

第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。 

第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。

一、CSR文件

1、生成Certificate Signing Request(CSR)

2、填写你的邮箱和常用名称,并选择保存到硬盘。

二、SSL certificate文件

1、通过刚生成的 .certSigningRequest在开发者中心添加测试推送证书(发布推送证书同理)(https://developer.apple.com)

2、下载下来双击安装

3、打开钥匙串-》我的证书,右击选择导出该证书(若没有该选项 点击他处再右击),给证书创建一个密码

注:JAVA后台用这个.p12证书就好,需要.pem证书的还需要如下步骤:

APNS证书导出pem

openssl x509 -in aps_development.cer -inform der -out yourCertName.pem 

APNS证书密钥导出

先在"钥匙串"中导出apns证书下的密钥,别导错了.

生成.p12格式.

从p12导出pem.

需要输入密码的.

openssl pkcs12 -nocerts -out MobileCAPKey.pem -in MobileCAPKey.p12 

导出不需要输入密码的

openssl pkcs12 -nodes -out MobileCAPKey.pem -in MobileCAPKey.p12 

主要是参数不同.

合并cer.pem和key.pem

cat yourCertName.pem MobileCAPKey.pem > apns-dev.pem

五、IOS端代码:

1、首先在项目的AppDelegate.m中加入以下两个代理方法

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
    NSString *token = [NSString stringWithFormat:@"%@", [deviceToken

substringWithRange:NSMakeRange(1, tokenStr.length - 2)]

]; //去掉首尾

    //获取终端设备标识,这个标识需要通过接口发送到服务器端,服务器端推送消息到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];

}

- (void)applicationDidBecomeActive:(UIApplication *)application

{

    //点击通知进入

    //一般在整个应用程序加载时执行,挂起进入后也会执行,所以很多时候都会使用到,将小红圈清空

    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;

}
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();
        }
 }
}

注意:

1、device token跟app无关,测试证书和发布证书获取到的不一样;

2、当机器被刷时token会变动;

3、证书有效期为1年,快要过期时应及时更换,更换不会影响老证书的运行;

4、格式:

{
"aps" : 
{
"alert" : "Message received from Bob",
"badge" : 5,
"sound" : "bingbong.aiff"
},
"otherData" : @""
}

5、bundle id不能带*

posted @ 2014-07-25 11:11  燕羽天空  Views(470)  Comments(0Edit  收藏  举报