本地推送UILocalNotification的实现
更新:HHH   时间:2023-1-7


        最近看唐巧的技术博客,有一篇博文提到如何改进客户端升级提醒功能(原文在这里: http://www.devtang.com/blog/2012/11/10/how-to-design-upgrade-notice/ ),采用的就是本地推送功能来提升用户体验。此外他还提到当时很火的一件事:一个技术男通过推送弹框向女友求爱。最简单的实现方式也是采用本地推送UILocalNotification。于是我从网上也查了些资料,自己学习了下UILocalNotification,先对其进行一个总结。


(1)一般推送消息都是程序在后台的状态下出现:屏幕上方下滑出现提示,且app的badge数目加一。因此,在这种情况下,本地推送的创建代码如下:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    //创建实例
    UILocalNotification *localNotification=[[UILocalNotification alloc] init];
   if(localNotification) {//主要是判断当前系统是否支持本地推送
      //创建推送激发时间
      NSDateFormatter *fm=[[NSDateFormatter alloc] init];
      [fm setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
      NSDate *fireDate=[fm dateFromString:@"2015-8-7 09:49:00"];
      
      //设置本地推送实例属性
      localNotification.fireDate=fireDate;//激发时间
      localNotification.repeatInterval=NSCalendarUnitDay;//重复频率
      localNotification.timeZone=[NSTimeZone defaultTimeZone];//时区
      localNotification.soundName=UILocalNotificationDefaultSoundName;//提醒声音
      
      localNotification.alertBody=@"This is the message body";//推送的消息体
      localNotification.alertAction=@"OK打开应用";//锁屏时,消息下方有“滑动来OK打开应用”
      localNotification.applicationIconBadgeNumber=1;//app图标右上角的消息个数
      
      //userInfo键值对用于区分不同的LocalNotification,从而可以删除对应的localNotification
      NSDictionary *dic=@{@"name":@"Layne"};
      localNotification.userInfo=dic;
      
      [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
   }
}

这样一来,在app进入到后台之后,在设定的时间就会弹出推送信息。


(2)还有一种情况,就是程序一直在前台运行,这种情况下app也是会收到推送消息的,但是不会有提示,在appDelegate中有个专门的函数用于处理这种情况:

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    UIAlertController *alert=[UIAlertController alertControllerWithTitle:@"Title"
                                                                 message:@"This is push message!"
                                                          preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];
    
    [alert addAction:cancelAction];
    [alert addAction:okAction];
    
    [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
    
}

在这个函数里我们可以定义AlertController进行专门的弹框提醒。


 (3)最后,取消掉本地通知有两种方式:

//取消所有的本地通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
//取消特定的本地通知
[[UIApplication sharedApplication] cancelLocalNotification:localNotification];

(4)localNotification.userInfo的使用:

//获取本地推送数组
NSArray *localArray = [[UIApplication sharedApplication] scheduledLocalNotifications];

//声明本地通知对象
UILocalNotification *localNoti;
if(localArray){
    for(UILocalNotification *noti  in localArray){
        NSDictionary *dict=noti.userInfo;
        if(dict){
            if([dict["name"] isEqualToString:@"Layne"]){
                //do something to the localnotification
            }
            break;
        }
    }
}

即可通过userInfo找到对应的localNotification,从而进行一些操作(例如取消本地通知等)。


(5)自定义与推送通知的交互:

用到三个类:

UIUserNotificationAction(UIMutableUserNotificationAction): 定义具体的操作(按钮)。

UIUserNotificationCategory(UIMutableUserNotificationCategory):包含一组UIUserNotificationAction

UIUserNotificationSettings:Notification的配置信息

具体代码如下:

//定义第一个action(按钮)
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];//第一个按钮
action1.identifier = @"ACTION_1";//按钮的标识
action1.title=@"Accept";//按钮的标题
action1.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序
action1.authenticationRequired = NO;//不需要认证(解锁)
action1.destructive = NO;

//定义第二个action(按钮)
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];  //第二按钮
action2.identifier = @"ACTION_2";
action2.title=@"Reject";
action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理
action2.authenticationRequired = YES;//需要解锁才能处理,如果action.activationMode = UIUserNotificationActivationModeForeground;则这个属性被忽略;
action2.destructive = YES;

//定义一个category
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
category.identifier = @"LEI";//这组动作的唯一标示
[category setActions:@[action1,action2] forContext:UIUserNotificationActionContextDefault];

//定义settings
UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:[NSSet setWithObjects:categorys, nil]];
//注册settings
[[UIApplication sharedApplication] registerUserNotificationSettings:uns];

关键一步:
//要把本地通知的category属性设置为和之前定义的category一样,否则不会显示按钮
localNotification.category = @"LEI";

最后:
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
......

之后再appDelegate中会有对应的事件处理函数:

-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler{
    
}

注:appDelegate中有众多的事件处理函数,例如

-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings



-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 



-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler 



-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 



-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error



-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo



-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler


这些事件处理函数可用来处理推送通知(本地推送和远程推送)。


        以上就是我对本地推送学习的所有总结,希望和大家一起学习进步。

返回开发技术教程...