一步一步实现iOS应用PUSH功能

1. push原理

iOS push 工作机制可以用下图简要概括

  • Provider:应用自己的服务器;
  • APNS:Apple Push Notification Service的简称,苹果的PUSH服务器;

push的主要工作流程是:

  • iOS设备连接网络后,会自动与APNS保持类似TCP的长链接,等待APNS推送消息的到来;
  • 应用启动时注册消息推送,并获取设备的在APNS中注册的唯一设备标示deviceToken上传给应用服务器(即Provider);
  • 在需要给应用推送消息时,Provider把push内容、接收push消息的deviceToken按APNS指定的格式打包好,发送给APNS;
  • APNS收到Provider发送的消息后,查找deviceToken指定的设备,如果该设备已经和APNS建立了连接,则立即将消息推送给该设备,如果设备不在线,则在该设备下次连接到APNS后将消息推送到设备。请注意苹果并不保证推送一定成功;
  • 设备收到push消息后,iOS系统会根据SSL证书判断这个push消息是发给那个应用的,进而启动相应客户端。

上述过程中,有两个关键步骤需要自己处理的是:1.客户端获取deviceToken,并上传到Provider;2.Provider发送push消息到APNS。这两个步骤中都需要苹果的push证书授权,下面就来介绍如何生成push证书,以及Provisioning Profile。

2. push证书及Provisioning Profile生成

  • 用付费帐号登录到http://developer.apple.com/iphone/index.action
  • 生成push证书前要先生成开发证书

    生成开发证书的过程不详细介绍,可以参考如何联机调试和发布程序。只是有一点需要注意的,生成开发证书过程中需要通过Keychain生成一个CSR文件,默认名为CertificateSigningRequest.certSigningRequest,这个文件将在生成push证书的时候用到。

  • 创建一个App ID
    • 创建过程中Description可以任意填写,比如叫push_demo
    • Bundle Identifier一般用com.company.appname这样的格式,例如com.mycompany.demo

    注意:要用push功能的Bundle Identifier一定不能出现通配符,比如com.mycompany.*,这样的名字是不能使用push的。

  • 生成Push SSL Certificate

    生成好App ID后点击Configure进入配置页。打开Enable for Apple Push Notification service选项,该选项下有Development Push SSL CertificateProduction Push SSL Certificate两个SSL Certificate可以配置,前面一个是用来的开发的push证书,后面一个是用来发布的。我们以开发push证书为例,点击Development Push SSL Certificate->Configure,后面会要求选择CSR文件,这就是生成开发证书时的CertificateSigningRequest.certSigningRequest文件,选择好CSR后就生成好相应的SSL Certificate了。下载下来,保存名为aps_developer.cer

  • 从Keychain中导出私钥、设置好密码,命名为private_key.p12
  • 生成push证书
    • 这时我们一共得到3个文件:

      1. CertificateSigningRequest.certSigningRequest
      2. private_key.p12
      3. aps_developer.cer
    • 将aps_developer.cer转成pem格式
      openssl x509 -in aps_developer.cer -inform DER -out aps_developer.pem -outform PEM
      
    • 将private_key.p12格式的私钥转换成private_key.pem
      openssl pkcs12 -nocerts -out private_key.pem -in private_key.p12
      

      这一步会要求输入p12私钥的密码,以及设置新生成的pem的密码。

    • 创建用于服务端的SSL p12格式证书,命名为aps_developer.p12
      openssl pkcs12 -export -in aps_developer.pem -inkey private_key.pem -certfile CertificateSigningRequest.certSigningRequest -name "aps_developer" -out aps_developer.p12
      

      这一步会要求输入private_key.pem的密码,注意不是private_key.p12的密码。如果密码错误,或者CertificateSigningRequest.certSigningRequest文件不匹配都不能正常生成aps_developer.p12文件,如果生成的aps_developer.p12文件大小是0,说明生成过程中出了问题,请检查pem私钥、密码、以及CertificateSigningRequest.certSigningRequest是否正确。

      aps_developer.p12就是Provider向APNS发送push消息需要的SSL证书。把这个证书和密码提供给服务端,服务端就可以发送push消息给APNS了。这时服务端已经可以工作了,但客户端还必须配置相应的Provisioning Profile才能启动应用的push功能。

      服务器配置需注意的是,由于我们生成的是开发环境的push证书,所以服务器应该连接APNS的sandbox环境地址:gateway.sandbox.push.apple.com:2195,如果应用正式发布,就要连接正式环境,必须生成相应的发布证书,并连接APNS正式环境地址:gateway.push.apple.com:2195

  • 生成Provisioning Profile
    • 新建Profile,命名为push_dev;
    • 选择相应证书;
    • App ID选择push_demo;
    • 选择设备;
    • 下载并安装该Profile供开发使用;

