之前在消息推送中间件APush里实现了对APNS的桥接。并利用业余时间阅读了官方指南Local and Push Notification Programming Guide。蛮有心得的。稍作总结。分享给大家,希望可以喜欢。欢迎留言讨论!

1.  APNS 通道环境

作为一个黑盒的消息推送服务。APNS为我们提供了开发和产品两套环境。这两套环境除了Host name不同外,授权证书也不近同样(证书里面会包括APP相关信息。如application bundle ID,在你创建不同的profile的时候,这些信息会自己主动加入进去)。当然Device Token也不同。以下的英文或许能更好地描写叙述这两套环境的不同:

Development: Use the development environment for initial development and testing of the provider application. It provides the same set of services as the production environment, although with a smaller number of server units. The development
environment also acts as a virtual device, enabling simulated end-to-end testing.You access the development environment atgateway.sandbox.push.apple.com , outbound TCP port 2195.

Production: Use the production environment when building the production version of the provider application. Applications using the production environment must meet Apple’s reliability requirements.You access the production environment atgateway.push.apple.com
, outbound TCP port 2195.

2.  APNS 消息格式

APNS 採用二进制消息协议,例如以下:

看官方的解释,蛮清晰的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ2ppYTEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

注意:

假设APNS成功接收到你的消息,它将什么也不返回;

假设你send a notification that is malformed or otherwise unintelligible, APNs returns an error-response packet and closes the connection. Any notifications that you sent after the malformed notification using the same connection are discarded, and must
be resent. 这点要格外重要,所以非常多开源工具包,例如说pushy提供了一个FailedConnectionListener,你能够通过实现该接口,方便的实现resent,代码片段例如以下:

private class MyFailedConnectionListener implements FailedConnectionListener<SimpleApnsPushNotification> {

    public void handleFailedConnection(
final PushManager<? extends SimpleApnsPushNotification> pushManager,
final Throwable cause) { if (cause instanceof SSLHandshakeException) {
// This is probably a permanent failure, and we should shut down
// the PushManager.
}
}
} // ... pushManager.registerFailedConnectionListener(new MyFailedConnectionListener());

error-response packet 结构例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ2ppYTEw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

Status code 解释例如以下:

  

A status code of 10 indicates that the APNs server closed the connection (for example, to perform maintenance).The notification identifier in the error response indicates the last notification that was successfully sent. Any notifications you sent
after it have been discarded and must be resent. When you receive this status code, stop using this connection and open a new connection.

3.  APNS 消息接收

An application must register with Apple Push Notification service for the operating systems on a device and on a computer to receive remote notifications sent by the application’s provider. Registration has three stages:

3.1 The app registers for remote notifications.



 3.2 The system sets up remote notifications for the app and, if registration is successful, passes a device token to the app delegate.



 3.3 The app sends its device token to the push provider.



 3.4 Device tokens can change. Your app needs to reregister every time it is launched—in iOS by calling the registerForRemoteNotificationTypes: method of UIApplication, and in OS X by calling the registerForRemoteNotificationTypes: method of NSApplication.



 3.5 Because the only notification type supported for non-running applications is icon-badging,pass NSRemoteNotificationTypeBadge as the parameter of registerForRemoteNotificationTypes:.



 3.6 If registration is successful, APNs returns a device token to the device and iOS passes the token to the app delegate in the application:didRegisterForRemoteNotificationsWithDeviceToken: method. If there is a problem in obtaining the token, the operating
system informs the delegate by calling the application:didFailToRegisterForRemoteNotificationsWithError: method.

用一幅图来说明这个流程。例如以下:

4.  APNS Qos

Apple Push Notification service includes a default Quality of Service (QoS) component that performs a store-and-forward function.

    If APNs attempts to deliver a notification but the device is offline, the notification is stored for a limited period of time, and delivered to the device when it becomes available.

    Only one recent notification for a particular application is stored. If multiple notifications are sent while the device is offline, each new notification causes the prior notification to be discarded. This behavior of keeping only the newest notification
is referred to as coalescing notifications.

    If the device remains offline for a long time, any notifications that were being stored for it are discarded.

注意我字体标黑的这个APNS的特性!

5.  APNS  FAQ

a. APNS feedback 服务是用来做什么的?

