本地通知使用总结

一.关于通知注册:

ios8之前:registerForRemoteNotificationTypes:

ios8之后:registerUserNotificationSettings

 

二.关于提醒角标

    1.本地推送UILocalNotification的applicationIconBadgeNumber属性只会影响角标的显示,不会影响通知栏的通知处理。

       1)当applicationIconBadgeNumber>0时,角标会随applicationIconBadgeNumber而变化。

       2)当applicationIconBadgeNumber=0时,角标维持推送前状态不变。

       3)当applicationIconBadgeNumber<0时,角标置0不显示。

    2.远程推送的badge字段,只会影响角标的显示,不会影响通知栏的通知处理。

      1)当badge>0时,角标会随badge而变化。

      2)当badge=0时,角标维持不变。

      3)当badge<0时,角标维持不变。

    3.UIApplication的applicationIconBadgeNumber属性既会影响角标的显示,又会影响通知栏通知的处理。

      1)当applicationIconBadgeNumber>0时,角标会随之变化,通知栏通知不变。

      2)当applicationIconBadgeNumber=0时,角标变为0不显示,通知栏通知清空。

       3)当applicationIconBadgeNumber<0时,角标变为0不显示,通知栏通知清空。

 

三.关于重复:

   1. UILocalNotification.repeatInterval:repeatInterval的下限应该是NSCalendarUnitMinute,即每分钟重复发送一次通知。如果设置为NSCalendarUnitSecond,那么消息不会重复,每秒发送一次通知,iOS系统当然不会容许这样的存在了。这里比较不好的一点是NSCalendarUnit是个枚举类型,该值不能自定义,例如你不能塞个10.0给它从而希望它每十秒重复一次。所以如果你想每20分钟发送一次通知,一小时内发送3次,那么只能同时设定三个通知了。

   2.若想设置复杂的重复通知,比如只在每周的周一、周三重复,则只能设置两个通知,分别进行周重复提醒。

 

四.关于userInfo:userInfo可以携带用户自定义的关于通知的信息,通常可以用来作为不同通知的区分标志

 

五.关于接收通知:

1. 如果此时应用程序还在运行(无论是在前台还是在后台)则会调用-(void)application:(UIApplication *)applicationdidReceiveLocalNotification:(UILocalNotification *)notification(如果是远程通知则通过application:(UIApplication *)applicationdidReceiveLocalNotification:(UILocalNotification *)notification)方法接收消息参数。参数中可以拿到notification对象,只要读取userInfo属性区分不同的通知即可。

2. 如果应用程序已经完全退出此时会调用- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法:

    1)通过点击通知栏通知进入:此时可以访问launchOptions中键为UIApplicationLaunchOptionsLocalNotificationKey的对象,这个对象就是发送的通知,由此对象再去访问userInfo。

   2)通过点击图标进入:可以通过[[UIApplication sharedApplication] scheduledLocalNotifications]获取全部的调度通知,并通过userinfo进行区分

 

六:关于覆盖安装:

    如果我们的应用程序给系统发送的本地通知是周期性的,那么即使把程序删了重装,之前的本地通知在重装时依然存在,没有从系统中移除



#import "AppDelegate.h"
#import "ViewController.h"
#import "HomeViewController.h"
#import "KCMainViewController.h"

#define NotificationID @"NotificationID"
NSString * const NotificationCategoryIdent  = @"ACTIONABLE";
NSString * const NotificationActionOneIdent = @"ACTION_ONE";
NSString * const NotificationActionTwoIdent = @"ACTION_TWO";


@implementation AppDelegate

#pragma mark 用户打开app,分为点击图标打开与点击通知栏通知打开方式
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
    //程序开启时取消之前注册的通知
    //1.通过点击通知栏通知开启app
//    UILocalNotification *notification=[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
//    if(notification!=nil){
//        NSDictionary *dic = [notification userInfo];
//        NSString *Identifer = [dic objectForKey:@"id"];
//        if ([Identifer isEqualToString:NotificationID]) {
//            [self cancelLocation:notification];
//        }
//
//    }
//    
//    //2.通过点击图标开启app
//    else {
//        [self cancelLocationWithIdentifier:NotificationID];
//    }
    
    [self cancelLocationWithIdentifier:NotificationID];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    ViewController *vc = [[ViewController alloc] init];
    self.window.rootViewController = vc;
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    
   
    UIUserNotificationType types = (UIUserNotificationTypeAlert|
                                    UIUserNotificationTypeSound|
                                    UIUserNotificationTypeBadge);
    
    NSSet *categories = [self addNotiActionCategories];
    
    
    //注册通知。ios8之后的方式
    if ([[UIApplication sharedApplication]currentUserNotificationSettings].types!=UIUserNotificationTypeNone) {
        
    }else{
        [[UIApplication sharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types  categories:categories]];
        
    }
    return YES;
    
}

