APNS 那些事!

        之前在消息推送中间件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 采用二进制消息协议,如下:

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

     

     注意:

       如果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 结构如下:

         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

时间: 2024-09-14 20:33:25

APNS 那些事!的相关文章

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

1.登录到 iPhone Developer Connection Portal 并点击 App IDs 2.创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,我们的iPhone程序ID像这样: AB123346CD.com.serverdensity.iphone 3.点击App ID旁的"Configure",然后按下按钮生产 推送通知许可证.根据"向导"指导的步骤生成一个签名并上传,最后下载生成的许可证.此步骤在 Apple文档

iOS推送的那些事_IOS

直接切入主题,讲讲如何模拟推送以及处理推送消息.在进入主题之前,我先说几个关键流程: 1.建Push SSL Certification(推送证书) 2.OS客户端注册Push功能并获得DeviceToken 3.用Provider向APNS发送Push消息 4.OS客户端接收处理由APNS发来的消息 推送流程图: Provider:就是为指定iOS设备应用程序提供Push的服务器.如果iOS设备的应用程序是客户端的话,那么Provider可以理解为服务端(推送消息的发起者)APNs:Apple

iOS推送集成和配置APNS推送证书方法图解

App中推送功能越来越普及,但是对于不经常做推送的人来说配置证书真的是非常痛苦的事.本文将以集成个推为例,详细讲解配置APNS证书的过程. 集成推送总体分为以下步骤(本文只讲1,2两个步骤) 创建APP应用,并且配置APNS证书 在个推平台创建应用 在项目中集成个推SDK 调试,实现推送 1.创建APP应用,并且配置APNS证书 登录到苹果开发者账号ps://developer.apple.com/account/overview.action">https://developer.app

要想提高工作效率,请拒绝做这7种事

PS:原文出自Medium上的CamMi Pham的           7 Things You Need To Stop Doing To Be More Productive, Backed By Science       转载自36Kr网作者boxi http://www.36kr.com/p/212874.html       同时参考蓝斯博客 http://blog.csdn.net/lancees/article/details/39554247       作者通过自身经历和一

毕业生、待业毕业生应该做的几件事

写在前面: 在IT(IT,Information Technology,信息技术,或许有人真的忘了或不知道IT代表什么含义)这个偏向于技术的行业里,聚集着大量的信息技术爱好者.他们相当一部分是年轻的学生或者刚进入社会不久的青年."教育从娃娃抓起",这话一点也不假,而且一直是这么做的.但是很多人(其中还包括一些教育工作者)认为教育是教育者的事而与被教育者关系不大,认为教育者仅仅是传道授业解惑而忽略了他们内心的想法和变化.很多学生在中学时或者在小时候不理解老师或家长告诫自己的话或者强迫要求

编码那点事

最近一直忙着做一个C++项目,一直也抽不出时间来更新博客.项目代码托管在 GitHub.是一个跨平台的数据包捕获程序,基于Qt 4.X和WinPcap库(Windows下)和Libpcap库(Linux下).目前还是进行中,只在Windows下测试.有兴趣的同学可以提提意见. 好了,言归正传.项目中频繁遇到了需要转换编码和字节序的地方,字节序没什么说的,无非就是大小端的问题.今天我们就谈一谈编码那点事吧. 现在还记得当时自己刚接触到字符串编码问题的纠结过程.什么ASCII.GBK.GB2312.

网站开发人员应该知道的61件事

有人在Stack Overflow上发问,动手开发网站之前,需要知道哪些事情? 不出意料地,他得到了一大堆回答. 通常情况下,你需要把所有人的发言从头到尾读一遍.但是,Stack Overflow有一个很贴心的设计,它允许在问题下方开设一个wiki区,让所有人共同编辑一个最佳答案.于是,就有了下面这篇文章,一共总结出六个方面共计61条"网站开发须知". 我发现,这种概述性的问题,最适合这种集合群智.头脑风暴式的回答方式了.这也是我第一次觉得,Stack Overflow做到了Wikip

iOS推送的那些事

关于推送 关于苹果的推送网上已经有非常多的资源讲解,我在这里就不再累赘.直接切入主题,讲讲如何模拟推送以及处理推送消息.在进入主题之前,我先说几个关键流程: 创建Push SSL Certification(推送证书) iOS客户端注册Push功能并获得DeviceToken 使用Provider向APNS发送Push消息 iOS客户端接收处理由APNS发来的消息 推送流程图: Provider:就是为指定iOS设备应用程序提供Push的服务器.如果iOS设备的应用程序是客户端的话,那么Prov

btrace一些你不知道的事(源码入手)

背景     周五下班回家,在公司班车上觉得无聊,看了下btrace的源码(自己反编译). 一些关于btrace的基本内容,可以看下我早起的一篇记录:btrace记忆      上一篇主要介绍的是btrace的一些基本使用以及api,这里我想从btrace源码本身进行下介绍.至于btrace的优势,能用来干些什么,自己上他的官网看下或者google一下,花个半小时就能明白了.      至于为什么会去反编译查看btrace源码,主要是会在部门整个关于btrace的分享.同时btrace的相关技术