iOS 通知——推送通知

在苹果的开发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实现推送服务

 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)


你可能感兴趣的:(iOS,通知)