The Apple Push Notification Service includes a feedback service to give you information about failed push notifications. When a push notification cannot be delivered because the intended app does not exist on the device, the feedback service adds that
device’s token to its list. Push notifications that expire before being delivered are not considered a failed delivery and don’t impact the feedback service. By using this information to stop sending push notifications that will fail to be delivered, you reduce
unnecessary message overhead and improve overall system performance.

      Query the feedback service daily to get the list of device tokens. Use the timestamp to verify that the device tokens haven’t been reregistered since the feedback entry was generated. For each device that has not been reregistered, stop sending notifications.
APNs monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices.    

      The feedback service maintains a separate list for each push topic. If you have multiple apps, you must connect to the feedback service once for each app, using the corresponding certificate, in order to receive all feedback.

      The feedback service has a binary interface similar to the interface used for sending push notifications. You access the production feedback service via feedback.push.apple.com on port 2196 and the development feedback service via feedback.sandbox.push.apple.com
on port 2196. As with the binary interface for push notifications, use TLS (or SSL) to establish a secured communications channel. You use the same SSL certificate for connecting to the feedback service as you use for sending notifications. To establish a
trusted provider identity, present this certificate to APNs at connection time using peer-to-peer authentication.

Once you are connected, transmission begins immediately; you do not need to send any command to APNs.Read the stream from the feedback service until there is no more data to read.

The feedback service’s list is cleared after you read it. Each time you connect to the feedback service, the information it returns lists only the failures that have happened since you last connected.

b. Best Practices for Managing Connections

You may establish multiple connections to the same gateway or to multiple gateway instances. If you need to send a large number of push notifications, spread them out over connections to several different gateways.This improves performance compared
to using a single connection: it lets you send the push notifications faster, and it lets APNs deliver them faster.

       Keep your connections with APNs open across multiple notifications; don’t repeatedly open and close connections. APNs treats rapid connection and disconnection as a denial-of-service attack. You should leave a connection open unless you know it will
be idle for an extended period of time—for example, if you only send notifications to your users once a day it is ok to use a new connection each day.

c. 接收到APNS消息后。我一般怎么处理呢?

If your app is frontmost, the application:didReceiveRemoteNotification: or application:didReceiveLocalNotification:method is called on its app delegate;

    If your app is not frontmost or not running, you handle the notifications by checking the options dictionary passed to the application:didFinishLaunchingWithOptions: of your app delegate for either the UIApplicationLaunchOptionsLocalNotificationKey or UIApplicationLaunchOptionsRemoteNotificationKey
key.



    实例代码例如以下:

 (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// 取得 APNs 标准信息内容
NSDictionary *aps = [userInfo valueForKey:@"aps"];
NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; //badge数量
NSString *sound = [aps valueForKey:@"sound"]; //播放的声音 // 取得自己定义字段内容
NSString *customizeField1 = [userInfo valueForKey:@"customizeField1"]; //自己定义參数,key是自己定义的
NSLog(@"content =[%@], badge=[%d], sound=[%@], customize field =[%@]",content,badge,sound,customizeField1); // Required
[APService handleRemoteNotification:userInfo];
} //iOS 7 Remote Notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSLog(@"this is iOS7 Remote Notification"); // Required
[APService handleRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNoData);
}

d.  消息发送过程中,突然出现Write failed: Broken pipe

可能由于某种原因,如发送了错误的token,导致Apple强行关闭了SSL连接。

跳过最后一次发送的信息,又一次连接,继续发送错误信息之后的信息。

e.  由于APNS发送成功没有不论什么返回,会不会出现是异常可是异常信息还没返回的现象

有可能,这个时候能够採取批量发送,等候一段时间。例如说1秒。通过Feedback来检查发送状态。

f.   一些你可能会忽视的细节:

Each application on a device is limited to 64 scheduled local notifications. The system discards scheduled notifications in excess of this limit, keeping only the 64 notifications that will fire the soonest. Recurring notifications are treated as a
single notification.

Custom sounds must be under 30 seconds when played. If a custom sound is over that limit, the default system sound is played instead.

參考文献:

1. Local and Push Notification Programming Guide

2. http://www.easyapns.com/apple-delegate

3. http://blog.csdn.net/tlq1988/article/details/9612237

