iOS 本地推送

概念

1.推送通知有5种不同的呈现效果

  • 在屏幕顶部显示一块横幅(显示具体内容)
  • 在屏幕中间弹出一个UIAlertView(显示具体内容)
  • 在锁屏界面显示一块横幅(锁屏状态下,显示具体内容)
  • 更新app图标的数字(说明新内容的数量)
  • 播放音效(提醒作用)

2.用户也可以决定是否要开启以下4个功能:

  • 显示App图标数字
  • 播放音效
  • 锁屏显示
  • 显示在“通知中心”

3、注意:

  • 发送推送通知时,如果程序正在前台执行,那么推送通知就不会被呈现出来,但是微信在前台的时候也能推送消息,方法是:创建一个view,仿造系统消息通知的样式向下出现,点击后回到根控制器再进行跳转(注意压栈)
  • 点击通知会打开该通知的app
  • 不管程序打开还是关闭,推送都能如期发出

步骤:

1.创建本地通知对象

UILocalNotification *localNotifi = [UILocalNotification new];

2、设置属性,参照下面

3、调度本地通知 (将本地通知加入本地通知调度池,iOS 7 到这一步完毕,不需要授权)

[[UIApplication sharedApplication] scheduleLocalNotification:localNotifi];

4、 注册通知权限(多个通知只需一次, 建议放在AppDelegate 的
didFinishLaunchingWithOptions方法中) ,iOS8以后必须需要用户授权才可以发送通知

授权效果
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];

参数:

settingsForTypes 通知需要更改的东西,可以修改多个地方,UIUserNotificationType 枚举:
UIUserNotificationTypeNone    = 0,
UIUserNotificationTypeBadge   = 1 << 0, //图标标记
UIUserNotificationTypeSound   = 1 << 1, //声音
UIUserNotificationTypeAlert   = 1 << 2, //提醒

categories:用于添加下拉快速回复功能,下面有介绍

5、删除通知(如果设置了 repeatInterval 重复属性,注意手动删除通知对象)
两种方式:
(1)删除当前程序注册的所有通知,不重复的也会被取消

[[UIApplication sharedApplication] cancelAllLocalNotifications];

(2) 删除指定的通知,一般用于取消重复的通知或者还没有被调用的通知,先获取通知,再遍历根据条件去删除(条件是 UserInfo 的值,是发送通知时所携带的参数)

NSArray *notifiArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *local in notifiArray) {
    //将来可以根据UserInfo的值,来查看这个是否是你想要删除的通知
    if (local.userInfo) {
        //删除单个通知
        [[UIApplication sharedApplication]cancelLocalNotification:local];
    }
}
UIApplication 方法

1、调度本地推送通知(调度完毕后,推送通知会在特定的时间fireDate发出)

[[UIApplication sharedApplication] scheduleLocalNotification:localNotifi];

2、获取被调度的所有本地推送通知
注意:已经发出且过期的推送通知就算调度结束,会自动从这个数组中移除

@property(nullable,nonatomic,copy) NSArray<UILocalNotification *> *scheduledLocalNotifications;

3、取消调度本地推送通知

- (void)cancelAllLocalNotifications;
- (void)cancelLocalNotification:(UILocalNotification *)notification;

4、立即发出本地推送通知
[[UIApplication sharedApplication]presentLocalNotificationNow:localNotifi];


属性:

1、通知触发时间

@property(nullable, nonatomic,copy) NSDate *fireDate;

例子:每隔3秒发送一个通知

localNotifi.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];

2、设置提醒内容

@property(nullable, nonatomic,copy) NSString *alertBody;

例子:

localNotifi.alertBody = @"今天不适合敲代码";

3、设置推送声音,值为声音文件名,默认值为 UILocalNotificationDefaultSoundName ,模拟器无效

@property(nullable, nonatomic,copy) NSString *soundName;

例子:

localNotifi.soundName = UILocalNotificationDefaultSoundName;

4、设置提醒后应用程序右上角图标标记

@property(nonatomic) NSInteger applicationIconBadgeNumber;

例子:

 localNotifi.applicationIconBadgeNumber = 5;

