IOS push

http://blog.163.com/ray_jun/blog/static/167053642201231144540434/  (原帖地址)


客户端发送device token给推送服务器,服务器将这个码发送给苹果服务器。客户端等待苹果的推送服务。 

 

后台服务器上的方法send_apns_to_devices方法,遍历所有注册推送服务的机器,将deviceToken号发给苹果2195端口,这样只要有一个客户端第一次启动app并且接收了APNS服务,那么所有的机器都会收到苹果的服务。除非用户关闭这个功能。

 

所以设置意见反馈服务器就很重要。客户端需要定期的给feedback服务器建立连接。使本地的feedback服务器连接苹果的2196端口,苹果服务器把卸载程序的机器号返回给服务器。然后服务器对deviceToken转换成64位的字符串。并且从SQL服务器上删除。这样,当有新用户注册苹果的APNS消息的时候,本地服务器遍历所有的deviceToken的时候,就能过滤掉删除程序的设备号。然后建立SSL连接的时候,苹果服务器就停止給已经删除程序的app发送推送通知服务了。


XCode项目(模拟发送远程通知):

https://github.com/stefanhafeneger/PushMeBaby


一、CSR文件

 

1、生成Certificate Signing Request(CSR)


 

2、填写你的邮箱和常用名称,并选择保存到硬盘。


 

点击继续:


 

这样就在本地生成了一个Push.certSigningRequest文件。

 

二、p12文件

 

1、导出密钥。



 

2、输入你的密码。

 

 

这样就生成了一个Push.p12文件。

 

三、SSL certificate文件

 

1、用你付过费的帐号登录到iOS Provisioning Portal,并新建一个App ID,这个过程可以参考:iOS应用的真机调试,这样就会生成下面这条记录:


 

2、点击右侧的Configure:


 

3、点击Development Push SSL Certificate一行后的Configure:

 

 

4、点击Continue:


 

5、选择前面生成好的Push.certSigningRequest文件,点击Generate,出现如下所示的页面:


 

6、点击Continue:


 

 

7、点击Download,并将文件命名为aps_developer_identity.cer;双击aps_developer_identity.cer 文件导入Keychain中

 

8、点击Done,你会发现状态变成了Enabled:


 

注意:有的App ID的Apple Push Notification service列是灰色的,并且不允许使用Configure按钮,这是因为APNS不支持带通配符的App ID。

 

到现在为止,我们已经生成了三个文件:

1、Push.certSigningRequest

2、Push.p12

3、aps_developer_identity.cer

 

在项目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代码:

 

Ios代码   收藏代码
  1. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge];   

 

通过registerForRemoteNotificationTypes方法,告诉应用程序,能接受push来的通知。

 

在项目的AppDelegate中添加下面的方法来获取deviceToken:

 

