在实现消息推送之前先提及几个于推送相关概念,如下图:



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].

二、消息推送实现:

1、 生成*.certSigningRequest文件,步骤如下:

[MacBookà应用程序à实用工具à钥匙串访问à证书助手à从证书机构求证书?à证书信息(用户电子邮箱地址{填写您的邮箱,如:your@email.com},常用名称{任意,如:PushDemo},请求是:{单选,选择‘存储到磁盘’})à继续à保存],这时会在您指定的地方生成你指定的文件,默认为CertificateSigningRequest.certSigningRequest文件,这里命名为:PushDemo.certSigningRequest.在此*.certSigningRequest已经生成,具体操作步骤如下面两张图所示。

如果生成成功,则会在[钥匙串访问|登录|密钥]栏目中列出与*.certSigningRequest关联的密钥,这里是PushDemo,如下图所示:



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如下图所示:

下载此开发许可证书(用于联机调试)。

总结,到现在为止,我们已经生成: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登录密码à允许à最终生成。

关键步骤如下图:


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

        }

    }

}

iOS 消息推送原理及实现总结 分类: ios技术 2015-03-01 09:22 70人阅读 评论(0) 收藏的更多相关文章

  1. iOS开发:创建真机调试证书 分类: ios相关 2015-04-10 10:22 149人阅读 评论(0) 收藏

    关于苹果iOS开发,笔者也是从小白过来的,经历过各种困难和坑,其中就有关于开发证书,生产证书,in_house证书,add_Hoc证书申请过程中的问题,以及上架发布问题.今天就着重说一下关于针对于苹果 ...

  2. iOS开源库--最全的整理 分类: ios相关 2015-04-08 09:20 486人阅读 评论(0) 收藏

    youtube下载神器:https://github.com/rg3/youtube-dl 我擦咧 vim插件:https://github.com/Valloric/YouCompleteMe vi ...

  3. IOS第三方数据库--FMDB 分类: ios技术 2015-03-01 09:38 57人阅读 评论(0) 收藏

    iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepers ...

  4. Java内部类总结 分类: 原理 2015-06-28 09:51 9人阅读 评论(0) 收藏

    内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的. 内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问 ...

  5. ASIHTTPRequest异步请求 分类: ios技术 2015-03-01 09:33 48人阅读 评论(0) 收藏

    我们运行程序,如果网速很慢,查询的时候会一直黑屏,直到请求结束画面才出现,这样用户体验很不好.因此同步请求一般只是在某个子线 程中使用,而不在主线程中使用.异步请求的用户体验要比同步请求好,因此一般情 ...

  6. OC基础:类的扩展.协议 分类: ios学习 OC 2015-06-22 19:22 34人阅读 评论(0) 收藏

    //再设计一个类的时候,有些方法需要对外公开(接口),有些仅供内部使用. 类的扩展:为类添加新的特征(属性)或者方法 对已知类: 1.直接添加 2.继承(在其子类中添加实例变量和方法) 3.使用ext ...

  7. IOS - 消息推送原理和实现

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Pr ...

  8. iOS 消息推送原理及实现Demo

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1.Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Pr ...

  9. iOS 消息推送原理

    一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图: 1. Provider:就是为指定IOS设备应用程序提供Push的服务器,(如果IOS设备的应用程序是客户端的话,那么Prov ...

随机推荐

  1. 破解SharpPlus Sqlite Develope[转]

    1.运行里输入regedit,打开注册表 2.编辑->查找,输入sqlite 查找结果如下 3.直接删除SqliteDev节点就可以了,重新打开Sqlite Developer就可以用了,当然还 ...

  2. java 线程安全

    要认识java线程安全,必须了解两个主要的点:java的内存模型,java的线程同步机制.特别是内存模型,java的线程同步机制很大程度上都是基于内存模型而设定的. 浅谈java内存模型: 不同的平台 ...

  3. PowerDesigner 生成数据库字典(有图有真相,绝对自创非转载)

    最近用pd做模型,生成数据字典时在网上找了很多,但是看的都很晕,说的不明白. 经过自己研究终于找到一个简单的方式,当然这只是简单的,大家举一反三去吧.辛苦弄的,求点赞!!! 先看效果图: 现在说一下步 ...

  4. Android Studio相关的坑

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  5. Chapter 1 First Sight——17

    Once I got around the cafeteria, building three was easy to spot. 我一走出自助餐厅,很容易看见建筑三. A large black & ...

  6. AJAX(XMLHttpRequest)进行跨域请求方法详解(一)

    注意:以下代码请在Firefox 3.5.Chrome 3.0.Safari 4之后的版本中进行测试.IE8的实现方法与其他浏览不同. 跨域请求,顾名思义,就是一个站点中的资源去访问另外一个不同域名站 ...

  7. php获取文件名

    php获取文件名$phpself =$_SERVER['PHP_SELF']; //获取当前文件名$str = end(explode("/",$phpself)); //去掉'/ ...

  8. svn up 提示:Skipped '.'

    >svn up Skipped '.' >svn cleanup '.' is not a working copy directory >svn co https://192.16 ...

  9. 关于Jsp页面在ww:iterator 标签里面判断的写法是可以直接写数组里面的变量的

    因为上面已经遍历了,所以可以直接写变量名

  10. zf-关于注册码全部错误的解决方法

    之所以错误,是因为这里的用户名称是石首市政务服务中心. 在数据库里把这个字段改成 上海卓繁 就可以了 一般都是在 SYS_INFO 这张表里面改