APNs php客户端及静默推送

简介

关于APNs的工作原理,网上有大量的文章,建议学习apple的官方文档。通过APNs我们就可以通过服务器想APP推送想要的内容和事件。从而实现通知或者激活应用的目的。本文我们讲介绍如何搭建php的APNs推送以及如何实现静默推送。

APNs PHP 客户端

经过多方的验证,目前推荐这个:
https://github.com/immobiliare/ApnsPHP

证书验证

想要通过苹果服务器推送信息,必须要有合法的证书。很多人在推送这部分花了很多时间,很多情况是没搞清楚失败到底是代码的问题还是证书的问题。所以,我们需要先验证证书的合法和正确性。

推送时,我们要制作推送证书,我们要选择正确的类型,具体的制作过程可自行搜索,最终的证书类型如下:
push cert

Easy APNS Provider

先前我的文章推荐过Knuff,经过深入的实践,这里我推荐Easy APNS Provider,可以从MAC store下载。相比较Knuff,EAP更加的稳定强大。通过工具我们就可以先行验证证书的正确性,避免后面定位问题浪费更多的时间。
[2020.03.31更新]:另一款值得推荐的是: https://github.com/noodlewerk/NWPusher

在MAC上用客户端向苹果发送推送服务器请求时,我们选择上面安装的证书就可以了。
easy apns provider config

PHP服务器证书生成

上面我们讲了怎么选择正确的客户端证书,当我们使用php 服务器推送时,我们还要做些额外的工作:

  • 打开“钥匙串”程序,(证书助理->从证书颁发机构请求证书),只填邮箱和常用名称,ca不用填,然后保存.certSigningRequest文件到磁盘。
  • 在iOS Dev Center 点击App IDs进入App ID列表。
  • 为 App 开启 Push Notification 功能。(推送证书分为两个版本,一个是Development版,一个是Production版,分别对应开发证书和发布证书。)
  • 上传刚才生成的.certSigningRequest文件,生成aps_development.cer推送证书,双击安装。
  • 打开“钥匙串”程序,(选择登录与我的证书选项后)找到IOS Push Services那条.
  • 右键导出,存储为cert.p12,(输入密码P*d)。然后将该证书的折叠向下展开打开,导出“专用密钥”,存储为key.p12。
  • 接下来打开终端执行下面的命令,生成的ck.pem就是我们在php脚本中要使用的证书。
    #生成cert.pem
    openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12
    #生成key.pem(先输出导出key.p12时设置的密码P*d, 然后设置一个新的密码,如pushpwd,这个密码后面php推送时要设置)
    openssl pkcs12 -nocerts -out key.pem -in key.p12
    #合并成ck.pem
    cat cert.pem key.pem > ck.pem

    APNs PHP客户端配置

这个软件包的最新版本支持HTTP2,如果你的PHP的版本支持HTTP2,建议优先使用。开发包里面自带了几个sample,简单配置后基本就可以使用。这里我们以sample_push.php为测试对象。
sample push demo code

如图所示,配置要点如下:

  • 目标环境:sandbox还是production,对于appstore下载的目标,请选择ENVIRONMENT_PRODUCTION,对于开发中的版本,清选择ENVIRONMENT_SANDBOX
  • 证书:填写证书的相对路径,这里最好时按照上面的步骤验证通过的证书
  • 在上面的步骤中我们生成pem证书时,要求一个最少4位的密码,所以这个地方一定要设置密码,否则connect会失败
  • device token:这里是我们要推送的目标的token。

测试通过的返回如下:

Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: INFO: Trying tls://gateway.sandbox.push.apple.com:2195... Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: INFO: Connected to tls://gateway.sandbox.push.apple.com:2195. Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: INFO: Sending messages queue, run #1: 1 message(s) left in queue. Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: STATUS: Sending message ID 1 [custom identifier: Message-Badge-3] (1/3): 167 bytes. Fri, 13 Jan 2017 13:31:36 +0100 ApnsPHP[15355]: INFO: Disconnected.

device token

在上面我们提到了设备的device token,那么调试阶段如何获取这个token呢?在我们发起了注册请求后,系统会触发相应的消息回调。相关的参考代码如下:

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    //读取APNS token
    NSString* _deviceToken = [[[[deviceToken description]
        stringByReplacingOccurrencesOfString: @"<" withString: @""]
        stringByReplacingOccurrencesOfString: @">" withString: @""]
        stringByReplacingOccurrencesOfString: @" " withString: @""];
    QMLogDebug(@"apns token:%@",_deviceToken);
    NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];
    [userDefault setObject:_deviceToken forKey:APNSTOKEN];
    [userDefault synchronize];
}

上面的deviceToken就获取了我们需要的token。这里的deviceToken是NSData对象,可以手动导出二进制,然后这个导出文件就可以在测试客户端中使用。

全部的证书

除了ck.pem证书,我们的项目还需要 entrust_root_certification_authority.pem 这个证书,一共两个证书。

静默推送

ios最新的版本中已经支持了静默推送,静默推送时,客户端会收到消息,执行相应的动作,但不会做任何给用户的提示。在普通的推送中我们可以通过如下的代码实现静默推送的效果:

{
  "aps" : {
    "badge" : 0
  }
}

但是苹果还是专门定义了一个开关来表示静默推送 "content-available" : 1,由于此开关优先级较低,在静默推送的报文中不能出现alert,sound 等,否则就会变成普通推送。

静默推送的payload如下:

{
  "aps" : {
    "content-available" : 1
  }
}

静默推送的前提:

  1. 只有app还在后台运行时,才能收到静默推送,否则推送了也没有用
  2. 跟普通推送类似,苹果对频率和到达性都不做保证。

参考:
How to generate a Push Notification certificate and download the Entrust Root Authority certificate

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注