首先简单说下iOS APNS:

Apple 使用公共密钥数字证书对来自 iOS应用程序的推送请求进行身份验证,所以您首先需要创建身份验证密钥,并向 Apple注册它们。我将在下一节中花相当长的篇幅来直接介绍这一点。

接下来,需要确定安装该应用程序并选择接收该应用程序的推送通知的每台设备。工作顺序如下:

1.iOS 应用程序中的一个警告对话框会请求用户的许可,以接收推送通知。

2.如果用户授予权限,iOS应用程序会联系 Apple Push Notification服务 (APNs)获得一个 ID字符串,以惟一地标识在此设备上安装的这个应用程序。(您可以将 ID看作类似于传统消息场景中的收件人电话号码)。

3.iOS 应用程序将 ID上传到您的服务器应用程序。

4.当服务器应用程序需要发送推送消息时,它对 Apple 的推送服务器进行身份验证,然后使用从步骤2和 3中获得的 ID指定消息的收件人。

如果收件人设备在线,它接收并处理消息。如果设备离线,那么消息将会排队,然后当设备下一次在线时交付。

APNS也使您的服务器应用程序可以定期验证您所保存的应用程序 ID列表。这使您有机会删除那些在后来删除应用程序或修改其推送选择状态的用户和 ID。

请求和保存设备令牌

您的 iOS 应用程序需要请求用户许可,在它所安装的设备上接收推送通知。通常情况下,您可以通过一个简单的 API调用在应用程序代理中实现这一点,如下:

[html] view plain copy
  1. [[UIApplication sharedApplication]
  2. registerForRemoteNotificationTypes:
  3. (UIRemoteNotificationTypeBadge |
  4. UIRemoteNotificationTypeSound |
  5. UIRemoteNotificationTypeAlert)];

如果用户授予许可,应用程序会自动联系 APNS 服务器获取设备令牌。令牌使APNS可以将该特定设备上所安装的这个特定应用程序识别为一个消息目的地。这个过程是自动的,并且在后台执行。您不需要为它编写任何代码。

在 APNS 服务器响应后,应用程序代理中的 didRegisterForRemoteNotificationsWithDeviceToken方法被调用,并将设备令牌作为一个调用参数传递进来。您必须保存设备令牌并将它上传到自己的推送通知服务器,如下:

[html] view plain copy
  1. - (void)application:(UIApplication*)application
  2. didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
  3. NSString *tokenStr = [deviceToken description];
  4. NSString *pushToken = [[[[tokenStr
  5. stringByReplacingOccurrencesOfString:@"<" withString:@""]
  6. stringByReplacingOccurrencesOfString:@">" withString:@""]
  7. stringByReplacingOccurrencesOfString:@" " withString:@""] retain];
  8. // Save the token to server
  9. NSString *urlStr = [NSString stringWithFormat:@"https://%@/push_token", RINGFULDOMAIN];
  10. NSURL *url = [NSURL URLWithString:urlStr];
  11. NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
  12. [req setHTTPMethod:@"POST"];
  13. [req setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
  14. NSMutableData *postBody = [NSMutableData data];
  15. [postBody appendData:[[NSString stringWithFormat:@"username=%@", username]
  16. dataUsingEncoding:NSUTF8StringEncoding]];
  17. [postBody appendData:[[NSString stringWithFormat:@"&token=%@",
  18. pushToken] dataUsingEncoding:NSUTF8StringEncoding]];
  19. [req setHTTPBody:postBody];
  20. [[NSURLConnection alloc] initWithRequest:req delegate:nil];
  21. }

在理想情况下,您将令牌与一些标记用户的信息(如在您的系统中的个人用户名)相关联,使您的服务器知道稍后要将消息发送给谁。(您可以将它想像为类似于将电话号码与个人姓名相关联。)如果您没有将令牌与自己的用户标识信息关联,您仍然可以将消息发送到这些设备,但您不能为每个用户自定义消息,因为您所拥有的是一个目标设备的字母令牌字符串。

服务器应该将令牌及其相关的标识信息保存在数据库中。在大多数应用程序中,它被保存在用户配置文件数据库中。

发送一个推送消息

