IOS推送通知开发流程
最近开发IOS的推送通知,现把流程及遇到的问题整理一下:
一、证书的准备工作
1.在开发电脑MAC上申请证书
打开钥匙串访问
选择从证书颁发机构请求证书
这里的邮箱账号写你自己的,常用名称可以随便写
选择存储到磁盘
这里最好新建一个文件夹 用来专门存储这些文件
2、在苹果开发平台生成开发证书或者生产证书
登录开发者账号
https://idmsa.apple.com/IDMSWebAuth/login?appIdKey=891bd3417a7776362562d2197f89480a8547b108fd934911bcbea0110d07f757&path=%2Faccount%2F&rv=1
选择Development 点击'+'按钮新增,我这里有证书在试用中
Development下面有两个选项 第一个是不带Push Notification,如果你选的是这个那你后期需要使用推送的时候,修改即可;第二种是带有Push Notification,所以我们选择第二个即可;页面下方点击continue
这里要注意,如果你在上一步选择的是没有Push Notification的,就不会出现下面这个页面;这个页面是要求你选择APP ID;
这里一定要看清楚,不要选错了,否则到时候推送通知推送不了,就是证书不匹配的问题
continue;
continue;
这里选择我们第一步到处的证书申请文件:CertificateSigningRequest.certSigningRequest
continue;
最后点击下载,下载完成以后双击安装该证书到钥匙串当中,一样的这个文件不能乱放等下会用到的,同csr文件放在一个目录中最好;这里需要在xcode 更换一下开发证书
3、导出开发证书格式为p12个人信息交换
展开开发证书,右击菜单选择导出
证书名字这里存储为Push,存储位置与上面一样;文件格式一定要p12
点击存储
这里需要输入证书的验证密码 这里就设置简单点:123456
到这里我们需要的文件都已经齐了,因为这个证书是新的证书,还需要修改一下描述文件
在开发平台 选择Provisioning Profiles,点击 Development,选择Edit;这里你选择的栏目必须是你项目中的APP ID,不要弄错了
在选择Certificates选择刚刚新建的开发证书 注意APP ID
点击Generate
将该描述文件下载下来,这个你可以放在其他位置,不用存放在上面的目录;
打开xcode打开项目替换一下描述文件即可
4.处理证书
进入终端,我这里是获取了root权限了
进入上面的目录
生成一个PushChatCert.pem文件
openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
把私钥Push.p12文件转化为.pem文件:
openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
对生成的这两个pem文件再生成一个p12文件,来把证书和私钥整合到一个文件里:
openssl pkcs12 -export -in PushChatCert.pem -inkey PushChatKey.pem -certfile CertificateSigningRequest.certSigningRequest -name "aps_developer_identity" -out aps_developer_identity.p12
注意在这里有可能会报错,我这里是有错误:
命令行提示unable to load certificates
删除 -certfile CertificateSigningRequest.certSigningRequest,再次执行命令,需要你输入之前在钥匙串导出p12文件设置的密码
最后成功生成文件aps_developer_identity.p12
5.打开xcode项目,添加Push Notification代码
在AppDelegate.m中添加一下代码:
- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{……//消息推送注册if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {//iOS 10 laterUNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];//必须写代理,不然无法监听通知的接收与点击事件center.delegate = self;[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {if (!error && granted) {//用户点击允许NSLog(@"注册成功");}else{//用户点击不允许NSLog(@"注册失败");}}];// 可以通过 getNotificationSettingsWithCompletionHandler 获取权限设置//之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改![center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {NSLog(@"========%@",settings);}];[application registerForRemoteNotifications];}else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){//iOS 8 - iOS 10系统//UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];//[application registerUserNotificationSettings:settings];[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettingssettingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)categories:nil]];[application registerForRemoteNotifications];}else{//iOS 8.0系统以下[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];}NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];[userDefaults setObject:@"" forKey:@"token"];return YES;}- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {NSString *token = [NSString stringWithFormat:@"%@", deviceToken];//获取终端设备标识,这个标识需要通过接口发送到服务器端,服务器端推送消息到APNS时需要知道终端的标识,APNS通过注册的终端标识找到终端设备。NSLog(@"My token is:%@", token);NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];[userDefaults setObject:token forKey:@"token"];}- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{// 处理推送消息NSLog(@"userinfo:%@",userInfo);NSLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);}- (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error {NSLog(@"Registfail%@",error); }
五、服务端添加javapns代码
将第3步生成的p12文件传送到服务端,我是在windows下测试的,
String certificatePath = "D:/aps_developer_identity.p12";
public class IOSBgNotice {private static final Logger log = LogManager.getLogger(IOSBgNotice.class);public static String certificatePath = "";public static void notice(String deviceToken, String alert, int badge) {/************************************************测试的服务器地址:gateway.sandbox.push.apple.com /端口2195产品推送服务器地址:gateway.push.apple.com / 2195***************************************************///为了兼容开发测试 所以推送需要发送两次sendNotice(deviceToken, alert, badge, "gateway.sandbox.push.apple.com");//developersendNotice(deviceToken, alert, badge, "gateway.push.apple.com");//distribution}private static void sendNotice(String deviceToken, String alert, int badge, String host) {try {deviceToken = deviceToken.replaceAll(" ", "");PushNotificationPayload payload = new PushNotificationPayload();payload.addAlert(alert);//push的内容payload.addBadge(badge);//图标小红圈的数值payload.addSound("default");//铃音PushNotificationManager pushManager = new PushNotificationManager();pushManager.addDevice("iPhone", deviceToken);//Connect to APNsint port = 2195;String certificatePath = "D:/aps_developer_identity.p12";//导出的证书String certificatePassword = "123456";//此处注意导出的证书密码不能为空因为空密码会报错
// pushManager.initializeConnection(host,port, certificatePath,certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, certificatePassword, "PKCS12", host, port));List<PushedNotification> notifications = new ArrayList<PushedNotification>();// 开始推送消息// Send PushDevice client = pushManager.getDevice("iPhone");log.debug("推送消息: " + client.getToken() + "\n" + payload.toString() + " ");PushedNotification notification = pushManager.sendNotification(client, payload);notifications.add(notification);List<PushedNotification> failedNotification = PushedNotification.findFailedNotifications(notifications);List<PushedNotification> successfulNotification = PushedNotification.findSuccessfulNotifications(notifications);int failed = failedNotification.size();int successful = successfulNotification.size();log.debug("功数:" + successful);log.debug("失败数:" + failed);pushManager.stopConnection();pushManager.removeDevice("iPhone");log.debug("消息推送完毕");} catch (Exception e) {e.printStackTrace();}}}
我这里发送两次是因为代码打包以后,生成服务器也会使用
6、测试
IOS需要在真机上测试,因为要获取token
运行代码以后,手机上收到推送通知
最重要的就是p12文件的制作,最开始在测试的时候一直报下面的异常:
javax.net.ssl.SSLException: Received fatal alert: internal_error
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1991)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1104)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at java.io.OutputStream.write(OutputStream.java:75)
at Push_1.main(Push_1.java:62)
出现这种情况,有两种原因:
第一、你IOS打包时的环境和p12证书不匹配,有可能你导出的时候不仔细,用的是生产的证书:
gateway.sandbox.push.apple.com
第二、Push Notification时,如果是开发环境就要使用开发苹果的开发服务器去推送;如果是生产环境就要使用生产服务器去推送:
gateway.push.apple.com
一定要注意这两点,必须要匹配才行
其他链接:
https://segmentfault.com/q/1010000000452323
https://blog.csdn.net/showhilllee/article/details/8631734
IOS推送通知开发流程相关推荐
- iOS 推送通知详解
这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了视频讲解.本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义. 介绍一点点背景资料 ...
- “iOS 推送通知”详解:从创建到设置到运行
"iOS 推送通知"详解:从创建到设置到运行 转自 http://www.csdn.net/article/2012-02-18/311976 这是一篇编译的文章,内容均出自Par ...
- iOS 推送通知及推送扩展
概述 iOS中的通知包括本地推送通知和远程推送通知,两者在iOS系统中都可以通过弹出横幅的形式来提醒用户,点击横幅会打开应用.在iOS 10及之后版本的系统中,还支持通知扩展功能(UNNotifica ...
- 智能分析网关微信端告警消息推送的开发流程
智能分析网关是TSINGSEE青犀视频研发的AI边缘计算智能硬件设备,它具有AI智能检测与识别的能力,可对视频及图像中的人.车.物体.行为等进行检测识别与定位.追踪.统计,具体可包括人脸检测与识别.车 ...
- ios推送通知之ios推送证书的申请和使用配置
很多人初次接触推送通知,不知道怎么去申请ios推送证书和配置推送. 很多人犯的错误就是用推送证书p12去打包ipa,推送不是用来打包的,下面详细介绍ios推证书的申请和配置使用. ios推送证书分为测 ...
- IOS推送通知的实现步骤
推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说来,当要显示消息或下载数据的时候, ...
- iOS 推送通知授权请求优化
觉得一篇不错的文章,简单翻译了一下. 原文地址 作者博客首页 推送通知是再次吸引用户打开app的一个重要手段.与直接打开app相比,用户更倾向于通过通知直接进入app丰富多彩的功能,所以不管是安卓用户 ...
- iOS 推送通知的样式总结
推送通知 推送通知的作用 推送通知的呈现效果 推送通知的呈现效果总结 推送通知的呈现效果设置 1. 推送通知 注意:这里说的推送通知跟NSNotification有所区别 NSNotification ...
- iOS 推送通知 客户端实现
关于推送,已经有很多文章了,我写一下自己在做推送时候的一些个人理解,对于如何取证书还有服务器实现网上有现成代码,不在累述.如果有说的不对的地方,希望大家指正. 首先: -(BOOL)applicati ...
最新文章
- Real World Haskell 第七章 I/O
- mysql源码学习 vc项目解决方案文件_Mysql源码学习——源码目录结构
- oracle存储过程和job
- golang MySQL 占内存_golang操作mysql使用总结
- TNNLS 22|分数不是关键,排名才是关键:针对排行榜的模型“行为”保持与灾难性遗忘的克服...
- NSThread使用总结
- 17秋 软件工程 团队第五次作业 Alpha Scrum2
- 循环计数_FOR 循环
- 块级元素行内元素内联元素
- bootstrape常用标签_bootstrap 常用data
- python实现bt下载器_Python 实现自动获取种子磁力链接方式
- Win11的文件资源管理器如何显示预览窗格?
- 机器学习深度神经网络——实验报告
- 新西兰 计算机 转专业,新西兰留学后如何转学转专业?
- 怎样取消php加密mppe,PHP 加密问题 求大神帮忙? 谢谢
- c++控制台版 俄罗斯方块 闪瞎眼
- leetcode 174:地下城游戏
- flstudio软件怎么设置中文语言切换?
- Git 报错:The ECDSA host key for gitlab.xx.net has changed, and the key for the corresponding.......
- python检索用人名查电话_ldap3 python搜索组成员并检索其sAMAcountName(Active Directory)...