您的位置:首页 > 编程语言 > PHP开发

ios本地通知和远程通知详解-------(注:文章最后有个php服务端实现DEMO)

2014-01-23 10:02 761 查看
声明: 这篇文章是我转载在百度空间的一篇介绍ios推送通知的好文章,想收藏起来以备不时之需,同时分享给所有需要的朋友们(分类译文是为了更多人看到),这是我找了好几天发现的最有价值的一篇文章了,但由于百度空间限制,这里的图片都是我重新截取的,愿大家有所收获,不喜勿喷~最后将转载地址发出以敬作者.http://hi.baidu.com/ncudlz/item/7c86cd32f14477f1e7bb7a90本篇文章主要是整理一下有关通知的相关知识。主要介绍:本地通知远程通知本文参考:编写push notification之获取device token编写push notification之服务器端发送通知iOS实现本地通知iOS实现本地通知本地通知本地通知,local notification,用于基于时间行为的通知,比如有关日历或者todo列表的小应用。另外,应用如果在后台执行,iOS允许它在受限的时间内运行,它也会发现本地通知有用。比如,一个应用,在后台运行,向应用的服务器端获取消息,当消息到达时,比如下载更新版本的提示消息,通过本地通知机制通知用户。本地通知是UILocalNotification的实例,主要有三类属性:scheduled time,时间周期,用来指定iOS系统发送通知的日期和时间;notification type,通知类型,包括警告信息、动作按钮的标题、应用图标上的badge(数字标记)和播放的声音;自定义数据,本地通知可以包含一个dictionary类型的本地数据。对本地通知的数量限制,iOS最多允许最近本地通知数量是64个,超过限制的本地通知将被iOS忽略。如果就写个简单的定时提醒,是很简单的,比如这样:示例写的很简单,启动应用后,就发出一个定时通知,10秒后启动。这时按Home键退出,一会儿就会提示上图的提示信息。如果应用不退出则无效。代码如下:UILocalNotification *notification=[[UILocalNotification alloc] init]; if (notification!=nil) {     NSLog(@">> support local notification");     NSDate *now=[NSDate new];     notification.fireDate=[now addTimeInterval:10];     notification.timeZone=[NSTimeZone defaultTimeZone];     notification.alertBody=@"该去吃晚饭了!";     [[UIApplication sharedApplication]   scheduleLocalNotification:notification];更详细的代码见官方文档:《Scheduling, Registering,and Handling Notifications》,可以设置比如声音,比如用户定义数据等。设置更多本地通知的信息:设置icon上数字。- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {        // Override point for customization after application launch.     /////////////   application.applicationIconBadgeNumber = 0;     // Add the view controller’s view to the window and display.     [self.window addSubview:viewController.view];     [self.window makeKeyAndVisible];    return YES; }添加通知时间,通知类型,取消通知#pragma mark – #pragma mark onChageValue -(IBAction)onChangeValue:(id)sender {     UISwitch *switch1=(UISwitch *)sender;     if (switch1.on) {         UILocalNotification *notification=[[UILocalNotification alloc] init];         NSDate *now1=[NSDate date];          notification.timeZone=[NSTimeZone defaultTimeZone];         notification.repeatInterval=NSDayCalendarUnit;         notification.applicationIconBadgeNumber = 1;         notification.alertAction = NSLocalizedString(@"显示", nil);         switch (switch1.tag) {             case 0:             {                 notification.fireDate=[now1 dateByAddingTimeInterval:10];                 notification.alertBody=self.myLable1.text;             }                 break;             case 1:             {                 notification.fireDate=[now1 dateByAddingTimeInterval:20];                 notification.alertBody=self.myLable2.text;             }                 break;             case 2:             {                 notification.fireDate=[now1 dateByAddingTimeInterval:30];                 notification.alertBody=self.myLable3.text;             }                 break;             default:                 break;         }         [notification setSoundName:UILocalNotificationDefaultSoundName];         NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:                               [NSString stringWithFormat:@"%d",switch1.tag], @"key1", nil];         [notification setUserInfo:dict];         [[UIApplication sharedApplication]   scheduleLocalNotification:notification];     }else {         NSArray *myArray=[[UIApplication sharedApplication] scheduledLocalNotifications];         for (int i=0; i<[myArray count]; i++) {             UILocalNotification    *myUILocalNotification=[myArray objectAtIndex:i];             if ([[[myUILocalNotification userInfo] objectForKey:@"key1"] intValue]==switch1.tag) {                 [[UIApplication sharedApplication] cancelLocalNotification:myUILocalNotification];             }         }     } }远程通知远程通知的原理:《偷窥iPhone Push Notification的幕后》《iPhone的Push(推送通知)功能原理浅析》。设备的准备首先要知道,push notification只能在真机上运行的,无法在模拟器上使用,如果在模拟器上运行,在注册设备的时候会有类似如下报错:Error in registration. Error: Error Domain=NSCocoaErrorDomain Code=3010 "remote notifications are not supported in the simulator" UserInfo=0x5d249d0 {NSLocalizedDescription=remote notifications are not supported in the simulator}真机也要注意,如果没有越狱,没有问题。越狱的话,比如通过blacksnOw,因为没有经过iTunes,无法生成有效的设备证书(device certificate),因此注册的时候不会成功。检查越狱版本是否可用,可以ssh到设备上,执行命令:ls /var/mobile/Library/Preferences/com.apple.apsd.plist  -l-rw——- 1 mobile mobile 119 Aug 24 19:21 /var/mobile/Library/Preferences/com.apple.apsd.plist返回的文件大小是119,就没有问题。2.获取device token的原理在说操作步骤之前,先说一下获取device token的一些原理方面的事情。device token,即设备令牌,不是系统唯一标识(见获取iOS设备的基本信息),需要在应用启动时发起到apple服务器请求,注册自己的设备和应用,并获得这个device token。device token有什么用?如果应用需要push notification给手机,那么它要有个服务器端(provider),但是它发出的信息不是直接给手机的,而是必须统一交给apple的服务器,这个服务器就是apple push notification server(apns)。apple服务器通过这个token,知道应用要发的消息是给哪个手机设备的,并转发该消息给手机,手机再通知应用程序。3.获取device token的操作步骤这里主要参照了这篇文章:Programming Apple Push Notification Services该文档很详细,照做就应该没有问题。需要注意的是identifier一定要和provision portal profile中的app id一致,即:要和:一致。另外,要确保设备绑定的是唯一的profile:编写代码,是在AppDelegate中增加两个方法:didRegisterForRemoteNotificationsWithDeviceToken:当应用第一次运行的时候,ios获取到device token后调用,用于注册设备到apns上之后的操作(比如将device token通知应用的服务器端provider)didFailToRegisterForRemoteNotificationsWithError:如果注册的时候失败,ios会调用这个方法,可以打印一些报错日志或者提醒用户通知不可用另外,有一个方法需要增加内容,主要是打印日志,说明是否已经注册:- (void)applicationDidFinishLaunching:(UIApplication *)application {        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];     NSLog(@"Initiating remoteNoticationssAreActive");     if(!application.enabledRemoteNotificationTypes){         NSLog(@"Initiating remoteNoticationssAreActive1");         [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];     }     UIApplication* myapp = [UIApplication sharedApplication];     myapp.idleTimerDisabled = YES;     [window addSubview:viewController.view];     [window makeKeyAndVisible]; }第一次运行带注册方法的应用,会看到类似这样的提示窗口:然后,在日志中看到类似下面的日志,主要是看到打印出device token的64位字符串,就说明成功了。这里看到那个device Token了吗?这个就是我们需要的东西5.获得证书苹果提供两种接入方式的证书:developer,用于测试production,用于产品如果是内部测试,使用developer方式即可。下载证书,通过ios provisioning portal:这要求:登录的apple developer program帐号必须是级别最高的agent(这是针对企业帐号来说的,如果是个人帐号就无所谓了),agent帐号即创始帐号,否则看不到configure链接;必须经过configure操作,已经enable了developer和product。然后进入configure链接,点击download按钮即可:6.处理证书如果是编写在mac下跑的objc程序,无需对证书做处理,可跳过这一步。如果是在java下使用,需要把打证书用的私有专用密钥和上述的支持通知的证书(注意,不是iphone developer证书)合并导出。生成证书:这里本人冒个泡:大家看到了吗?生成的证书是p12格式的,这个在java下可以直接使用.可是我是需要在php下使用的,因而需要通过控制台转化一下.输入这条命令:将p12格式转化为pem格式.
openssl pkcs12 -in 
CertificateName
.p12
-out 
CertificateName
.pem -nodes
点击存储的时候,会提示生成一个文件密码:
当然可以密码为空。之后会提示:
这里需要输入mac登录用户的密码。文件生成。7.编写发送通知的实例如果是编写mac代码,有一个现成的项目可用:http://stefan.hafeneger.name/download/PushMeBabySource.zip导入到xcode中,只需将:
deviceToken填写成设备的token字符串,另外,pathForResource改为上面图中的:aps_developer_identity另外,要把刚才获得证书步骤中下载的证书复制到xcode项目Resources目录下:
可以看到文件名和上面的pathForResource的参数一致。之后运行程序就可以在设备上收到推送通知。如果是用java编写,可以用第三方库,见:http://code.google.com/p/javapns/编写简单的发送通知代码:import org.json.JSONException;import javapns.back.PushNotificationManager; import javapns.back.SSLConnectionHelper; import javapns.data.Device; import javapns.data.PayLoad;public class Main {    /**      * @param args      * @throws Exception      */     public static void main(String[] args) throws Exception {          PayLoad simplePayLoad = new PayLoad();         // Get PushNotification Instance          PushNotificationManager pushManager = PushNotificationManager.getInstance();          // Link iPhone’s UDID (64-char device token) to a stringName          pushManager.addDevice("iPhone", "00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ");          simplePayLoad.addAlert("My alert message测试");          simplePayLoad.addBadge(1);          simplePayLoad.addSound("default");          Device client = PushNotificationManager.getInstance().getDevice("iPhone");          PushNotificationManager.getInstance().initializeConnection("gateway.sandbox.push.apple.com", 2195, "/home/ubuntu/mypush.p12", "password", SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);          PushNotificationManager.getInstance().sendNotification(client, simplePayLoad);测试中文没有乱码问题。编写比较复杂的使用示例(可以控制通知是否有提示窗口、是否有提醒声音):aPayload.addBadge( 2),显示在手机应用图标上的数字aPayload.addAlert("软件版本有更新"),显示提示窗口文字aPayload.addSound("default.wav"),指定提示声音另外,也可以使用php的第三方实现,比如:http://code.google.com/p/php-apns基本原理是启动一个php服务,监控memcacheq队列,如果有消息就发送给苹果服务器。 from:http://wangjun.easymorse.com/?p=1482
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息