要发送一个推送消息,您的服务器要查找即将发送消息的目标应用程序 ID 列表,根据收件人的用户配置文件为每个收件人个性化消息

联系 APNS 消息服务器,APNS 服务器的 Web服务 API很复杂。对 Java开发人员来说幸运的是,开源 JavaPNS库可以使其使用变得更简单。JavaPNS和下载和文档链接参见参考资料。下面代码显示了如何使用 JavaPNS 库向设备发送类似于短信的消息:

[html] view plain copy
  1. String[] devices = {"token1", "token2};
  2. List<PushedNotification> notifications
  3. = Push.alert("Hello World!", "keypair.p12", "password", false, devices);

JavaPNS 库的主界面方法是在 Push类中的静态方法。APNS允许您在消息中嵌入各种内容。请参阅 iOS推送消息指南,获取所支持的负载类型的完整清单(参见参考资料)。Push类为每种类型的消息提供方便的方法,并且它将消息的转换为APNS 服务器接受的 JavaScript Object Notation (JSON)格式。在清单3中,keypair.p12 是从 KeyChain Access导出的 p12文件,password是 p12文件的密码。devices阵列是从 iOS应用程序接收的设备令牌列表。所有这些设备都将收到这个推送消息。在参数中的false值指定该消息应发送到APNS 开发服务器(沙箱),而不是其生产服务器。(回忆一下,您通常为沙箱创建一个 p12密钥对,为生产服务器创建一个不同的密钥对。)

方法调用返回的值是一个 PushedNotification对象的列表,您可以用它来确定推送交付的状态,如图所示:

[html] view plain copy
  1. for (PushedNotification notification : notifications) {
  2. if (notification.isSuccessful()) {
  3. /* Apple accepted the notification and should deliver it */
  4. } else {
  5. String invalidToken = notification.getDevice().getToken();
  6. /* Add code here to remove invalidToken from your database */
  7. }
  8. }

如果通知对象告诉您,有某个设备令牌不再处于激活状态,例如,如果用户从设备中删除了该应用程序,或在应用程序设置中禁用了通知,您应该从数据库中删除该令牌,以便您不会再向它发送消息。

保持最新的活动设备令牌列表的另一种方式,是让您的服务器应用程序定期检查APNS服务器。清单5显示了如何查询APNS 反馈服务,使用 JavaPNS从APNS 沙箱接收一个无效设备令牌的列表:

[html] view plain copy
  1. <?php
  2. //feedback.php
  3. $ctx = stream_context_create();
  4. stream_context_set_option($ctx, 'ssl', 'local_cert', 'server_certificates_bundle.pem');
  5. stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
  6. // assume the private key passphase was removed.
  7. // stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
  8. $fp = stream_socket_client('ssl://feedback.push.apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT, $ctx);
  9. // Development server is ssl://feedback.sandbox.push.apple.com:2196
  10. if (!$fp) {
  11. print "Failed to connect feedback server: $err $errstr\n";
  12. return;
  13. }
  14. else {
  15. print "Connection to feedback server OK\n";
  16. }
  17. print "APNS feedback results\n";
  18. while ($devcon = fread($fp, 38))
  19. {
  20. $arr = unpack("H*", $devcon);
  21. $rawhex = trim(implode("", $arr));
  22. $feedbackTime = hexdec(substr($rawhex, 0, 8));
  23. $feedbackDate = date('Y-m-d H:i', $feedbackTime);
  24. $feedbackLen = hexdec(substr($rawhex, 8, 4));
  25. $feedbackDeviceToken = substr($rawhex, 12, 64);
  26. print "TIMESTAMP:" . $feedbackDate . "\n";
  27. print "DEVICE ID:" . $feedbackDeviceToken. "\n\n";
  28. }
  29. fclose($fp);
  30. ?>
  31. ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<span style="font-family: Menlo; ">    </span>

  可能是要先给已经删除了应用的设备发送push,apple才会认为此token无效,此时再访问feedback才能正确获取无效的token列表,否则可能为空。不要将资源浪费在将消息发送到已删除您的应用程序的设备,或选择不接收通知的设备,这一点很重要。

  其他考虑事项

推送通知不能在 iOS模拟器上进行测试;您必须将应用程序部署到实际设备上对其进行测试。因为用于对消息进行身份验证的数字证书被捆绑到应用程序的配置概要文件,您需要使用在开发或临时分发应用程序中的开发证书进行测试。在应用程序通过审批并在 App Store中提供后,您必须切换到生产证书。

此外,重要的是要理解,为大数据库中的用户定制和发送推送消息是一项资源密集型工作。例如,每5秒遍历一次一个百万用户级的数据库,以确定 10个当时需要收到消息的用户,这成本非常高。服务器端的基础架构需要精心的设计和规划,以支持对大量用户的频繁推送通知。相反,一次向一百万个用户发送推送消息会产生大量的流量,因此通过使用一个线程池可以更好地处理这一场景,而不是阻止一个单独线程。JavaPNS库提供一个简单的 API,它使用线程池,可以同时将消息推送给大量设备。

结束语

推送技术让您的服务器应用程序绕过电信运营商,并直接通过 Internet向 iOS设备的应用程序发送消息。虽然实现推送通知并非小事(客户端 SSL证书对 Apple服务器的身份验证需求很复杂),但是来自 Urban Airship和 JavaPNS等第三方的帮助可以使发送通知更加容易。SMS和 MMS有自己的位置,并且仍然比推送技术更可靠,但您可以通过实现推送消息使您的 iOS应用程序更加丰富,提供更多的功能。

细说feedback客户服务器

如果供应商试图推送通知给应用程序,但应用程序不再存在于设备,该设备反馈一个报告给苹果推送通知服务器。这种情况经常发生在用户卸载应用程序。如果设备报告失败的传递尝试的应用程序的APN需要一些方法来通知供应商,以便它能够避免将通知发送给该设备。这样做可以减少不必要的报文开销,提高了系统的整体性能。

为了这个目的,苹果推送通知服务为每一个应用程序建立了一个feedback的APN不断更新列表中的设备的服务。设备标识以设备令牌二进制编码格式被识别。供应商应定期查询反馈服务器来确定他们的应用列表中的设备令牌。然后,经核实该应用程序已没有注册接受APNS应停止将通知发送给这些设备。

访问的反馈服务是通过二进制接口与用于发送推送通知您的生产反馈服务访问端口2196通过feedback.push.apple.com,类似;您访问沙箱反馈通过feedback.sandbox.push服务apple.com,端口2196。推送通知的二进制接口,你必须使用TLS(SSL)建立一个安全的通信通道的SSL证书,需要为这些连接的是同一个置备发送通知。要建立一个值得信赖的供应商的身份,你应该出示该证书的APN在连接时使用对等验证。

一旦你连接,传输立即开始,你不需要发送任何命令的APN开始读取流书面反馈服务,直到有没有更多的数据读取接收到的数据是在具有下列格式的元组:

Timestamp:自1970年以来,固定在UTC时间戳(一个四字节time_t的值),表示在APN时,决定不再存在于设备中的应用。这个值,这是网络顺序,代表秒。您应该使用时间戳来确定,如果应用程序在设备上重新注册的设备令牌的那一刻起录得的反馈服务与您的服务,如果没有的话,你应该停止的设备发送推送通知。

Token length:长度为两个字节的整数值,以网络顺序的设备令牌。

Device token:设备令牌是二进制编码。

在检查反馈服务,不从设备上是不存在的应用程序发送推送通知的APN显示器供应商的辛勤工作。

参考文章:http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW3

iOS如何让APP删除后不接受APNS推送消息相关推荐

  1. iOS 如何让APP 删除后不接受 APNS 推送消息

    首先简单说下iOS APNS: Apple 使用公共密钥数字证书对来自 iOS应用程序的推送请求进行身份验证,所以您首先需要创建身份验证密钥,并向 Apple注册它们.我将在下一节中花相当长的篇幅来直 ...

  2. ios 消息服务器,关于IOS APNS推送消息(iphone端+服务端)

    这两天,项目要求做个推送功能,研究了一天,在此跟各位分享下.因为之前做了一年的php,所以服务端我自己写的,php语言. 1:请求证书,APPID各种繁琐的操作,我就不多话了,我也是看网上例子的. h ...

  3. ios 之apns推送

    每次看到iOS的远程消息推送,总是感觉很头大,即便后来项目都做完了,还是觉得摸不着远程推送的脉门,网上介绍的资料虽多,但不是写的太简单了,就是写的太详细了,不能一下抓住要点,今天终于能够抽出点时间,来 ...

  4. Android,ios,安卓app推送消息通知,java后台向手机推送app的通知教程

    文章目录 一.业务介绍 1.1 产品简介 1.2 名词解释 1.3 消息推送流程 二.应用创建 三.客户端 SDK 集成 3.1 Android 3.2 iOS 四.服务端推送 4.1 服务端消息下发 ...

  5. iOS 推送,删除指定推送消息或者撤回某条推送

    iOS 推送,删除指定推送消息 远程推送经常会出现收到重复推送的问题,或者想删除某条推送消息的问题,本文将详细说明 静默推送 在 iOS10 之后 Apple 新增了静默推送的功能,使 App 可以在 ...

  6. iOS 当APP接收到推送消息时,对推送消息进行处理

    结合最近做的项目来总结一下,在我们接收到推送通知后我们将要怎么处理这条推送消息,也为以后再做相关推送的时候能够更快处理. 首先要说明两个概念:本地通知和远程推送.本地通知是由本地应用触发的,接收会比较 ...

  7. ios极光推送 App收到推送消息时,修改BadgeNumber,同时点击状态栏消息以后跳到指定的页面和静默推送

    极光推送生产环境测试需要打包为adhot或者用testflight 在收到远程推送的消息的时候,有以下三种情况需要考虑: 1. 程序在后台运行 2. 程序未运行 3. 程序运行在前台 原则上,应用在收 ...

  8. 极光推送:java后台向APP推送消息(android,ios极光推送消息)

    Maven添加依赖 <!--极光推送--><dependency><groupId>cn.jpush.api</groupId><artifact ...

  9. 极光推送:后台向APP:android,ios极光推送消息

    1. 添加依赖 //jpushcompile group: 'cn.jpush.api', name: 'jpush-client', version: '3.3.4' 2. 注册极光用户 //APP ...

最新文章

  1. SQL Server 自动增长清零
  2. (转)男人的真?。。。
  3. python正则匹配_Python正则表达式初识(五)
  4. 初步了解Linux内核中断初始化
  5. win10安装ensp启动40_acer e5-475g笔记本如何安装win10系统【图文教程】
  6. 解析Vue.js中的computed工作原理
  7. python自动化办公知识点整理汇总_Python自动化办公知识点整理汇总
  8. GIT — 使用回顾
  9. LeetCode 433. 最小基因变化(广度优先搜索)
  10. python之多并发socket
  11. 【GYM-100889 C】Chunin Exam【左右手路径问题】
  12. sns分享 jia.js的使用 jiathis插件
  13. 如何共享OneNote笔记本
  14. 用python计算偏导数
  15. 【虾神白话空间统计】笔记:置信度、零假设、PZ值、随机分布
  16. 洛谷p1282多米诺骨牌
  17. 计算机 蓝牙鼠标卡顿,无线鼠标卡顿不流畅是什么原因_无线鼠标卡顿不流畅的处理方法...
  18. Web网站架构演变历程
  19. 转行程序员日记---2020-10-12【不是孤独一人】
  20. 年轻人的第一个桌面应用

热门文章

  1. vue中使用ECharts实现折线图和饼图
  2. 程序猿推送利器:使用Python+Server酱打造微信通知推送利器
  3. Java Cache 缓存方案详解及代码-Ehcache
  4. python求上α分位点_什么是标准正态分布的上α分位点以及怎样求?
  5. 基金从业考试一般要准备多长时间?
  6. 【音视频技术】AVC H264的一些基本概念和知识点
  7. 联想电脑快捷键的使用和通用设置
  8. Linux中磁盘读写速度测试
  9. 关于如何在空间中建立直角坐标系
  10. c语言经典笔试100题,100条经典C语言笔试题目(全).doc