iOS 远程推送的实现

iOS的推送可以用下图简单的概括:

这里 Provider 是指某个应用的Developer,当然如果开发者使用AVOS Cloud的服务,把发送消息的请求委托给我们,那么这里的Provider就是AVOS Cloud的推送服务程序了。上图可以分为三步:

第一步:AVOS Cloud推送服务程序把要发送的消息、目的设备的唯一标识打包,发给APNs。

第二步:APNs在自身的已注册Push服务的应用列表中,查找有相应标识的设备,并把消息发送到设备。

第三步:iOS系统把发来的消息传递给相应的应用程序,并且按照设定弹出Push通知

为了实现消息推送,有两点非常重要:

1. App的推送证书

要能够完整实现一条消息推送,需要我们在App ID中打开Push Notifications,需要我们准备好Provisioning Profile和SSL证书,并且一定要注意Development和Distribution环境是需要分开的。最后,把SSL证书导入到AVOS Cloud平台,就可以尝试远程消息推送了。具体的操作流程如下:

(1). 登录 iPhone Developer Connection Portal 链接) 然后点击 App IDs
(2). 创建一个 Apple ID ,如:com.chenjungang.apnstest  注意:通配符 ID 不能用于推送通知服务。
(3). 点击 Apple ID 旁的“Configure”,根据“向导” 的步骤生成一个签名上传,然后下载生成的许可证。
(4). 双击 .cer 文件将你的 aps_development.cer 导入 Keychain 中。
(5). 在 Mac 上打开“钥匙串访问”,然后在“登录”中选择 "密钥"分类,找到我们创建的证书,然后右击“Apple Development IOS Push Services: com.tadpole.TestAPNs” > 导出 “Apple Development IOS Push Services: com.tadpole.TestAPNs”。保存为 cert.p12 文件。
(6). 通过终端命令将这个 cert.p12 文件转换为 PEM 格式,打开终端, cd 进入证书所在目录,执行如下命令:(Java 直接给 .p12 文件,Phppem 文件)

openssl pkcs12 -in cert.p12 -out apple_push_notification_production.pem -nodes -clcerts

执行完上面命令会在当前目录下生成一个名为apple_push_notification_production.pem文件,这个文件就是我们需要得到php连接APNS 的文件,将apple_push_notification_production.pem和push.php放入同一目录上传到服务器,push.php的代码如下:

 1 <?php
 2 $deviceToken = ‘ad853c20 3a9b874e 00d0cde2 44a73752 999bb250 9fa36129 0525d5d0 a6ba3e4c‘;
 3
 4 // Put your private key‘s passphrase here:
 5 $passphrase = ‘123456‘;
 6
 7 // Put your alert message here:
 8 $message = ‘This is some push message!‘;
 9 $ctx = stream_context_create();