5、是否显示锁屏时 slider 文字,默认为YES,以及提醒的按钮文字

@property(nonatomic) BOOL hasAction;

设置提醒的按钮文字 / 锁屏时界面底部的闪光文字(滑动来...)

@property(nullable, nonatomic,copy) NSString *alertAction;

锁屏界面默认的是回复来查看


锁屏界面效果

注意:这个值会改变两个地方,还会改变提醒的按钮文字

提醒Alter效果

6、设置时区,一般设置为 [NSTimeZone defaultTimeZone],跟随手机的时区

@property(nullable, nonatomic,copy) NSTimeZone *timeZone;

7、 设置重复,每隔多久重复发一次推送通知,单位是日历组件,最小单位是分钟,0代表不重复,如果此属性设置了, 那么调度池不会用完释放!需要手动删除通知对象

@property(nonatomic) NSCalendarUnit repeatInterval;
localNotifi.repeatInterval = NSCalendarUnitMinute;

8、设置依赖的日历历法,默认就是跟随系统走,历法不一样每月重复间隔时间也不一样(如农历是30天)

@property(nullable, nonatomic,copy) NSCalendar *repeatCalendar;

例子:更改为按农历时间重复

localNotifi.repeatCalendar = [NSCalendar calendarWithIdentifier:@"NSCalendarIdentifierChinese"];

9、在哪个区域发送通知, 进入这个区域就发送这个通知
可以进来调一次,出去调一次

@property(nullable, nonatomic,copy) CLRegion *region NS_AVAILABLE_IOS(8_0);

区域是否只检测一次

@property(nonatomic,assign) BOOL regionTriggersOnce NS_AVAILABLE_IOS(8_0);

10、设置启动图,点击推送通知打开app时显示的启动图片

@property(nullable, nonatomic,copy) NSString *alertLaunchImage;

11、设置弹出框的标题

@property(nullable, nonatomic,copy) NSString *alertTitle NS_AVAILABLE_IOS(8_2);

12、设置通知推送携带的参数,一般用于点击通知打开指定控制器页面

@property(nullable, nonatomic,copy) NSDictionary *userInfo;

例子: 发送通知时,带一个索引2的参数,点击通知打开程序后自动跳到第三个控制器(TabBarController)

localNotifi.userInfo = @{@"selectIndex" : @(2)};

13、设置分类,用于添加下拉快速回复功能,下面有介绍

@property (nullable, nonatomic, copy) NSString *category NS_AVAILABLE_IOS(8_0);

点击通知跳到指定控制器界面

案例结构,tabBarController的索引分别为0 1 2

1、接收到本地通知后调用(AppDelegate中),该方法只有程序前台或后台的时候才有用,退出无法接收到消息即无法跳转,如需要在程序退出时推送通知,注意配合下面方式一起使用
(notification 参数中可获取 userInfo 参数来做一些事情)

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

2、程序退出获取本地通知的方法(重要)
原理:程序退出前发送通知给系统(加入调度池),并传出 userInfo 信息,然后退出,当触发通知时会唤醒AppDelegate的 didFinishLaunchingWithOptions 方法,系统又将 userInfo 信息传给程序,并通过方法的launchOptions 参数获取到本地通知对象

UILocalNotification *localNotifi = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];

注意,控制台无法直接打印通知对象,因为编译程序已关闭,只能通过程序查看,可以创建一个label放在页面上,接收到通知后,将通知信息显示在label上

还要注意,程序在前台运行时,通知一样会发送来(虽然上面没有显示),程序接到通知会自动发生跳转(相当于自动点击了通知),这时候我们需要对程序的状态进行判断,如果在前台接收到通知不进行任何操作或提示用户是否进行跳转
UIApplication 单例的一个方法可以查看程序当前的状态

@property(nonatomic,readonly) UIApplicationState applicationState;
判断用户当前是否是激活状态 ,枚举值:
UIApplicationStateActive,     激活
UIApplicationStateInactive,     将要激活
UIApplicationStateBackground     后台

AppDelegate 中完整代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 请求用户授权
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];

    // 处理退出后通知的点击,程序启动后获取通知对象,如果是首次启动还没有发送通知,那第一次通知对象为空,没必要去处理通知(如跳转到指定页面)
    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        UILocalNotification *localNotifi = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
        [self changeLocalNotifi:localNotifi];
    }
    return YES;
}