#pragma mark 调用过用户注册通知方法之后执行(也就是调用完registerUserNotificationSettings:方法之后执行)
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
    if (notificationSettings.types!=UIUserNotificationTypeNone) {
        
        [self addLocalNotification];
    }
}



#pragma mark 当应用在前台,或者后台运行时收到通知后的处理接口
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    
    //获取通知的userInfo
    NSString *receiveUseInfoID = notification.userInfo[@"id"];

        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"失败" message:@"失败" preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction *actCancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
    
        }];
    
        UIAlertAction *actDetail = [UIAlertAction actionWithTitle:receiveUseInfoID style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
    
        }];
    
        [alertController addAction:actCancel];
        [alertController addAction:actDetail];
        [[self getCurrentVC] presentViewController:alertController animated:YES completion:nil];
}


#pragma mark 当应用未在前台,收到本地通知后,左划通知,显示按钮对应的点击动作处理接口
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler {
    if ([identifier isEqualToString:NotificationActionOneIdent]) {
        
        NSLog(@"You chose action 1.");
    }
    else if ([identifier isEqualToString:NotificationActionTwoIdent]) {
        
        NSLog(@"You chose action 2.");
    }
    if (completionHandler) {
        
        completionHandler();
    }
}


#pragma mark 当应用未在前台,收到远程通知后,左划通知 通知滑动后的动作选项处理接口
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
    
    if ([identifier isEqualToString:NotificationActionOneIdent]) {
        
        NSLog(@"You chose action 1.");
    }
    else if ([identifier isEqualToString:NotificationActionTwoIdent]) {
        
        NSLog(@"You chose action 2.");
    }
    if (completionHandler) {
        
        completionHandler();
    }
}


#pragma mark 进入前台后设置消息信息,只在由后台进入前台时调用,重新开启app时不会调用
-(void)applicationWillEnterForeground:(UIApplication *)application{
//    NSInteger num =[UIApplication sharedApplication].applicationIconBadgeNumber;
//    [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//进入前台取消应用消息图标
}

#pragma mark 进入前台后设置消息信息,由后台进入前台以及重新开启app时均会调用
- (void)applicationDidBecomeActive:(UIApplication *)application{

    [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//进入前台取消应用消息图标,同时清空通知栏通知

}

#pragma mark 程序即将退出时注册通知
-(void)applicationWillTerminate:(UIApplication *)application{
    [self addLocalNotification];
}


#pragma mark - 私有方法
#pragma mark 添加本地通知

-(void)addLocalNotification{

    NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 7];
    [self addNormalLocationWithIdentifier:NotificationID WithFireDate:fireDate WithRepeatInterval:NSCalendarUnitWeekday];
}

//注册通知
-(void)addNormalLocationWithIdentifier:(NSString *)Identifier  WithFireDate:(NSDate *)fireDate WithRepeatInterval:(NSCalendarUnit)repeatInterval{
    
    UILocalNotification *notification=[[UILocalNotification alloc]init];
    //设置调用时间
    notification.fireDate=fireDate;//通知触发的时间,10s以后
    notification.repeatInterval=repeatInterval ;//通知重复次数,枚举类型,除枚举类型外的其它值不会引起重复通知,为0时亦不会重复
    [notification setCategory:NotificationCategoryIdent];
    //notification.repeatCalendar=[NSCalendar currentCalendar];//当前日历,使用前最好设置时区等信息以便能够自动同步时间
    
    //设置通知属性
    notification.alertBody=@"你好你好,是否立即体验?"; //通知主体
    notification.applicationIconBadgeNumber=4;//应用程序图标右上角显示的消息数
    notification.alertAction=@"打开应用"; //待机界面的滑动动作提示
    notification.alertLaunchImage=@"Default";//通过点击通知打开应用时的启动图片,这里使用程序启动图片
    //notification.soundName=UILocalNotificationDefaultSoundName;//收到通知时播放的声音,默认消息声音
    notification.soundName=@"msg.caf";//通知声音(需要真机才能听到声音)
    
    //设置用户信息
    NSMutableDictionary *aUserInfo = [[NSMutableDictionary alloc] init];
    aUserInfo[@"id"] = Identifier;
    aUserInfo[@"sequence"] = [NSNumber numberWithInt:-1];
    notification.userInfo = aUserInfo;
    
    //按调度调用通知
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];

    //立即调用通知
    //[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}


