关于推送的实现

2013-08-25 

补充推送的原理介绍:

http://www.zhihu.com/question/20667886

http://www.ifanr.com/3979


本来还想自己写一个,不过看到下面这个文章,解释了我的大部分问题,唯一一个问题没有搞清楚的是,provider的处理,我们的程序是直接发送给了服务器,服务器那边怎么处理的还真不知道。

原文地址:http://blog.csdn.net/showhilllee/article/details/8488780

IOS的推送实现由这样几步来完成:


    创建本地工程,info.plist中设置Bundle identifier为刚刚创建的Bundle Id。Com.soso.sosoimage。设定Code Signing Identity为刚刚创建的Provisioning Profile。

    程序第一次执行的时候,调用如下代码.

[cpp]  view plain copy
  1. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];  


三个参数分别代表消息(横幅或提醒,由用户Setting决定,程序不可更改)、数字标记、声音。

在AppDelegate.m中添加两个方法.
[cpp]  view plain copy
  1. //iPhone 从APNs服务器获取deviceToken后回调此方法  
  2. - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken  
  3. {  
  4.     NSString* dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];  
  5.     NSLog(@"deviceToken:%@", dt);  
  6. }  
  7.   
  8. //注册push功能失败 后 返回错误信息,执行相应的处理  
  9. - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err  
  10. {  
  11.     NSLog(@"Push Register Error:%@", err.description);  
  12. }  
获取DeviceToken后,将其传给Provider。

使用Provider向APNS发送Push消息(就是这里provider没有明白是干嘛使的)

Provider,将推送信息发送给APNS(苹果推送服务器)的程序。有很多开源的实现,我们使用javapns ( http://code.google.com/p/javapns/ )。
首先,Provider要有目标DeviceToken,这是发送目标,由客户端传给Provider之后存在某处。
安装javapns,需要导入的jar为bcprov-jdk15-146.jar, log4j-1.2.15.jar, JavaPNS_2.3_Alpha_5.jar。
将前面导出的P12文件放在Provider的工程目录下。
Provider向APNS发送消息可以参考javapns中NotificationTest.java。也可以参考如下例子。

(1)使客户端图标显示数字标记

[cpp]  view plain copy
  1. Push.badge(2, keystore, password, false"7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");  
其中,2为要显示的数字,应用程序的右上角角标;
[cpp]  view plain copy
  1. String keystore = "PushCertificates.p12";     //P12文件的路径;  
  2. String password = "sosoimage";                //P12文件的密码;  
false,指的是使用测试环境,使用正式产品环境应传入true.
"7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67"为客户端获得并传给Provider的DeviceToken,此参数还可以传入String[]对象,以同时向多个客户端Push消息。

(2)使客户端显示横幅或提醒

Provider可以向客户端Push一条Message,但客户端有权限决定这条Message的显示方式(无、横幅、提醒)。

[cpp]  view plain copy
  1. Push.alert("A Message", keystore, password, )false"7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");  

(3)混合方式

可以在一个Push消息里附带多种信息,Message, 标记,声音,可以使用如下代码.
[cpp]  view plain copy
  1. PushNotificationPayload payload = PushNotificationPayload.complex();  
  2. payload.addAlert("A Message");  
  3. payload.addBadge(2);  
  4. payload.addSound("test.aiff");  
  5. Push.payload(payload, , keystore, password, false"7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");  

上面的代码都有可能会有相应的Exception抛出来,需要处理。更多的使用方式可以参考 http://code.google.com/p/javapns/ 

以上就是Provider处理的内容


IOS客户端接收处理由APNS发来的消息

(1)当程序未启动,用户接收到消息。需要在AppDelegate中的didFinishLaunchingWithOptions得到消息内容。代码如下,
[cpp]  view plain copy
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
  2. {  
  3.     ...  
  4.       
  5.     NSDictionary* payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];  
  6.     if (payload)   
  7.     {  
  8.     ...  
  9.     }  
  10.   
  11.     ...  
  12. }  
(2) 当程序在前台运行, 接收到消息不会有消息提示(提示框或横幅)。 当程序运行在后台 ,接收到消息会有消息提示,点击消息后进入程序,AppDelegate的didReceiveRemoteNotification函数会被调用(需要自己重写), 消息做为此函数的参数传入 ,代码如下
[cpp]  view plain copy
  1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload  
  2. {   
  3.     ...  
  4. }  
(3)无论在哪个函数传入,消息总是一个NSDictionary对象,处理方式可以参考如下代码
[cpp]  view plain copy
  1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload   
  2. {  
  3.     NSLog(@"remote notification: %@",[payload description]);  
  4.     NSString* alertStr = nil;          
  5.     NSDictionary *apsInfo = [payload objectForKey:@"aps"];      
  6.     NSObject *alert = [apsInfo objectForKey:@"alert"];      
  7.     if ([alert isKindOfClass:[NSString class]])      
  8.     {         
  9.         alertStr = (NSString*)alert;      
  10.     }      
  11.     else if ([alert isKindOfClass:[NSDictionary class]])      
  12.     {          
  13.         NSDictionary* alertDict = (NSDictionary*)alert;          
  14.         alertStr = [alertDict objectForKey:@"body"];      
  15.     }          
  16.     application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];          
  17.     if ([application applicationState] == UIApplicationStateActive && alertStr != nil)      
  18.     {  
  19.         UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];  
  20.         [alertView show];      
  21.     }  
  22. }  
    [html]  view plain copy print ?
    1.   

你可能感兴趣的:(关于推送的实现)