Ios代码   收藏代码
  1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 

    {

        NSLog(@"userInfo=%@",userInfo);

    }


  2. - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
  3. {     
  4.     NSLog(@"My token is:%@", [[deviceToken descriptionstringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]);
  5. }  
  6.   
  7. - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 
  8. {        
  9.     NSLog(@"Failed to get token, error:%@"[error localizedDescription]);  
  10. }  

 

获取到的deviceToken,我们可以提交给后台应用程序,发送通知的后台应用程序除了需要知道deviceToken之外,还需要一个与APNS连接的证书。

 

这个证书可以通过我们前面生成的两个文件中得到。

 

1、将aps_developer_identity.cer转换成aps_developer_identity.pem格式

 

Shell代码   收藏代码
  1. openssl x509 -in aps_developer_identity.cer -inform DER -out aps_developer_identity.pem -outform PEM  

 

2、将p12格式的私钥转换成pem

 

Shell代码   收藏代码
  1. openssl pkcs12 -nocerts -out Push_Noenc.pem -in Push.p12  

 

3、创建p12文件

 

Shell代码   收藏代码
  1. openssl pkcs12 -export -in aps_developer_identity.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_developer_identity" -out aps_developer_identity.p12  

 

这样我们就得到了在.net或java等后台应用程序中使用的证书文件:aps_developer_identity.p12

 

如果后台应用是php的话,在Mac上启动 Keychain助手,然后在login keychain中选择 Certificates分类。你将看到一个可扩展选项“Apple Development Push Services”

  • 扩展此选项然后右击“Apple Development Push Services” > Export “Apple Development Push Services ID123”。保存为 apns-dev-cert.p12 文件。
  • 扩展“Apple Development Push Services” 对“Private Key”做同样操作,保存为 apns-dev-key.p12 文件。
  • 需要通过终端命令将这些文件转换为PEM格式:
  • openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
    openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
  • 如果你想要移除密码,要么在导出/转换时不要设定或者执行:openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
  • 最后,你需要将键和许可文件合成为apns-dev.pem文件,此文件在连接到APNS时需要使用:cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

在.net应用程序中发送通知。

有个开源的类库:apns-sharp。

地址是:http://code.google.com/p/apns-sharp/

我们下载源代码,对里面的JdSoft.Apple.Apns.Notifications做相应的调整就能用了。

我们根据DeviceToken和p12File对JdSoft.Apple.Apns.Notifications.Test代码做相应的调整,如下图。


这样就OK了。

效果:

通知的代码:

[csharp]  view plain copy
  1. for (int i = 1; i <= count; i++)  
  2. {  
  3.     //Create a new notification to send  
  4.     Notification alertNotification = new Notification(testDeviceToken);  
  5.       
  6.     alertNotification.Payload.Alert.Body = string.Format("Testing {0}...", i);  
  7.     alertNotification.Payload.Sound = "default";  
  8.     alertNotification.Payload.Badge = i;  
  9.                       
  10.     //Queue the notification to be sent  
  11.     if (service.QueueNotification(alertNotification))  
  12.         Console.WriteLine("Notification Queued!");  
  13.     else  
  14.         Console.WriteLine("Notification Failed to be Queued!");  
  15.   
  16.     //Sleep in between each message  
  17.     if (i < count)  
  18.     {  
  19.         Console.WriteLine("Sleeping " + sleepBetweenNotifications + " milliseconds before next Notification...");  
  20.         System.Threading.Thread.Sleep(sleepBetweenNotifications);  
  21.     }  
  22. }  

 

PHP 应用程序中发送通知:

使用 PHP 很容易根据数组并 转换成 JSON而创建载荷:
$payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
显示 $payload 的内容可以看到传送到APNS 的 JSON字符串:
{
     "aps" : { "alert" : "This is the alert text", "badge" : 1, "sound" : "default" }
}
这将使消息显示于设备上,触发提升声音并将“1”置于程序图标上。默认按钮“Close”和“View”同时会显示于弹出窗口上。

 

对于 Server Density iPhone程序而言,让用户按下“View”直接进入产生此提示的服务器是很重要的,所以我们增加了额外的自定义值:
$payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default');
$payload['server'] = array('serverId' => $serverId, 'name' => $name);
$output = json_encode($payload);
当用户按下“View”后,自定义server值将被传递到设备中的程序。JSON 值如下:
{
     "aps" : { "alert" : "This is the alert text", "badge" : 1, "sound" : "default" },
     "server" : { "serverId" : 1, "name" : "Server name")
}
256字节的限制适用于整个载荷,包括自定义字典集。
原生接口
在Server Density中,一旦产生了一条提示,将建立一个载荷并插入队列中。因此有必要时我们可以同时发送多个载荷。

Apple推荐使用这种方法,因为如果你在发送各载荷时频繁连接和断开,APNS有可能会封锁你的IP。
如Apple 描述:

原生接口使用原生socket,具有二进制内容,采用数据流技术,不产生回馈。


打开连接
打开连接的 PHP 5代码如下:
$apnsHost = 'gateway.sandbox.push.apple.com';
$apnsPort = 2195;
$apnsCert = 'apns-dev.pem';

 

$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);

$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2,
STREAM_CLIENT_CONNECT, $streamContext);
如果发送错误,你可以参考$errorString。它也包括了SSL许可证不正确时的详细信息。

许可证文件处于执行的PHP代码的当前工作目录下,如果需要你可指定其绝对路径。
注意测试时应该使用开发许可证及sandbox。成品主机名为 gateway.push.apple.com ,而且你必须使用不同的产品许可证。
发送载荷
在此,我们循环整个载荷队列进行发送。构建发送到APNS的二进制内容简单示例如下:
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) .
chr(strlen($payload)) . $payload;
fwrite($apns, $apnsMessage);
注意 $deviceToken 是从数据库中提取并去除空格得到的。我们还应该检查是否$payload超过256个字节。

$apnsMessage 包括了正确的二进制载荷,而fwrite 将载荷写入当前活动的数据流连接中。

完成后,应关闭连接:
socket_close($apns);
fclose($apns);
php-apns

有一个开源服务器库php-apns实现了以上所有功能,它依赖于 memcached

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值