什么是APNS?

苹果推送通知服务(APNs)是推送通知的网关,iPhone ipad 对于应用程序在后台运行有诸多限制,考虑到手机电池电量,应用不允许在后台进行过多的操作。因此,当用户切换到其他程序后,原先的程序无法保持运行状态。对于那些需要保持持续连接状态的应用程序(比如社区网络应用),将不能收到实时的信息。推送是解决轮询所造成的流量消耗和电量消耗的一个比较好的解决方案

为解决这一限制,苹果推出了APNs(苹果推送通知服务 Apple Push Notification services)。APNs 允许设备与苹果的推送通知服务器保持常连接状态。当你想发送一个推送通知给某个用户的iPhone上的应用程序时,你可以使用 APNs 发送一个推送消息给目标设备上已安装的某个应用程序。

苹果的推送服务APNs基本原理简单来说就是苹果利用自己专门的推送服务器(APNs)接收来自我们自己应用服务器的需要被推送的信息,然后推送到指定的iOS设备上,然后由设备通知到我们的应用程序,设备以通知或者声音的形式通知用户有新的消息。推送的前提是装有我们应用的设备需要向APNs服务器注册,注册成功后APNs服务器会返给我们一个device_token,拿到这个token后我们将这个token发给我们自己的应用服务器,当有需要被推送的消息时,我们的应用服务器会将消息按指定的格式打包,然后结合设备的device_token一并发给APNs服务器,由于我们的应用和APNs维持一个基于TCP的长连接,APNs将新消息推送到我们设备上,然后在屏幕上显示出新消息来。

推送流程

  • 获取设备device_token阶段

上图完成了如下步骤:

1.Device连接APNs服务器并携带设备序列号
2.连接成功,APNs经过打包和处理产生device_token并返回给注册的Device
3.Device携带获取的device_token向我们自己的应用服务器注册
4.完成需要被推送的Device在APNs服务器和我们自己的应用服务器注册

执行顺序如下所示:


这里要提到的一点是,我们的设备和APNS服务器之间的通讯是基于SSL协议的TCP流通讯,二者之间维持一个长连接,当从APNS服务器注册成功后,一定要将device_token发送给我们的应用服务器,因为在推送过程中,首相是由我们的应用服务器(上图中Provider)将需要推送的消息结合device_token按指定格式(后面会提到)打包然后发送给APNS服务器,然后由APNS服务器推送给我们的设备。

消息推送过程

推送的过程经过如下步骤:

1.首先,安装了具有推送功能的应用,我们的设备在有网络的情况下会连接苹果推送服务器,连接过程中,APNS会验证device_token,连接成功后维持一个长连接;

2.Provider(我们自己的服务器)收到需要被推送的消息并结合被推送设备的device_token一起打包发送给APNS服务器;

3.APNS服务器将推送信息推送给指定device_token的设备;

4.设备收到推送消息后通知我们的应用程序并显示和提示用户(声音、弹出框)

3.3 完整流程介绍

比较直观的流程参照下图:

应用启用推送通知功能,需要用户确认;应用收到设备识别ID(device token),相当于接收推送通知的地址;应用将设备识别ID发送到你开发的服务器;当有推送通知的需要时,你就可以通过你开发的服务组件发送信息到苹果的服务器上;苹果推送通知服务将信息推送到用户的设备上。

上图显示了我们的应用服务器将消息推送到我们的App的完整路径,其实真正完成推送的是APNS服务器,我们自己的应用服务器只是将需要推送的消息告诉苹果服务器,至于如何维护消息队列或如何保证消息能被推送到指定的设备上,这些都由苹果APNS给我们做完了

Push机制类型

四种:徽章、提示框、声音和横幅,具体表现形式如下图

  • Push机制的4个组件
  • Provider
  • APNS
  • iPhone设备
  • Client App
    其中APNS(Apple Push Notification Service)是由苹果提供的消息推送服务中心,所有的消息都经由这里转发给相应的设备

证书生成

![Uploading 19175943_bPmM_098454.jpeg . . .]

先概述下大致过程,然后下面会截图给出详细的步骤

