当前位置: 移动技术网 > 移动技术>移动开发>IOS > 本地通知使用总结

本地通知使用总结

2018年12月26日  | 移动技术网移动技术  | 我要评论

一.关于通知注册:

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

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网