10 stream_context_set_option($ctx, ‘ssl‘, ‘local_cert‘, ‘apple_push_notification_production.pem‘);
11 stream_context_set_option($ctx, ‘ssl‘, ‘passphrase‘, $passphrase);
12
13 // Open a connection to the APNS server
14 //这个为正式的发布地址
15  //$fp = stream_socket_client(“ssl://gateway.push.apple.com:2195“, $err, $errstr, 60, //STREAM_CLIENT_CONNECT, $ctx);
16 //这个是沙盒测试地址,发布到appstore后记得修改哦
17 $fp = stream_socket_client(
18 ‘ssl://gateway.sandbox.push.apple.com:2195‘, $err,
19 $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
20 if (!$fp)
21 exit("Failed to connect: $err $errstr" . PHP_EOL);
22 echo ‘Connected to APNS‘ . PHP_EOL;
23
24 // Create the payload body
25 $body[‘aps‘] = array(
26 ‘alert‘ => $message,
27 ‘sound‘ => ‘default‘
28 );
29
30 // Encode the payload as JSON
31 $payload = json_encode($body);
32
33 // Build the binary notification
34 $msg = chr(0) . pack(‘n‘, 32) . pack(‘H*‘, $deviceToken) . pack(‘n‘, strlen($payload)) . $payload;
35
36 // Send it to the server
37 $result = fwrite($fp, $msg, strlen($msg));
38
39 if (!$result)
40 echo ‘Message not delivered‘ . PHP_EOL;
41 else
42 echo ‘Message successfully delivered‘ . PHP_EOL;
43
44 // Close the connection to the server
45 fclose($fp);
46
47 ?>

PHP

2. 设备标识DeviceToken

知道了谁要推送,或者说要推送给哪个App之后,APNs还需要知道推到哪台设备上,这就是设备标识的作用。获取设备标识的流程如下:

第一步:App打开推送开关,用户要确认TA希望获得该App的推送消息

第二步:App获得一个DeviceToken

第三步:App将DeviceToken保存起来,这里就是通过[AVInstallation saveInBackground]将DeviceToken保存到AVOS Cloud

第四步:当某些特定事件发生,开发者委托AVOS Cloud来发送推送消息,这时候AVOS Cloud的推送服务器就会给APNs发送一则推送消息,APNs最后消息送到用户设备

推送相关的几个概念

消息类型

一条消息推送过来,可以有如下几种表现形式:

1. 显示一个alert或者banner,展现具体内容

2. 在应用icon上提示一个新到消息数

3. 播放一段声音

开发者可以在每次推送的时候设置,在推送达到用户设备时开发者也可以选择不同的提示方式。

本地消息通知

iOS上有两种消息通知,一种是本地消息(Local Notification),一种是远程消息(Push Notification,也叫Remote Notification),设计这两种通知的目的都是为了提醒用户,现在有些什么新鲜的事情发生了,吸引用户重新打开应用。

本地消息什么时候有用呢?譬如你正在做一个To-do的工具类应用,对于用户加入的每一个事项,都会有一个完成的时间点,用户可以要求这个To-do应用在事项过期之前的某一个时间点提醒一下TA。为了达到这一目的,App就可以调度一个本地通知,在时间点到了之后发出一个Alert消息或者其他提示。

我们在处理推送消息的时候,也可以综合运用这两种方式。

代码里面如何实现推送

首先,我们要获取DeviceToken。

App需要每次启动的时候都去注册远程通知——通过调用UIApplication的registerForRemoteNotificationTypes:方法,传递给它你希望支持的消息类型参数即可,例如:

 1 #define IS_IOS8_AND_UP ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
 2
 3 -(void)settingPushMessage:(UIApplication*)application
 4 {
 5
 6     if (IS_IOS8_AND_UP) {
 7         [application registerForRemoteNotifications];
 8         UIUserNotificationType types = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert;
 9         [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]];
10     }else{
11         //消息推送支持的类型
12         UIRemoteNotificationType types =
13         (UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound);
14         //注册消息推送
15         [[UIApplication sharedApplication]registerForRemoteNotificationTypes:types];
16     }
17
18 }
19
20 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
21 {
22     //获取token
23     NSString* token = [NSString stringWithFormat:@"%@",deviceToken];
24     token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];
25     token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];
26     [[NSUserDefaults standardUserDefaults] setObject:token forKey:@"APVNToken"];
27
28     NSLog(@"token====%@",token);
29 }
30 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
31 {
32     //这里是获取token失败
33     NSString *error_str = [NSString stringWithFormat: @"%@", error];
34     NSLog(@"Failed to get token, error:%@", error_str.description);
35 }
36 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
37 {
38     //在此处理接收到的消息。
39     NSLog(@"Receive remote notification : %@",userInfo);
40 }

请注意:注册流程需要在app每次启动时调用,这并不不会带来额外的负担,因为iOS操作系统在第一次获得了有效的device token之后,会本地缓存起来,以后app再调用registerForRemoteNotificationTypes:的时候会立刻返回,并不会再进行网络请求。另外,app层面不应该对device token进行缓存,因为device token也有可能变化——如果用户重装了操作系统,那么APNs再次给出的device token就会和之前的不一样,又或者是,用户restore了原来的backup到新的设备上,那么原来的device token也会失效。

其次,我们要处理收到消息之后的回调

我们可以设想一下消息通知的几种使用场景:

1,在app没有被启动的时候,接收到了消息通知。这时候操作系统会按照默认的方式来展现一个alert消息,在app icon上标记一个数字,甚至播放一段声音。

2,用户看到消息之后,点击了一下action按钮或者点击了应用图标。如果action按钮被点击了,系统会通过调用application:didFinishLaunchingWithOptions:这个代理方法来启动应用,并且会把notification的payload数据传递进去。如果应用图标被点击了,系统也一样会调用application:didFinishLaunchingWithOptions:这个代理方法来启动应用,唯一不同的是这时候启动参数里面不会有任何notification的信息。

3,如果远程消息发送过来的时候,app正在运行,这时候会发生什么呢?

app代理的application:didReceiveRemoteNotification:方法会被调用,同时远程消息中的payload数据会作为参数传递进去。

常见问题FAQ

1. 我能推送长消息吗?

不能,APNs限制了每个notification的payload最大长度是256字节,超长的消息是不能发送的。

2. 推送怎么加声音提醒?