在Mac上生成 Apple推送通知SSL许可证:

  1. 登录到 apple Developer Connection Portal 并点击 App IDs
  2. 创建一个不使用通配符的 App ID 。通配符 ID 不能用于推送通知服务。例如,我们的iPhone程序ID像这样:54im.com.PushChat
  3. 点击App ID旁的“Configure”,然后按下按钮生产 推送通知许可证。根据“向导”指导的步骤生成一个签名并上传,最后下载生成的许可证。
  4. 通过双击.cer文件将你的 aps_developer_identity.cer 引入Keychain中。
  5. 在Mac上启动 Keychain助手,然后在login keychain中选择 Certificates分类。你将看到一个可扩展选项“Apple Development Push Servicescom.54im.PushChat”
  6. 扩展此选项然后右击“Apple Development Push Services” > Export “Apple Development Push Services:com.54im.PushChat”。保存为 PushChat_cert.p12 文件。
  7. 扩展“Apple Development Push Services” 对“Private Key”做同样操作,保存为 PushChat_key.p12 文件。
  8. 需要通过终端命令将这些文件转换为PEM格式:
    openssl pkcs12 -clcerts -nokeys -out cert.pem -in PushChat_cert.p12
  9. 转换得到key的pem:
    openssl pkcs12 -nocerts -out key.pem -in PushChat_key.p12
  10. 如果你想要移除密码,要么在导出/转换时不要设定或者执行:
    openssl rsa -in key.pem -out key.unencrypted.pem
  11. 最后,你需要将键和许可文件合成为apns-dev.pem文件,此文件在连接到APNS时需要使用:
    cat apns-dev-cert.pem key.unencrypted.pem > ck.pem

5.2.2 配置详解

  1. 创建APPID

首先登陆我们的Apple Developer后台为将要使用推送服务的App新建一个App ID,如下图,点击新建后输入基本信息

APPID创建好后,我们点编辑刚刚生成好的APPID,生成下development证书,生产情况下用 Production证书

创建正式过程中,要求上传一张Certificate Signing Request 证书请求签名文件


2. 生成证书请求文件
输入证书信息

3. 生成PUSH证书

还记得刚刚苹果开发者那里要上传的证书不,将生成好的这个.certSigningRequest证书上传上去,

下载aps_development.cer这个证书到mac上,如果是发布版的推送证书,就为aps_production.cer。然后双击该证书,将推送证书安装到我们的Mac机器上,安装成功后会看到如下界面(如果是发布版,则证书的Development部分显示的是Production)

需要为certificate和它之下的private key各自export出一个.p12文件。(会出现设置密码过程)

  1. 导出公钥

导出私钥

  1. key转换

需要将上面的2个.p12文件转成.pem格式:

openssl pkcs12 -clcerts -nokeys -out cert.pem -in Push_Chat_cert.p12
openssl pkcs12 -nocerts -out key.pem -in Push_Chat_cert_key.p12

如果需要对key不进行加密
openssl rsa -in key.pem -out key.unencrypted.pem

然后就可以 合并两个.pem文件, 这个ck.pem就是服务端需要的证书了
cat cert.pem key.unencrypted.pem > apns-dev.pem

创建 Provisioning Profile

5.3 创建 provisioning profile

  1. key转换

需要将上面的2个.p12文件转成.pem格式:

openssl pkcs12 -clcerts -nokeys -out cert.pem -in Push_Chat_cert.p12
openssl pkcs12 -nocerts -out key.pem -in Push_Chat_cert_key.p12

如果需要对key不进行加密
openssl rsa -in key.pem -out key.unencrypted.pem

然后就可以 合并两个.pem文件, 这个ck.pem就是服务端需要的证书了
cat cert.pem key.unencrypted.pem > apns-dev.pem

创建 Provisioning Profile
5.3 创建 provisioning profile


将该prifiles文件下载下来,名字是PushChat.mobileprovision,其实不用下载,xcode里面会根据你的项目id自动去拉对于的这个文件

客户端制作