//注册只在某些日期按周重复的通知
-(void)addRepeatLocationWithWeekDate:(NSArray *)dateArray WithIdentifier:(NSString *)identifier{
    
    NSInteger todayWeekDay = [self weekdayWithDate:[NSDate date]];
    
    for (NSString * dateStr in dateArray) {
         NSInteger dateNum = [dateStr integerValue];
        NSInteger dateSeq;
        dateSeq = (dateNum + 7 -todayWeekDay)%7;
        if (!dateSeq) {
            dateSeq = 7;
        }
        
         NSDate *date = [[NSDate date] dateByAddingTimeInterval:(24*3600*dateSeq)];
        [self addNormalLocationWithIdentifier:identifier WithFireDate:date WithRepeatInterval:NSCalendarUnitWeekday];
    }
}

//注册有小睡nap分钟的通知
-(void)addNapLocationWithIdentifier:(NSString *)identifier  WithFireDate:(NSDate *)fireDate WithRepeatInterval:(NSCalendarUnit)repeatInterval WithNap:(NSInteger)nap{
    
    
    //若nap为0,则注册一次通知,相当于不重复,否则重复三次
    NSInteger times;
    if (nap > 0) {
        times = 3;
    } else {
        times = 1;
    }
    
    for (int i = 0; i < times; i++) {
        [self addNormalLocationWithIdentifier:identifier WithFireDate:[fireDate dateByAddingTimeInterval:i * nap * 60] WithRepeatInterval:repeatInterval];
    }
}

#pragma mark 移除本地通知,在不需要此通知时记得移除


//移除指定通知
-(void)cancelLocation:(UILocalNotification *)noti{
    [[UIApplication sharedApplication] cancelLocalNotification:noti];
}


//移除特定id的通知
-(void)cancelLocationWithIdentifier:(NSString *)identifier{
    
    for (UILocalNotification *noti in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
        NSString *notiID = noti.userInfo[@"id"];
        if ([notiID isEqualToString:identifier]) {
            
            [[UIApplication sharedApplication] cancelLocalNotification:noti];
        }
    }
}

//移除全部通知
-(void)cancelAllLocation{
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
}

#pragma mark 添加通知动作action
-(NSSet *)addNotiActionCategories{
    UIMutableUserNotificationAction *action1;
    action1 = [[UIMutableUserNotificationAction alloc] init];
    [action1 setActivationMode:UIUserNotificationActivationModeBackground];
    [action1 setTitle:@"Action 1"];
    [action1 setIdentifier:NotificationActionOneIdent];
    [action1 setDestructive:NO];
    [action1 setAuthenticationRequired:NO];
    
    UIMutableUserNotificationAction *action2;
    action2 = [[UIMutableUserNotificationAction alloc] init];
    [action2 setActivationMode:UIUserNotificationActivationModeBackground];
    [action2 setTitle:@"Action 2"];
    [action2 setIdentifier:NotificationActionTwoIdent];
    [action2 setDestructive:NO];
    [action2 setAuthenticationRequired:NO];
    
    UIMutableUserNotificationCategory *actionCategory;
    actionCategory = [[UIMutableUserNotificationCategory alloc] init];
    [actionCategory setIdentifier:NotificationCategoryIdent];
    [actionCategory setActions:@[action1, action2]
                    forContext:UIUserNotificationActionContextDefault];
    
    NSSet *categories = [NSSet setWithObject:actionCategory];
    return categories;
}


#pragma mark 返回周几
-(int)weekdayWithDate:(NSDate *)date{ //返回周几
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [gregorian components:NSCalendarUnitWeekday fromDate:date];
    int weekday = [components weekday];
    return weekday-1==0?7:weekday-1;
}

#pragma mark 获取窗口当前展示VC
- (UIViewController *)getCurrentVC
{
    UIViewController *result = nil;

    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal)
    {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for(UIWindow * tmpWin in windows)
        {
            if (tmpWin.windowLevel == UIWindowLevelNormal)
            {
                window = tmpWin;
                break;
            }
        }
    }

    UIView *frontView = [[window subviews] objectAtIndex:0];
    id nextResponder = [frontView nextResponder];

    if ([nextResponder isKindOfClass:[UIViewController class]])
        result = nextResponder;
    else
        result = window.rootViewController;

    return result;
}

@end





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值