4. http://www.cocoachina.com/bbs/read.php?tid=98797

APNS 那些事!的更多相关文章

  1. .NET向APNS苹果消息推送通知

    一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...

  2. 生成php所需要的APNS Service pem证书的步骤

    1.登录到 iPhone Developer Connection Portal 并点击 App IDs 2.创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,我们的i ...

  3. APNS IOS 消息推送

    一.Apns简介: Apns是苹果推送通知服务. 二.原理: APNs会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书以确定其为苹果设备):然后,将服务器的信息接收并且 ...

  4. 聊聊iOS中网络编程长连接的那些事

    1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...

  5. 【腾讯Bugly干货分享】H5 视频直播那些事

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...

  6. CSharpGL(31)[译]OpenGL渲染管道那些事

    CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...

  7. TODO:字节的那点事Go篇

    TODO:字节的那点事Go篇 (本文go version go1.7.3 darwin/amd64) 在Golang中string底层是由byte数组组成的. fmt.Println(len(&quo ...

  8. Microsoft Visual Studio 2013 — Project搭载IIS配置的那些事

    前段时间在改Bug打开一个project时,发生了一件奇怪的事,好好的一直不能加载solution底下的这个project,错误如下图所示:大致的意思就是这个project的web server被配置 ...

  9. OpenNLP:驾驭文本,分词那些事

    OpenNLP:驾驭文本,分词那些事 作者 白宁超 2016年3月27日19:55:03 摘要:字符串.字符数组以及其他文本表示的处理库构成大部分文本处理程序的基础.大部分语言都包括基本的处理库,这也 ...

随机推荐

  1. 获取系统的emoji表情定制键盘

    首先 ,想要获取系统的表情,要首先知道表情对应的UTF8 的编码方式,我将其中一部分的图片展示出来 ,然后用UIButton 排列,iOS 7后又增加了300多个表情符号,这些都可以百度查到,现在上代 ...

  2. 1.unix网络编程基础知识

    接触网络编程一年多了,最近在系统的学习vnp两本书,对基础知识做一些总结,希望理解的更透彻清晰,希望能有更多的沉淀. 1.套接口地址 针对IPv4和IPv6地址族,分别定义了两种类型的套接口地址:so ...

  3. ORACLE存储过程笔记2

    ORACLE存储过程笔记2 运算符和表达式     关系运算 =等于<>,!=不等于<小于>大于<=小于等于>=大于等于       一般运算   +加-减*乘/除 ...

  4. 关于RtlInitUnicodeString感想

    01 VOID RtlInitUnicodeString (OUT PUNICODE_STRING DestinationString,IN PCWSTR SourceString OPTIONAL) ...

  5. Clojure学习05:谓词函数

    谓词函数是一个判断式,一个返回bool值的函数. clojure中(lisp习惯)有个规定:对于判断功能的函数,函数名后面都有一个“?”号.所以只要看到后面带问号的函数名,就知道这一定是一个判断函数. ...

  6. Flask web开发 处理Ajax请求

    本文介绍如何处理ajax请求, 一.处理ajax的post请求 举例一: js代码举例如下: var id = obj.parentNode.parentNode.id; $.post("/ ...

  7. Webservice-WSDL详解(三)

    怎样向别人介绍WS的功能呢?一般咱们会写接口文档,亦或口头告诉使用的人.这些方式都存在问题:其中一个我上篇中说过,客户端是无法直接使用服务端接口的:二是程序员在电脑前,想使用WS时,他们的工具(如Ec ...

  8. JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开

    Pre 解决思路 代码后记: 客户端app上的部分代码 调用: 服务器上: 客户端判断服务器是否还活着代码: PRE 在利用socket写通讯程序的时候,想检测服务器是否还活着. 从网上找了很多资料, ...

  9. swf上传文件

    以下是自学it网--中级班上课笔记 网址:www.zixue.it 引入的js包自己在网上找一个,这里好像不支持上传文件,反正我没找到,呵呵~~ html文件 <!DOCTYPE html PU ...

  10. CSS - ResetCss

    /* KISSY CSS Reset 理念:清除和重置是紧密不可分的 特色:1.适应中文 2.基于最新主流浏览器 */ /* 清除内外边距 */ body, h1, h2, h3, h4, h5, h ...