消息推送是可以指定声音的。譬如你可以对正面的反馈使用欢快的声音,对负面的反馈使用低沉一点的声音,都可以达到别出心裁让人眼前一亮的目的。

你需要先放一些aiff、wav或者caf音频文件到app的资源文件中,然后在推送的时候指定不同的音频文件名就可以了。

3. 推送的Badge是怎么回事?

推送并不一定会导致应用图标上红色数字增加,是否显示这一数字,显示成多少,都取决于开发者自己。

在发送推送消息的时候,我们可以选择是否递增这一数字;如果不选择这一项,那么消息推送并不会导致应用图标上红色数字的出现。

好,现在问题来了,这个数字如果搞出来了,怎么让它消失掉呢?

其实我们只需要在任何时候设置 UIApplication.applicationIconBadgeNumber 属性为0,就可以让这个数字消失掉。

一般我们会选择在应用启动的时候(application:didFinishLaunchingWithOptions:方法中),或者干脆一点,在应用每次被切换到前台的时候(applicationWillEnterForeground:方法中),调用这一行代码,即可立刻清除掉Badge数字了。

4. AVOS Cloud平台发出去的通知格式究竟是什么样子的

对于每一条推送消息,都包含一个payload,通常是组成了一个JSON的Dictionary,这其中必不可少的是aps属性,它对应的value也是一个Dictionary,包含下面一些内容:

1)alert消息(文本或Dictionary)

2)应用图标上的红色数字

3)播放的声音文件名

在由推送激活的app打开事件中,application:didFinishLaunchingWithOptions:的options参数就是这个大的Dictionary对象。

1 {
2     aps =     {
3         alert = "hello, everyone";
4         badge = 2;
5         sound = default;
6     };
7 } 

这里要注意的时alert部分,它的值可以是一个String(文本消息),也可以是一个JSON的Dictionary。当它是文本消息的时候,系统就会把这些文字显示到一个alertview中;如果它也是由一个JSON Dictionary组成的话,其格式如下:

* body

* action-loc-key

* loc-key

* loc-args

* launch-image

body部分就是alertView中将要展现出来的文本消息,loc-属性主要是用来实现本地化消息,launch-image只是app主bundle里的一个图片文件的名称,一般来说我们不指定这一属性。

5. 如何显示本地化的消息

有两种办法可以实现推送消息的本地化:

1)在推送的payload中使用loc-key和loc-args来指定进行本地化,这样Provider方只需要按照统一的格式来发送即可,消息的解析和组装则由客户端来完成。

2)如果推送的payload里面不包含loc-key/loc-args信息,那么Provider方就需要自己做本地化处理,然后给不同的device发送不同的消息,为了做到这一点,还需要app在上传device token的时候也把用户的语言设置信息传回来。

目前,因为AVOS Cloud主要就是瞄准中国大陆市场和海外中文用户,所以我们在推送上还不提供多语言支持。

6. 应用该怎么响应推送消息

上面说的处理流程,只能简单展示一下远程消息,激活用户让他们重新回到app中来。但是有时候,我们希望带给用户更好的使用体验,譬如如果我们告诉用户:张三刚刚评论了你的照片。这时候用户如果点击action按钮进入app,我们是展示具体的评论页面为好,还是展示通常的启动页面然后让用户自己去找张三的评论好?我想负责任的开发者都会选择前者。