#import "AppDelegate.h"
@implementation AppDelegate
/**
* This is what you need to add to your applicationDidFinishLaunching
*/- (void)applicationDidFinishLaunching:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{[[UIApplication sharedApplication]registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];// Clear application badge when app launches
application.applicationIconBadgeNumber = 0;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application{
// Add registration for remote notifications[[UIApplication sharedApplication]registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];// Clear application badge when app launches
application.applicationIconBadgeNumber = 0;
}
/*
* -------------------------------------------------------
*  BEGIN APNS CODE
*/
/**
* Fetch and Format Device Token and Register Important Information to Remote Server
*/- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
#if !TARGET_IPHONE_SIMULATOR
// Get Bundle Info for Remote Registration (handy if you have more than one app)NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
// Check what Notifications the user has turned on.  We registered for all three, but they may have manually disabled some or all of them.NSUInteger rntypes = [[UIApplication  sharedApplication] enabledRemoteNotificationTypes];
// Set the defaults to disabled unless we find otherwise...
NSString *pushBadge = (rntypes & UIRemoteNotificationTypeBadge) ? @"enabled" : @"disabled";NSString *pushAlert = (rntypes & UIRemoteNotificationTypeAlert) ? @"enabled" : @"disabled";NSString *pushSound = (rntypes & UIRemoteNotificationTypeSound) ? @"enabled" : @"disabled";
// Get the users Device Model, Display Name, Unique ID, Token & Version Number
UIDevice *dev = [UIDevice currentDevice];
NSString *deviceName = dev.name;
NSString *deviceModel = dev.model;
NSString *deviceSystemVersion = dev.systemVersion;
// Prepare the Device Token for Registration (remove spaces and < >)
NSString *deviceToken = [[[[devToken description]                              stringByReplacingOccurrencesOfString:@"<"withString:@""]                          stringByReplacingOccurrencesOfString:@">" withString:@""]                          stringByReplacingOccurrencesOfString: @" " withString: @""];
// Build URL String for Registration// !!! CHANGE "www.mywebsite.com" TO YOUR WEBSITE. Leave out the http://// !!! SAMPLE: "secure.awesomeapp.com"
NSString *host = @"121.199.25.24/pushchat";
// !!! CHANGE "/apns.php?" TO THE PATH TO WHERE apns.php IS INSTALLED
// !!! ( MUST START WITH / AND END WITH ? ).
// !!! SAMPLE: "/path/to/apns.php?"
NSString *urlString = [NSString stringWithFormat:@"/apns.php?task=%@&appname=%@&appversion=%@&devicetoken=%@&devicename=%@&devicemodel=%@&deviceversion=%@&pushbadge=%@&pushalert=%@&pushsound=%@", @"register", appName,appVersion, deviceToken, deviceName, deviceModel, deviceSystemVersion, pushBadge, pushAlert, pushSound];// Register the Device Data// !!! CHANGE "http" TO "https" IF YOU ARE USING HTTPS PROTOCOLNSURL *url = [[NSURL alloc] initWithScheme:@"http" host:host path:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];[NSURLConnection sendAsynchronousRequest:requestqueue:[NSOperationQueue mainQueue]completionHandler:^(NSURLResponse *urlR, NSData *returnData, NSError *e) {NSLog(@"Return Data: %@", returnData);}];NSLog(@"Register URL: %@", url);
#endif
}
/**
* Failed to Register for Remote Notifications
*/
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
#if !TARGET_IPHONE_SIMULATORNSLog(@"Error in registration. Error: %@", error);
#endif
}
/**
* Remote Notification Received while application was open.
*/- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
#if !TARGET_IPHONE_SIMULATORNSLog(@"remote notification: %@",[userInfo description]);NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];NSString *alert = [apsInfo objectForKey:@"alert"];NSLog(@"Received Push Alert: %@", alert);
NSString *sound = [apsInfo objectForKey:@"sound"];NSLog(@"Received Push Sound: %@", sound);
//AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
NSString *badge = [apsInfo objectForKey:@"badge"];
NSLog(@"Received Push Badge: %@", badge);application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];#endif
}
/*
*  END APNS CODE
-------------------------------------------------------*/
- (void)applicationWillResignActive:(UIApplication *)application
{// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

并且修改里面的push服务器地址

NSString *host = @"api.54im.com/pushchat";

现在可以把项目编译到iphone或者ipad上面了,注意项目 General中team配置。

APNS苹果远程推送相关推荐

  1. 详解APNS苹果消息推送通知

    苹果消息通知什么? 如下图如示 就是APP的服务端在用户未打开APP进程时,还能发通知给用户APP的服务技术 相关概念 Provider:提供推送的第三方服务系统 Device:苹果设备,例如ipho ...

  2. iOS开发 - ANPs推送通知 标签: 推送通知ANPs远程推送、本地推送

    iOS开发 - ANPs推送通知 标签: 推送通知ANPs远程推送本地推送 2015-05-03 14:12 3510人阅读 评论(0) 收藏 举报 本文章已收录于:  iOS知识库  分类: [IO ...

  3. [转]iOS 远程推送(APNs)

    我是搬运工.原帖:http://blog.csdn.net/lifengzhong/article/details/7737028 目录(?)[-] 一简介 二使用步骤 step1 step2 ste ...

  4. JAVA后台对接苹果APNS(VOIP)实现推送

    最近公司需要用苹果APNs实现类似微信视频接电话的效果,查看了苹果官网有VOIP这个东西,于是进行了研究开发. 首先总结一下接入流程: 在开发者中心申请对应的证书(推送证书,VOIP证书) IOS 注 ...

  5. Go语言150行代码搞定苹果Apns高并发推送

    苹果消息推送Apns是每个apple app必须面对的坎.目前捣腾的小项目需要定时向所有用户推送消息.之前使用python第三方库pyapns实现,结果运行一段时间发现内存消耗很高,而且推送不稳定,经 ...

  6. 【苹果相册推送iMessage】群发公用推送服务器(APNS)

    推荐内容IMESSGAE相关 作者推荐内容 iMessage苹果推软件 *** 点击即可查看作者要求内容信息 作者推荐内容 1.家庭推内容 *** 点击即可查看作者要求内容信息 作者推荐内容 2.相册 ...

  7. iOS-本地推送和远程推送,常用的三方推送和常用的测试方法,推送实现和原理详解...

    什么是消息推送 举一个常见的例子,我们的手机上经常会有弹出一些信息,例如QQ信息.微信信息等等,这就是常见的消息推送. 例如: 消息推送的类型: 在屏幕顶部显示一块横幅(显示具体内容) 在屏幕中间弹出 ...

  8. 远程推送,集成极光的SDK,证书制造

    由于iOS操作系统限制,我们APP在后台不能做操作,也不能接收任何数据,所以需要用推送来接收消息. APNs服务,苹果官方网址:https://developer.apple.com/library/ ...

  9. 苹果消息推送服务教程:第一二部分(共2部分)

    苹果消息推送服务教程:第一部分(共2部分) 转自 http://www.raywenderlich.com/zh-hans/24732/苹果消息推送服务教程:第一部分(共2部分) 这是iOS教程团队的 ...

最新文章

  1. 事件——事件绑定||事件函数传参||事件修饰符||按键修饰符||自定义按键修饰符
  2. CheckStyle及其配置的详细解释
  3. python打开.data_DataX初体验-python命令启动以及纯java启动
  4. Question of the Day: Microsoft | Database, Multiple Questions in One
  5. 面试题25:合并两个排序的链表
  6. 90 行代码,15 个元素教你如何实现无限滚动!
  7. Git常用指令的使用
  8. 在java创建线程结果_Java创建线程的三种方式
  9. QT重装系统后的程序异常处理与Windows奔溃导致无法开机的资料备份
  10. UART协议就应该这么理解
  11. Young不等式的一个新证明
  12. 软件测试实习面试都问啥?
  13. 阿里妈妈展示广告引擎新探索:迈向全局最优算力分配
  14. word文档中表格计算机功能在哪,word文档筛选功能在哪里
  15. u检验和t检验区别与联系
  16. c-lodop自定义分页打印
  17. ad怎么修改栅格_AD 10怎么设置栅格?
  18. 罗丹明PEG罗丹明,RB-PEG-RB
  19. python数据分析前景如何_数据分析师的前景怎么样?
  20. aix查看lv_AIX中的硬盘、PP、VG、LV、文件系统

热门文章

  1. 管段超声波流量计大口径
  2. Unity使用Mesh Simplify 减面(网格简化)
  3. ETL讲解,到底什么是ETL
  4. 使用Android Studio 3.2编译android-serialport-api JNI
  5. mysql5.7与8.0密码加密方式
  6. [附源码]PHP计算机毕业设计旅游网站设计(程序+LW)
  7. 鸿蒙系统上市时间未定,为啥华为会说鸿蒙上市时间未定,并表示很支持安卓,原因很简单...
  8. 图书管理系统php心得500,500内部服务器错误是
  9. html当中如何引用js文件
  10. 深度学习基础--不同网络种类--反馈深度网络(feed-back deep networks, FBDN)