#pragma mark - 处理后台和前台通知点击
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    [self changeLocalNotifi:notification];
}

- (void)changeLocalNotifi:(UILocalNotification *)localNotifi{
    // 如果在前台直接返回
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
        return;
    }
    // 获取通知信息
    NSString *selectIndex = localNotifi.userInfo[@"selectIndex"];
    // 获取根控制器TabBarController
    UITabBarController *rootController = (UITabBarController *)self.window.rootViewController;
    // 跳转到指定控制器
    rootController.selectedIndex = [selectIndex intValue];
}

快捷回复功能(iOS 8以后可用), category 属性的使用方法

如QQ的功能:触发通知后,点击下拉出现,点击“好的”两个字当做消息回复回去


QQ自动回复效果图

案例的效果:

案例效果

设置快捷回复之后锁屏左滑会出现如下样式

锁屏左滑效果

步骤:

1、发送通知时,给通知对象设置一个 category 标识符,用于AppDelegate中的配置

localNotifi.category = @"category";

2、在AppDelegate中配置注册授权信息

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 创建分类,注意使用可变子类
    UIMutableUserNotificationCategory *category = [UIMutableUserNotificationCategory new];
    // 设置标识符,注意与发送通知设置的category标识符一致~!
    category.identifier = @"category";
    // 设置按钮,注意使用可变子类UIMutableUserNotificationAction
    // 设置前台按钮,点击后能使程序回到前台的叫做前台按钮
    UIMutableUserNotificationAction *action1 = [UIMutableUserNotificationAction new];
    action1.identifier = @"qiantai";
    action1.activationMode = UIUserNotificationActivationModeForeground;
    // 设置按钮的标题,即按钮显示的文字
    action1.title = @"呵呵";

    // 设置后台按钮,点击后程序还在后台执行,如QQ的消息
    UIMutableUserNotificationAction *action2 = [UIMutableUserNotificationAction new];
    action2.identifier = @"houtai";
    action2.activationMode = UIUserNotificationActivationModeBackground;
    // 设置按钮的标题,即按钮显示的文字
    action1.title = @"后台呵呵";
    // 给分类设置按钮
    [category setActions:@[action1,action2] forContext:UIUserNotificationActionContextDefault];

    // 注册,请求授权的时候将分类设置给授权,注意是 NSSet 集合
    NSSet *categorySet = [NSSet setWithObject:category];
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categorySet];
    // 注册通知
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}

3、点击分类按钮后进行回复消息处理

分类按钮点击后执行的方法

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler{
    // 我们可以在这里获取标识符,根据标识符进行判断是前台按钮还是后台按钮还是神马按钮,进行相关逻辑处理(如回复消息)
    NSLog(@"identifier : %@",identifier);
    // 一旦接受必须调用的方法(告诉系统什么时候结束,系统自己对内部进行资源调配)
    completionHandler();
}

注意:该方法会有警告


警告界面

警告说completionHandler这个回调没调用,系统希望知道你什么时候做完,系统到时自己内部进行资源调配

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • @(〓〓 iOS-实用技术)[远程/本地推送] 作者: Liwx 邮箱: 1032282633@qq.com 目...
    Liwx阅读 3,297评论 6 28
  • iOS 本地推送 概念 1.推送通知有5种不同的呈现效果 在屏幕顶部显示一块横幅(显示具体内容)在屏幕中间弹出一个...
    iOS_Alex阅读 1,371评论 0 9
  • 1. 推送通知简介 1.1: 这里说的推送通知跟NSNotification有所区别 NSNotification...
    iYeso阅读 959评论 0 0
  • 概念 1.推送通知有5种不同的呈现效果 在屏幕顶部显示一块横幅(显示具体内容) 在屏幕中间弹出一个UIAlertV...
    JzRo阅读 684评论 0 0
  • iOS中通知机制又叫消息机制,其包括两类:一类是本地通知;另一类是推送通知,也叫远程通知。两种通知在iOS中...
    七里汀阅读 2,069评论 3 2