在苹果的开发API中有3个不同的通知,分别是广播通知、本地通知、推送通知。
推送通知
推送通知,也叫远程通知。推送通知除了可以在iOS设备上使用外,还可以在Mac OS X10.7版本以后的苹果电脑 使用。
推送通知时,即使应用不在前台运行,也可以让用户接收到信息。
推送通知的运行原理不同于本地通知,使用推送通知,必须必须具备三个条件,缺一不可。
1、使用应用的用户;
2、提供推送内容的提供者;
3、苹果公司;
推送通知的原理。
苹果公司为推送通知提供了一个APNS服务(Apple Push Notificaton Service,即苹果推送服务),APNS为所有苹果设备提供安全持久连接通道,内容提供者通过APNS把通知发送给用户的设备。
首先,用户安装了应用,应用运行的时候请求操作系统,操作系统会请求APNS。如果请求成功,APNS会返回令牌给应用,这个过程我们不需要。但是要为应用做一些设置,即在开发者配置门户网站生成App ID、配置概要文件。
然后,用户安装的应用在获得令牌后,把它发送给服务喝咖啡内容提供者,内容提供者接收到这个令牌后,再与APNS通信,APNS认证且通过后,内容提供者发送通过给APNS。
最后,APNS再把通知发送人用户设备。
详细步骤为
步骤1、接收推送通知的应用向iOS操作系统发出请求注册推送通知;
步骤2、iOS操作系统向苹果公司APNS服务器请求APNS设备令牌;
步骤3、苹果公司APNS服务器向接收推送通知的应用返回令牌;
步骤4、接收推送通知的应用向内容提供者服务器发送令牌;
步骤5、内容提供者服务器向苹果公司APNS服务器发送推送通知;
步骤6、苹果公司APNS服务器向接收推送通知的应用推送通知;
推送的配置
配置推送通知需要iOS开发者帐号,然后配置一个Apple ID、配置概要文件和SSL证书。
推送通知配置步骤
步骤1 钥匙串访问中证书签名请求;
钥匙串访问——证书助理——从证书颁发机构请求证书——弹出证书助理对话框——填写用户电子邮件地址、常用名称,同时在请求是选项选择“保存到磁盘”——点击继续——弹出保存证书文件对话框——选择保存文件的位置和文件名——点击存储
步骤2 iOS开发中心的配置门户网站创建App ID;
开发者成功登录配置门户网站——左侧栏——选择App IDs——页面管理应用的App ID中点击New App ID——填写相关信息,Description项中填写应用描述的信息;Bundle Seed ID(App ID Prefix)应用包种子ID,它作为应用的前缀,所描述的应用共享了相同的公钥;Bundle Identifier(App ID Suffix)包标识,作为应用的后缀,苹果公司推荐使用域名反写;——点击Submit提交信息,跳转到创建App ID页面——App ID页面列表中出现刚刚创建的MyNotes信息。
步骤3 iOS开发中心的配置门户网站配置应用推送通知;
App ID页面——列表中选择Enable for Apple Push Notification service以开启推送通知支持
步骤4 iOS开发中心的配置门户网站生成SSL证书;
App ID页面——列表中有两个配置,配置一是Development Push SSL Certificate,即开发配置证书;配置二是Production Push SSL Certificate,即发布产品配置证书——点击相对应的Configure——弹出产生证书签名请求对话框——点击Continue——弹出选择证书文件对话框——点击选取文件,以选择我们上一节中请求的证书签名文件——点击Generate,文件开始上传,上传成功后生成SSL证书——出现生成证书的页面——点击Download,下载生成的SSL证书——点击Done关闭对话框,回到配置页面。
步骤5 iOS开发中心的配置门户网站下载SSL证书;
步骤6 钥匙串访问中为SSL证书导出pl2文件;
在编程时需要使用pl2格式文件,pl2用于存放个人证书我私钥,通常包含保护密码,是二进制格式。
双击下载的SSL证书——弹出修改钥匙串的提示框——输入帐号与密码——点击修改钥匙串——打开钥匙串访问工具——左边栏上方——登录——左边栏下方——我的证书——在右边视图框中查找“Apple Development iOS Push Service:名称”——右击该选项——弹出操作对话框——选择“导出Apple Development iOS Push Services:名称”,根据提示设置保存文件的位置和密码,输入密码选择总是允许——导出文件“名称.pl2”保管好以备后面编程时使用。
客户端编程
1、概要配置文件设置
推送通知的编程 比较简单,编程的关键是获得令牌,这是从APNS返回的,然后还要把内容提交给提供商。
配置开发工具Xcode工程。编写iOS推送应用需要在Xcode工程中进行一些配置,这些配置主要是设备代码签名标识,代码签名标识的前提要有配置概要文件(Provisioning Profiles)。
配置概要文件(Provisioning Profiles)是应用在设备上编译时使用的,文件分为开发配置概要和发布配置概要文件,分别用于开发(调试)和发布。
配置文件的管理步骤:
开发者成功登录配置门户网站——左侧栏——选择Provisioning——其中Development标签用于管理开发配置概要文件,Distributtion标签用于管理发布配置概要文件,虽然处理标签不同,但它们的管理过程是一样的——选择Development——选择New Profile——输入Profile Name名称,如herman;选择证书Certificates;选择App ID;选择项目配置概要文件所支持的设备——点击Submit提交信息——返回管理配置概要文件页面——点击新创建的配置概要文件,如herman后面的download按钮下载配置概要文件——下载后,双击配置概要文件——进入Xcode设备管理工具——可以管理相关设备。
设置代码签名标识时,先要把配置概要文件下载到本地,代码签名标识需要选择这个配置概要文件,即选择TAGETS——配置文件名herman——Code Signing Identity。设置完成后即可以开始编码工作了。
2、代码实现
推送通知的代码实现主要分为两个步骤
步骤1 注册接收通知
步骤2 接收注册通知结果
两个步骤都是在应用程序委托对象AppDelegate中实现的。
1)、application:didFinishLaunchingWithOptions:应用启动方法,在这个方法注册接收通知的类型和图标上标记;
2)、application:didRegisterForRemoreNotificationsWithDeviceToken:注册成功回调;
3)、application:didFailToRegisterForRemoteNotificationsWithError:注册失败回调;
4)、application:didReceiveRemoteNotification:接收推送通知
// 注册
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 注册接收通知类型
[[UIApplication sharedApplication] registerForRemoteNOtificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
// 设置图标标记
application.applicationIconBadgeNumber = 1;
return YES;
}
// 注册回调方法
// 注册成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"设备令牌:%@", deviceToken);
// 将二进制的令牌转换为字符串开式
NSString *tokeStr = [NSString stringWithFormat:@"%@", deviceToken];
if (0 == tokeStr.length)
{
return ;
}
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"\<\>"];
tokeStr = [tokeStr stringByTrimmingCharactersInSet:set]; // 替换掉其他字符
tokeStr = [tokeStr stringByReplacingOccurrencesOfString:@" " withString:@""]; // 替换掉空格
// 网络请求,将令牌等信息发送给内容提供者
NSString *strURL = @"http:192.168.1.103/push_chat_service.php"; // 根据内容提供者情况,提供一个服务器程序接收令牌等信息
NSURL *url = [NSURL URLWithString:strURL];
ASIFormDatarRequest *request = [ASIFormDataRequest requestWithURL:url];
// 发送令牌
[request setPostValue:tokeStr forKey:@"token"];
// 发送App ID
[request setPostValue:@"9823512.com.51.work6.PushChat" forKey:@"appid"];
[request setDelegate:self];
[request startAsynchronous];
}
// 注册失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationWithError:(NSError *)error
{
NSLog(@"获得令牌失败:%@",error);
}
// 接收通知
- (void)application:(UIApplication *)application dieReceiveRemoteNotification:(NSDictionary *)userInfo
{
// 打印接收到的信息
NSLog(@"%@", userInfo);
// 根据应用的状态执行不同的操作
if ([[UIAppliaction sharedApplication] applicationState] == UIApplicationStateActive)
{
// 前台状态
NSLog(@"%@", 前台活动状态);
}
else
{
// 后台状态
NSLog(@"%@", 后台状态);
}
}
推送服务端编程
内容提供者接收到的设备令牌保保存起来,在有新内容需要推送的时候,启动一个服务程序逐个设备推送他们的内容。在推送的具体过程中并不是直接由内容提供者直接发送给用户设备,而是服务程序与APNS通信建立信任连接,然后把内容推送给APNS,再由APNS利用安全通道推送给用户设备。
内容提供者的推送服务程序,需要进行SSL认证编程,以及构建APNS数据包,数据包分成三个部分,一是Command命令;二是deviceToken令牌;三是Payload载荷。Payload载荷不能超过256字节,是JSON格式,如
{
"aps" : {
"alert" :"you got your emails",
"badge" : 9,
"sound" : "bingeing.aiff"
}
}
推送编程
推出服务程序可以使用很多计算机语言实现,如php、java、.net或是note.js。
使用PHP实现推送服务
<?php
$deviceToken = 'alsdjlasdjfo2wo324jlsdkfjladjflj123jljldsjflajsdflajsd';
// 推送方式,包含内容和声音
$body = array("aps" => array("alert" => '新年好. from PHP', "badge" => 11, "sound" => 'default'));
// 创建数据流上下文件对象
$ctx = stream_context_create();
// 设置pem格式文件,即指定一个pem证书文件
$pem = "apns-dev.pem";
// 设置数据流上下文件的本地认证证书
steam_context_set_option($ctx, "ssl", "local_cert", $pem);
$pass = "51work6.com";
// 设置数据流上下文的密码
stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
// 苹果公司的APNS服务器有两个 ,一个是用于产品发布,一个是用于应用测试时使用,开发端口都是2195。
// 产品发布APNS服务器,gateway.push.apple.com
// 测试APNS服务器,geteway.sandbox.push.apple.com
// sock通信
$fp = stream_socket_client("ssl://gateway.sandbox.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if (!$fp)
{
echo "连接失败";
return ;
}
print "连接 OK \n";
// 载荷信息,JSON编码
#payload = json_encode(&body);
// 构建发送的二进制信息
$msg = chr(0).pack("n",32).pack("H*", str_replace(' ', '',$deviceToken)).ack("n", strlen($payload)).$payload;
echo "发送消息:".$payload."\n";
fwrite($fp,$msg);
fclose($fp);
?>
说明:php只支持pem格式的文件,而不支持pl2格式,所以证书需要转换为pem格式。
pl2格式转换pem格式方法
打开终端窗口执行如下命令
$ openssl pkcs12 - in 证书.pl2 - out pans - dev.pem - nodes
Enter Import Password:
MAC verified OK
php代码运行的两种方法
方法1 把这个文件放到Apache HTTP服务器目录下,并保证Apache下安装和PHP,然后用浏览器运行。在浏览器中输入http://localhost/phpPNs/Pusher.php,这个URL是我自己Apache HTTP服务器上的PHP文件。
方法2 需要安装PHP解释器,在终端上运行下面的命令
$ php - f Pusher.php
连接OK
发送消息:{"aps" : {"alert" : "\u65b0\u5e74\u597d. from PHP", "badge" : 11, "sound" : "default"}}
使用java实现推送服务
使用别人已经封装好的javapns类库(http://code.google.com/p/javapns)
package com._51work6;
import javapns.Push;
import javapns.notification.PushNotificationPayload;
public class Pusher
{
public static void main(String[] args)
{
try
{
// 创建推送通知的对象
PushNotificationPayload payload = new PushNotificationPayload();
// 设置通知的内容
payload.addCustomAlertBody("新年好!from java");
// 设置通知的标记数
payload.addBadge(11);
// 设置通知到达时的类型,即声音
payload.addSound("default");
// 发送通知 参数1通知对象;参数2指定证书;参数3证书文件设置的密码;参数4设置访问的是苹果公司APNS服务器的发布产品服务器还是应用测试服务器(true为发布产品服务器,false为应用测试服务器);参数5设备令牌
Push.payload(payload, "ssl/证书.pl2", "51work6.com", false, "alsdjlasdjfo2wo324jlsdkfjladjflj123jljldsjflajsdflajsd");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
说明:推送代码的实现还依赖于如下几个类库:
1、bcprov-jdk15-146.jar(下载地址:http://code.google.com/p/javapns/)
2、JavaPNS_2.2.jar(下载地址:http://code.google.com/p/javapns/)
3、log4j-1.2.15.jar(下载地址:http://logging.apache.org/log4j/1.2/download.html)