iOS推送-从证书申请->移动端代码->node.js服务端代码

来源:互联网 发布:有app源码怎么生成app 编辑:程序博客网 时间:2024/06/08 07:08

    • 证书申请
      • 创建AppID
      • 从证书颁发机构请求request证书
      • 申请development证书
      • 申请Provisioning Profiles
      • 申请SSL推送证书
      • 下载已经申请的文件
    • 移动端代码
    • 服务端配置
      • 生成pem文件
      • 验证生成的pem文件是否可用
      • Nodejs代码

此教程更新于17年8月,之后可能会有变动。

此教程基于development环境,生产环境雷同。

证书申请

创建AppID

1.1 用于推送的AppID必须是确定的bundleID,不能带有通配符。
这里写图片描述

1.2 appid创建之后,push状态处于待激活状态
这里写图片描述

从证书颁发机构请求request证书

2.1 申请证书之前,必须先申请request证书

Created with Raphaël 2.1.0打开钥匙串证书助理从证书颁发机构请求证书存储到磁盘

申请development证书

3.1
这里写图片描述

3.2 此时需要上传之前申请到的request证书
这里写图片描述

申请Provisioning Profiles

4.1 绑定刚才已创建的appID
这里写图片描述

4.2 绑定刚才已申请的development证书
这里写图片描述

4.3 绑定设备,继续直到done。

申请SSL推送证书

5.1 申请此证书有两种方式

  • 1.1 选中之前创建的AppID,点击编辑按钮
    这里写图片描述
    1.2 点击下面的创建SSL证书
    这里写图片描述
    1.3 仍然需要上传request证书
    1.4 生成的SSL证书
    这里写图片描述
  • 2.1 先删除第一种方法生成的SSL推送证书。直接点击创建开发环境证书
    这里写图片描述
    2.2 选择创建SSL
    这里写图片描述
    2.3 此时比第一种方法多出的一个步骤就是绑定AppID
    这里写图片描述
    2.4 之后的步骤同第一种方法

下载已经申请的文件

6.1 下载开发证书cer文件

6.2 下载开发推送证书cer文件

6.3 下载开发Provisioning Profiles文件

6.4 下载的文件如下:
这里写图片描述

6.5 双击安装证书文件和描述文件

移动端代码

本例基于iOS10以上代码测试,实际开发中需要做出兼容。

1.1 iOS10以上SDK提供最新UNUserNotificationCenter接口,调用此接口,需提前导入#import <UserNotifications/UserNotifications.h>
1.2 代码如下:

#import "AppDelegate.h"#import <UserNotifications/UserNotifications.h>@interface AppDelegate ()<UNUserNotificationCenterDelegate>@end@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    // Override point for customization after application launch.    //消息推送注册    UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];    [center setDelegate:self];    UNAuthorizationOptions type = UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert;    [center requestAuthorizationWithOptions:type completionHandler:^(BOOL granted, NSError * _Nullable error) {        if (granted) {            DLog(@"注册成功");        }else{            DLog(@"注册失败");        }    }];    [application registerForRemoteNotifications];    return YES;}//完成注册后收到devicetoken- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {    //上传deviceToken给后台服务器    NSString *fullStr = [deviceToken description];    DLog(@"fullstr= %@",fullStr);    NSString *deviceTokenStr = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<" withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];    NSLog(@"deviceTokenStr:\n%@",deviceTokenStr);}- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {    DLog(@"注册推送失败:%@",error);}//处理通知- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {}- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {    DLog(@"接收到推送内容==%@", response.notification.request.content.userInfo);}

服务端配置

生成pem文件

1.1 服务端上传给APNS的服务器需要pem格式的文件,所以,先转换格式。
1.2 从钥匙串中导出文件

  • 导出cert.cer文件,其实就是推送证书aps_development.cer文件
    这里写图片描述
  • 导出cert.p12文件
    这里写图片描述
  • 导出key.p12文件,需要输入验证密码
    这里写图片描述

