ios本地通知和远程通知

来源:互联网 发布:单片机堆栈空间 编辑:程序博客网 时间:2024/06/08 07:38

本篇文章主要是整理一下有关通知的相关知识。主要介绍:

  • 本地通知
  • 远程通知

本文参考:

  • 编写pushnotification之获取device token
  • 编写pushnotification之服务器端发送通知
  • iOS实现本地通知
  • iOS实现本地通知

本地通知

本地通知,localnotification,用于基于时间行为的通知,比如有关日历或者todo列表的小应用。另外,应用如果在后台执行,iOS允许它在受限的时间内运行,它也会发现本地通知有用。比如,一个应用,在后台运行,向应用的服务器端获取消息,当消息到达时,比如下载更新版本的提示消息,通过本地通知机制通知用户。

本地通知是UILocalNotification的实例,主要有三类属性:

  • scheduledtime,时间周期,用来指定iOS系统发送通知的日期和时间;
  • notificationtype,通知类型,包括警告信息、动作按钮的标题、应用图标上的badge(数字标记)和播放的声音;
  • 自定义数据,本地通知可以包含一个dictionary类型的本地数据。

对本地通知的数量限制,iOS最多允许最近本地通知数量是64个,超过限制的本地通知将被iOS忽略。

如果就写个简单的定时提醒,是很简单的,比如这样:

image

示例写的很简单,启动应用后,就发出一个定时通知,10秒后启动。这时按Home键退出,一会儿就会提示上图的提示信息。如果应用不退出则无效。

代码如下:

UILocalNotification *notification=[[UILocalNotification alloc]init]; 
if (notification!=nil) { 
   NSLog(@">> support localnotification"); 
    NSDate*now=[NSDate new]; 
   notification.fireDate=[nowaddTimeInterval:10]; 
   notification.timeZone=[NSTimeZonedefaultTimeZone]; 
   notification.alertBody=@"该去吃晚饭了!"; 
   [[UIApplicationsharedApplication]  scheduleLocalNotification:notification];

更详细的代码见官方文档:《Scheduling,Registering, and HandlingNotifications》,可以设置比如声音,比如用户定义数据等。

设置更多本地通知的信息:

  • 设置icon上数字。

- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    
    // Overridepoint for customization after applicationlaunch. 
   ///////////// 
  application.applicationIconBadgeNumber =0; 
   // Add the view controller’s view to the window anddisplay. 
    [self.windowaddSubview:viewController.view]; 
    [self.windowmakeKeyAndVisible];

 

    returnYES; 
}

  • 添加通知时间,通知类型,取消通知

