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以后必须需要用户授权才可以发送通知

iOS 本地推送_第1张图片
授权效果
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 *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;

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


iOS 本地推送_第2张图片
锁屏界面效果

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

iOS 本地推送_第3张图片
提醒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);

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

iOS 本地推送_第4张图片
案例结构,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的功能:触发通知后,点击下拉出现,点击“好的”两个字当做消息回复回去


iOS 本地推送_第5张图片
QQ自动回复效果图

案例的效果:

iOS 本地推送_第6张图片
案例效果

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

锁屏左滑效果

步骤:

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这个回调没调用,系统希望知道你什么时候做完,系统到时自己内部进行资源调配

你可能感兴趣的:(iOS 本地推送)