zoukankan      html  css  js  c++  java
  • 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()+" "+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不能带*

  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/swallow37/p/3867540.html
Copyright © 2011-2022 走看看