#pragma mark – 
#pragma mark onChageValue 
-(IBAction)onChangeValue:(id)sender 

    UISwitch*switch1=(UISwitch *)sender; 
    if(switch1.on) { 
       UILocalNotification *notification=[[UILocalNotification alloc]init]; 
       NSDate *now1=[NSDatedate];  
       notification.timeZone=[NSTimeZonedefaultTimeZone]; 
       notification.repeatInterval=NSDayCalendarUnit; 
       notification.applicationIconBadgeNumber =1; 
       notification.alertAction = NSLocalizedString(@"显示",nil); 
       switch (switch1.tag) { 
           case 0: 
           
               notification.fireDate=[now1dateByAddingTimeInterval:10]; 
               notification.alertBody=self.myLable1.text; 
           
               break; 
           case 1: 
           
               notification.fireDate=[now1dateByAddingTimeInterval:20]; 
               notification.alertBody=self.myLable2.text; 
           
               break; 
           case 2: 
           
               notification.fireDate=[now1dateByAddingTimeInterval:30]; 
               notification.alertBody=self.myLable3.text; 
           
               break; 
           default: 
               break; 
       
       [notificationsetSoundName:UILocalNotificationDefaultSoundName]; 
       NSDictionary *dict = [NSDictionarydictionaryWithObjectsAndKeys: 
                             [NSString stringWithFormat:@"%d",switch1.tag], @"key1",nil]; 
       [notification setUserInfo:dict]; 
       [[UIApplicationsharedApplication]  scheduleLocalNotification:notification]; 
    }else{ 
       NSArray *myArray=[[UIApplication sharedApplication]scheduledLocalNotifications]; 
       for (int i=0; i<[myArray count]; i++) { 
           UILocalNotification   *myUILocalNotification=[myArrayobjectAtIndex:i]; 
           if ([[[myUILocalNotification userInfo] objectForKey:@"key1"]intValue]==switch1.tag) { 
               [[UIApplication sharedApplication]cancelLocalNotification:myUILocalNotification]; 
           
       
   
}

远程通知

远程通知的原理:《偷窥iPhonePush Notification的幕后》和《iPhone的Push(推送通知)功能原理浅析》。

  1. 设备的准备

首先要知道,pushnotification只能在真机上运行的,无法在模拟器上使用,如果在模拟器上运行,在注册设备的时候会有类似如下报错:

Error in registration. Error: Error Domain=NSCocoaErrorDomainCode=3010 "remote notifications are not supported in the simulator"UserInfo=0x5d249d0 {NSLocalizedDescription=remote notifications arenot supported in the simulator}

真机也要注意,如果没有越狱,没有问题。越狱的话,比如通过blacksnOw,因为没有经过iTunes,无法生成有效的设备证书(devicecertificate),因此注册的时候不会成功。

检查越狱版本是否可用,可以ssh到设备上,执行命令:

ls/var/mobile/Library/Preferences/com.apple.apsd.plist -l

 

-rw——- 1 mobilemobile 119 Aug24 19:21 /var/mobile/Library/Preferences/com.apple.apsd.plist

返回的文件大小是119,就没有问题。

2.获取device token的原理

在说操作步骤之前,先说一下获取device token的一些原理方面的事情。

device token,即设备令牌,不是系统唯一标识(见获取iOS设备的基本信息),需要在应用启动时发起到apple服务器请求,注册自己的设备和应用,并获得这个devicetoken。

device token有什么用?如果应用需要pushnotification给手机,那么它要有个服务器端(provider),但是它发出的信息不是直接给手机的,而是必须统一交给apple的服务器,这个服务器就是apple push notificationserver(apns)。apple服务器通过这个token,知道应用要发的消息是给哪个手机设备的,并转发该消息给手机,手机再通知应用程序。

3.获取device token的操作步骤

这里主要参照了这篇文章:ProgrammingApple Push Notification Services

该文档很详细,照做就应该没有问题。

需要注意的是identifier一定要和provision portal profile中的app id一致,即:

image

要和:

image

一致。

另外,要确保设备绑定的是唯一的profile:

image

编写代码,是在AppDelegate中增加两个方法:

  • didRegisterForRemoteNotificationsWithDeviceToken:当应用第一次运行的时候,ios获取到device token后调用,用于注册设备到apns上之后的操作(比如将devicetoken通知应用的服务器端provider)
  • didFailToRegisterForRemoteNotificationsWithError:如果注册的时候失败,ios会调用这个方法,可以打印一些报错日志或者提醒用户通知不可用

另外,有一个方法需要增加内容,主要是打印日志,说明是否已经注册:

- (void)applicationDidFinishLaunching:(UIApplication *)application{    
   [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0]; 
   NSLog(@"InitiatingremoteNoticationssAreActive"); 
   if(!application.enabledRemoteNotificationTypes){ 
       NSLog(@"InitiatingremoteNoticationssAreActive1"); 
       [[UIApplication sharedApplication]registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeBadge)]; 
   
   UIApplication* myapp = [UIApplicationsharedApplication]; 
   myapp.idleTimerDisabled = YES; 
    [windowaddSubview:viewController.view]; 
    [windowmakeKeyAndVisible]; 
}

第一次运行带注册方法的应用,会看到类似这样的提示窗口:

J%ZIE~[N)`A%S_MRQRS6I92

然后,在日志中看到类似下面的日志,主要是看到打印出device token的64位字符串,就说明成功了。

ios本地通知和远程通知

5.获得证书

苹果提供两种接入方式的证书:

  • developer,用于测试
  • production,用于产品

如果是内部测试,使用developer方式即可。

下载证书,通过ios provisioning portal:

image

这要求:

  • 登录的apple developerprogram帐号必须是级别最高的agent(这是针对企业帐号来说的,如果是个人帐号就无所谓了),agent帐号即创始帐号,否则看不到configure链接;
  • 必须经过configure操作,已经enable了developer和product。

然后进入configure链接,点击download按钮即可:

image

6.处理证书

如果是编写在mac下跑的objc程序,无需对证书做处理,可跳过这一步。

如果是在java下使用,需要把打证书用的私有专用密钥和上述的支持通知的证书(注意,不是iphonedeveloper证书)合并导出。

image

生成证书:

image

点击存储的时候,会提示生成一个文件密码:

image

当然可以密码为空。

之后会提示:

image

这里需要输入mac登录用户的密码。

文件生成。

7.编写发送通知的实例

如果是编写mac代码,有一个现成的项目可用:http://stefan.hafeneger.name/download/PushMeBabySource.zip

导入到xcode中,只需将:

image

deviceToken填写成设备的token字符串,另外,pathForResource改为上面图中的:

aps_developer_identity

另外,要把刚才获得证书步骤中下载的证书复制到xcode项目Resources目录下:

image

可以看到文件名和上面的pathForResource的参数一致。

之后运行程序就可以在设备上收到推送通知。

如果是用java编写,可以用第三方库,见:

http://code.google.com/p/javapns/

编写简单的发送通知代码:

import org.json.JSONException;

 

importjavapns.back.PushNotificationManager; 
import javapns.back.SSLConnectionHelper; 
import javapns.data.Device; 
import javapns.data.PayLoad;

 

public class Main {

 

    
    publicstatic 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 astringName 
        pushManager.addDevice("iPhone", "00000000 00000000 0000000000000000 00000000 00000000 00000000 00000000"); 
        simplePayLoad.addAlert("My alertmessage测试"); 
        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队列,如果有消息就发送给苹果服务器。









iOS的通知(notifications)有两种形式:

push notifications,从iOS3开始就有了,由远程服务器发起通知
local notifications,从iOS4开始支持,由本地应用发起的通知
两种通知都是为了提醒用户后台执行的应用有了变化。从用户角度来看,效果是一样的,都是通知。只是实现的方式不一样,对于技术实现来说。

本文主要说明push notification的device token的步骤。

可以通过《偷窥iPhone Push Notification的幕后》和《iPhone的Push(推送通知)功能原理浅析》对pushnotification有个原理上的了解。


设备的准备

首先要知道,pushnotification只能在真机上运行的,无法在模拟器上使用,如果在模拟器上运行,在注册设备的时候会有类似如下报错:

Error in registration. Error: Error Domain=NSCocoaErrorDomainCode=3010 "remote notifications are not supported in the simulator"UserInfo=0×5d249d0 {NSLocalizedDescription=remote notifications arenot supported in the simulator}

真机也要注意,如果没有越狱,没有问题。越狱的话,比如通过blacksnOw,因为没有经过iTunes,无法生成有效的设备证书(devicecertificate),因此注册的时候不会成功。

检查越狱版本是否可用,可以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,就没有问题。

获取device token的原理

在说操作步骤之前,先说一下获取device token的一些原理方面的事情。

devicetoken,即设备令牌,不是系统唯一标识(见获取iOS设备的基本信息),需要在应用启动时发起到apple服务器请求,注册自己的设备和应用,并获得这个devicetoken。

device token有什么用?如果应用需要pushnotification给手机,那么它要有个服务器端(provider),但是它发出的信息不是直接给手机的,而是必须统一交给apple的服务器,这个服务器就是apple push notificationserver(apns)。apple服务器通过这个token,知道应用要发的消息是给哪个手机设备的,并转发该消息给手机,手机再通知应用程序。

0 0