1.3 有两种可用的转换方式

  • a-1. 导出的cert.cer文件和导出的key.p12文件配对转换pem格式。转换key.p12的时候用到导出时候的密码
$ openssl x509 -in cert.cer -inform DER -outform PEM -out cert.pem$ openssl pkcs12 -in key.p12 -out key.pem -nodes//得到cert.pem和key.pem//知道 cert.cer文件其实就是之前导出的推送证书,所以用```aps_development.cer```替换```cert.cer```也是可行的。
  • a-2. 导出的cert.p12文件和导出的key.p12文件配对转换。
$ openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12$ openssl pkcs12 -nocerts -out key.pem -in key.p12//注意点:此种方法转换key.p12的时候,需要输入passphrase密码。记住此密码,在JS请求参数中需要使用。

现在得到的key.pemcert.pem文件,无论服务是NodeJS, Python还是Ruby,都可以使用。

验证生成的pem文件是否可用

2.1 终端输入如下代码:

$ openssl s_client -connect gateway.sandbox.push.apple.com:443 -cert cert.pem -key key.pem

显示如下说明可用

    Key-Arg   : None    Start Time: 1502948067    Timeout   : 300 (sec)    Verify return code: 0 (ok)

Node.js代码

3.1 首先要安装apn模块

//查看所有版本$ npm view apn versions//安装指定版本$ npm view apn@2.1.5 

3.2 js具体代码: 方式1方式2都可以实现

/// <reference path="../NodeJS/typings/index.d.ts" />"use strict"const apn = require("apn");//方式1/*let deviceToken = "f8ca917e82724992d387210c0cd7dd65381d818f6b6e8387e1fdfe9d6e77f410";var options = {    cert: "cert.pem",    key: "key.pem",    // passphrase: "123456",    production: false};var apnProvider = new apn.Provider(options);var note = new apn.Notification();// note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now. note.badge = 3;note.sound = "ping.aiff";note.alert = "You have a new message";note.payload = {'messageFrom': 'John Appleseed'};note.topic = "com.longhuiyun.ios";console.log(`sending: ${note.compile()} to ${token}`);apnProvider.send(note, deviceToken).then( result => {    console.log("sent: ", result.sent.length);    console.log("failed: ",result.failed.length);    console.log(result.failed);});apnProvider.shutdown();*///方式2/**/let tokens = ["43fe62877980297b1a1da9043fdb70246272fe635855f174d714bc1301da445a","f8ca917e82724992d387210c0cd7dd65381d818f6b6e8387e1fdfe9d6e77f410"];let service = new apn.Provider({    cert: "cert.pem",//注意填入正确的文件路径    key: "key.pem",    passphrase: "123456", //创建pem的时候确定的passphrase,需要加入    gateway: "gateway.sandbox.push.apple.com",//可忽略    port: 443 //可忽略});let note = new apn.Notification({    alert: "测试下",    sound: "ping.aiff",});note.topic = "com.longhuiyun.ios";console.log(`sending: ${note.compile()} to ${tokens}`);service.send(note, tokens).then( result => {    console.log("sent: ", result.sent.length);    console.log("failed: ",result.failed.length);    console.log(result.failed);});//关闭服务service.shutdown();

3.3 在终端中执行js文件,会看到消息发送成功

$ node apnsService.jspath=== ./key.pemsending: {"aps":{"alert":"测试下","sound":"ping.aiff"}} to 43fe62877980297b1a1da9043fdb70246272fe635855f174d714bc1301da445a,f8ca917e82724992d387210c0cd7dd65381d818f6b6e8387e1fdfe9d6e77f410sent:  2 //发送成功failed:  0[]

3.4 最后可以写个web页面,专门负责可视化信息发送

3.5 对于服务端和APNS服务端通信可能出现的错误码
这里写图片描述
此出处为苹果官方文档 具体错误可以参考。

3.6 对于apn模块的使用,具体可参考官方git

原创粉丝点击