2013-08-25
补充推送的原理介绍:http://www.zhihu.com/question/20667886
http://www.ifanr.com/3979
本来还想自己写一个,不过看到下面这个文章,解释了我的大部分问题,唯一一个问题没有搞清楚的是,provider的处理,我们的程序是直接发送给了服务器,服务器那边怎么处理的还真不知道。
原文地址:http://blog.csdn.net/showhilllee/article/details/8488780
IOS的推送实现由这样几步来完成:
程序第一次执行的时候,调用如下代码.
- [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
三个参数分别代表消息(横幅或提醒,由用户Setting决定,程序不可更改)、数字标记、声音。
在AppDelegate.m中添加两个方法.- //iPhone 从APNs服务器获取deviceToken后回调此方法
- - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
- {
- NSString* dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
- NSLog(@"deviceToken:%@", dt);
- }
- //注册push功能失败 后 返回错误信息,执行相应的处理
- - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
- {
- NSLog(@"Push Register Error:%@", err.description);
- }
使用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)使客户端图标显示数字标记
- Push.badge(2, keystore, password, false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
- String keystore = "PushCertificates.p12"; //P12文件的路径;
- String password = "sosoimage"; //P12文件的密码;
"7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67"为客户端获得并传给Provider的DeviceToken,此参数还可以传入String[]对象,以同时向多个客户端Push消息。
(2)使客户端显示横幅或提醒
Provider可以向客户端Push一条Message,但客户端有权限决定这条Message的显示方式(无、横幅、提醒)。
- Push.alert("A Message", keystore, password, )false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
(3)混合方式
可以在一个Push消息里附带多种信息,Message, 标记,声音,可以使用如下代码.- PushNotificationPayload payload = PushNotificationPayload.complex();
- payload.addAlert("A Message");
- payload.addBadge(2);
- payload.addSound("test.aiff");
- Push.payload(payload, , keystore, password, false, "7bb8d508e32df651c6c239439737dbd40a88d2461ad2ac1e5dbe49ecea5ccc67");
上面的代码都有可能会有相应的Exception抛出来,需要处理。更多的使用方式可以参考 http://code.google.com/p/javapns/
以上就是Provider处理的内容
IOS客户端接收处理由APNS发来的消息
(1)当程序未启动,用户接收到消息。需要在AppDelegate中的didFinishLaunchingWithOptions得到消息内容。代码如下,- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- ...
- NSDictionary* payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
- if (payload)
- {
- ...
- }
- ...
- }
- - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload
- {
- ...
- }
- - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload
- {
- NSLog(@"remote notification: %@",[payload description]);
- NSString* alertStr = nil;
- NSDictionary *apsInfo = [payload objectForKey:@"aps"];
- NSObject *alert = [apsInfo objectForKey:@"alert"];
- if ([alert isKindOfClass:[NSString class]])
- {
- alertStr = (NSString*)alert;
- }
- else if ([alert isKindOfClass:[NSDictionary class]])
- {
- NSDictionary* alertDict = (NSDictionary*)alert;
- alertStr = [alertDict objectForKey:@"body"];
- }
- application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];
- if ([application applicationState] == UIApplicationStateActive && alertStr != nil)
- {
- UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
- [alertView show];
- }
- }