要做到灵活响应不同类型的通知消息,我们需要在通知的payload中增加更多信息,而不能仅仅只有alert出来的文字信息。对于AVOS Cloud消息推送平台来讲,就需要开发者使用更高级功能的JSON格式。譬如我们发送这样的json字符串{"action":{"type":4},"alert":"hello, everyone”} 最终在app内会收到这样的UserInfo Dictionary:

1 {
2     action =     {
3         type = 4;
4     };
5     aps =     {
6         alert = "hello, everyone";
7         badge = 4;
8     };
9 } 

“hello, everyone”会显示到alertView中,但是整个Dictionary会通过launchOptions传递给application: didFinishLaunchingWithOptions: 方法,这样我们在程序里面就可以对不同的消息实现不同的跳转了。

时间: 2025-02-01 10:39:48

iOS 远程推送的实现的相关文章

IOS远程推送

一.关于推送通知 推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说来,当要显示消息或下载数据的时候,通知是由远程服务器(程序的提供者)发送,然后通过苹果的推送通知服务(Apple Push Notification Service,简称apns)推送到设备的程序上. 推送的新消息可能是一条信息.一项即将到期的日程或是一份远程服务器上的新数据.在系统上展现的时候,可以显示警告信息或

iOS 远程推送 根据后台推送内容的不同跳转指定页面

转发自:http://www.jianshu.com/p/4531bd6e3a01 iOS 远程推送,根据后台推送内容的不同, 跳转指定页面 我目前的需求是总体分为两类: 1:私信.关注.点赞一类,只需跳转到对应的tabbar 中的某一项 2:每日精品文章项目推送,分两个子类 (1)如果当前已经打开 文章项目页面,则直接刷新,不推出新页面 (2)如果当前未打开此页面,则push出新的文章项目页面 iOS 推送情况分为 应用未启动的 情况: 打开应用 ,推送信息 会通过 - (BOOL)appli

iOS远程推送原理及实现过程

推送通知,是现在的应用必不可少的功能.那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什么呢?在做 iOS 远程推送时,我们会遇到各种各样的问题.那么首先让我们准备一些做推送需要的东西.我们需要一个付费的苹果开发者账号(免费的不可以做远程推送),有了开发者账号,我们可以去苹果开发者网站,配置自己所需要的推送的相关证书.然后下载证书,供我们后面使用,详细的证书配置过程,我们下面再说. 首先我们要说说iOS推送通知的基本原理: 苹果的推送服务通知是由自己专门的推送服务器AP

iOS 远程推送的详细配置

首先,来说一下苹果的推送机制.顾名思义,推送,是指服务器向客户端发送消息,那么在iOS中,应用是被后台挂起的,并不能一直连接网络,那么服务器怎么才能把消息发送到客户端呢?这就用到推送,苹果的推送机制,是只能由APNS发送推送通知,所以你自己的后台服务器想给客户端推送通知,得把要推送的内容发送给APNS. 说到这里,如果还不了解苹果的推送机制,可以自行查看资料.总之整体的流程就是:APP启动的时候,获取本设备的device_token,然后把这个device_token告诉你自己的服务器,服务器拿

iOS远程推送之友盟Push

入职后的一个任务,就是做远程推送,听老大说用的是友盟Push.所以就看了一下友盟push,具体的集成以及证书的生成请参照这里.具体的就不再多说了,主要是自己重新封装了一下UMessage,具体的内容如下: // // ZGUmessagePush.h // NotePad // // Created by zhanggui on 15/10/19. // Copyright © 2015年 xiaoguizi. All rights reserved. // #import <Foundatio

iOS远程推送,从机制到实现,尽量详细

本人第一次写博客,写的不好的地方大家请见谅. 本文主要参考了http://blog.csdn.net/showhilllee/article/details/8631734,感谢showhilllee详细的讲解.因为在做的过程中有些自己的理解和变化,所以自己再写一遍关于推送的详细博客. 本文分为四部分介绍: 一.解释APNS远程推送 二.配置推送的证书 三.导出自己服务器可用的证书 四.代码实现设备注册推送.获取推送消息 好了,现在开始正式讲解推送. 一.首先上一个老图,苹果很早就给大家的,推送

iOS 远程推送通知 详解

1: ios本地通知和远程通知 http://wangjun.easymorse.com/?p=1482 2: 苹果远程通知服务申请激活例图 (外国佬写的.) http://mobiforge.com/developing/story/programming-apple-push-notification-services 3:书籍参考:iPhone 开发秘籍 第16章 推送通知. 好了,进入正文: 首先是申请证书的网址 https://developer.apple.com/ios/manag

IOS远程推送证书的制作步骤

今天还在看环信的使用方法,在环信的官网上发现了这组制作远程推送证书的一组图片,正好之前本人没有写过关于远程证书的笔记,这里要写一篇博文,整理一下远程推送证书的制作流程,尽管如此,本篇博文依然是作者原创,方便自己学习.参考使用.(声明本文的图片全部来自网络,是为了节省时间) (1)打开开发者中心,并登陆自己的开发者账号(或者公司的开发者账号) (2)从Member Center进入Certificates, Identifiers & Profiles (3)选择要制作的证书为推送证书 对于开发环

iOS远程推送原理

远程推送 就是从远程服务器推送消息给客户端的通知,当然需要联网. 远程推送服务APNs (Apple Push NotificationServices) 为什么需要远程推送通知? 传统获取数据的局限性是只要用户关闭了app,就无法跟app的服务器沟通,无法从服务器上获得最新的数据内容 而远程推送通知可以解决这个问题,不管用户打开还是关闭app,只要联网了,都能接收到服务器推送的远程通知. 我们先从网络连接开始了解下. http协议:是个短连接,一个请求一个响应就结束了.典型的网络请求. tcp