3. Xcode证书设置、Info.plist设置

  • 用Xcode打开客户端工程,设置Info.plist的Bundle identifier为com.mycompany.demo
  • 打开工程设置,必须将证书设置为与push_dev关联的证书。

4. 客户端获取deviceToken

服务端要发送push消息给某一设备还必须知道该设备的deviceToken。应用运行后获取到deviceToken,然后上传给服务器,下面介绍应用如何获取deviceToken。应用必须先注册使用push功能。

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];
      // do something
      // ...
  }

在AppDelegate中添加下面方法来获取deviceToken:

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

  - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
      NSLog(@"%@", error);
  }

应用获取到deviceToken后,上传给Provider,Provider就可以用这个deviceToken给这个设备push消息了。

5. Payload格式及自定义数据

服务器配置好证书并拿到deviceToken后就可以向APNS发送消息了。发送消息的格式如下图所示:

Payload就是push的消息负载,这就是应用需要关心的数据。 Payload是一个JSON字典,最大值是 256 字节,超过这个限制,APNS将拒绝转发。基本格式如下:

{
    "aps": {
      "alert":"Hello Push!",
      "badge":1,
      "sound":"default"
    },
    "page":"home"
  }

必须包含aps键值。badge表示应用程序图标显示的数字,sound表示收到push的提示音。 Payload的具体结构参考Apple Push Notification Service

要在这个结构中新增自定义数据,请加在aps空间之外。比如后台推送消息给应用同时要求应用打开某个页面:

后台告诉客户端收到这个push后打开应用的主页,这里的page、home都是自己定义的。必须注意的是,Payload大小不能超过限制,所以可以把自定义数据更简化点,比如可以把home与编号1对应,page简写为p,这样"p":1表示打开主页,可以缩小Payload的大小。

6. 客户端接收push消息

iOS系统收到push消息后,如果用户点击查看,系统将根据证书启动相应应用。如果应用已经启动,将调用AppDelegate的方法:

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
      // userInfo 就是push消息的Payload
  }

如果应用还没有启动,通过push冷启动后,仍然能在启动后获取Payload:

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
      NSLog(@"Payload: %@", userInfo);
  }

目前为止,push功能基本就完成了,可以开始push功能测试了,如果服务器还没开发完成,或者想快速测试是否能正常push,可以使用下面的代码实现后台push测试。发送push前要配置好SSL证书,以及deviceToken和Payload结构。

object c 版本
c 版本
java 版本
php 版本

还有个小问题,当Payload设置了badge,应用图标上将一直显示一个数字提示,如果要清除数字提示,或者设置成其他数字,调用下面函数就可以完成。

 [[UIApplication sharedApplication] setApplicationIconBadgeNumber:number];

number为0就会清除数字提示。

一步一步实现iOS应用PUSH功能

时间: 2024-10-25 21:19:42

一步一步实现iOS应用PUSH功能的相关文章

一步一步学ios UITextView(多行文本框)控件的用法详解(五5.8)

本文转载至 http://wuchaorang.2008.blog.163.com/blog/static/48891852201232014813990/ 1.创建并初始化 创建UITextView的文件,并在.h文件中写入如下代码: [csharp] view plaincopy #import <UIKit/UIKit.h> @interface TextViewController : UIViewController <UITextViewDelegate> { UITe

一步一步实现消息推送 2014-06-19

因为项目的需求,需要实现消息推送的功能,所以最近调研了很多有关消息推送的消息. 1.需要了解公钥和私钥 2.了解certificate.appid.Provisioning等的作用. 3.参考了网上不少资料,推送的整个过程参考http://blog.csdn.net/showhilllee/article/details/8631734  并截取了最新的apple证书申请流程图 但是后端服务器,先是采用了“一步一步教你做ios推送”中的php,但是没有消息被推送到手机端,后面采用了github中

一步一步学习Vue(十一)

本篇继续学习vuex,还是以实例为主:我们以一步一步学Vue(四)中讲述的例子为基础,对其改造,基于vuex重构一遍,这是原始的代码: todolist.js ; (function () { var list = []; var Todo = (function () { var id = 1; return function (title, desc) { this.title = title; this.desc = desc; this.id = id++; } })(); /** *

大流量网站性能优化:一步一步打造一个适合自己的BigRender插件(转)

BigRender 当一个网站越来越庞大,加载速度越来越慢的时候,开发者们不得不对其进行优化,谁愿意访问一个需要等待 10 秒,20 秒才能出现的网页呢? 常见的也是相对简单易行的一个优化方案是 图片的延迟加载.一个庞大的页面,有时我们并不会滚动去看下面的内容,这样就浪费了非首屏部分的渲染,而这些无用的渲染,不仅包括图片,还包括其他的 DOM 元素,甚至一些 js/css(某些js/css 是根据模块请求的,比如一些 ajax),理论上,每增加一个 DOM,都会增加渲染的时间.有没有办法能使得

【转】朱兆祺带你一步一步学习嵌入式(连载)

原文网址:http://bbs.elecfans.com/jishu_357014_2_1.html#comment_top  从最初涉及嵌入式Linux开始到现在,深深的知道嵌入式的每一步学习都是举步维艰.从去年11月份开始,我就着手整理各种学习资料,希望推动嵌入式学习的前进贡献自己微不足道的一份力量.从去年到现在,将C语言的学习经验整理成<攻破C语言笔试与机试陷阱及难点>(现在仍在更新),这份资料已经在电子发烧友论坛的单片机论坛连载(http://bbs.elecfans.com/jish

一步一步学Vue(十二)

为了提升代码的逼格,之后代码改为Vue文件组件,之前代码虽然读起来容易理解,而且适合在小的项目中使用,但是有如下缺点: 全局定义(Global definitions) 强制要求每个 component 中的命名不得重复 字符串模板(String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \ 不支持CSS(No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏 没有构建步骤(No build step) 限

一步一步学习Swift之(一):关于swift与开发环境配置

一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Swift 采用安全的编程模式并添加了很多新特性,这将使编程更简单,更灵活,也更有趣. 4.Swift 是基于成熟而且倍受喜爱的 Cocoa 和 Cocoa Touch 框架,它的降临将重新定义软件开发. 5.Swift 是编写 iOS 和 OS X 应用的极佳手段,并将伴随着新的特性和功能持续演进.

Android教程-从零开始一步一步接入SDK

从零开始一步一步接入SDK 本篇博客想总结一下笔者在接入手游渠道SDK的一些经验方法,为想接入手游渠道或者想学习如何接入SDK的童鞋们提供一个参考.本篇博客基于Android平台,关于IOS接入SDK的方法,笔者以后有机会也会整理. 首先来给大家说明一下SDK,何为SDK?它的全称是,SoftWare Develop Kit,意思是软件开发工具包,它是可以辅助我们去开发某类软件的相关文档,范例和工具的集合.关于SDK,这里推荐一个服务商店,名叫Devstore(http://www.devsto

一步一步学习Vue(六)

本篇继续介绍vue-router,我们需要要完成这样个demo:<分页显示文章列表>:这里我们以博客园首页列表为例简化处理: 按照上图框选所示,简单分为蓝色部分文章组件(ArticleItemComponent),橙色框选部分列表组件(ArticleListComponent):分页部分我们就简单通过router-link指令构建满足演示即可,我们的代码实现逻辑: 1.列表组件初始化数据,传递给文章组件进行渲染 2.路由改变时重新初始化列表组件,更新数据 请看我们的第一版代码: <!DO