关于iOS本地推送的那些事儿
2016-08-11 17:42
316 查看
最近在做一个项目,需要大量的本地推送,本地推送有一个坑,就是iOS系统限制了注册本地推送的数量,最大的注册量为64条,没有那么多的容量供我们挥霍。网上相关的文章比较少提到推送数量限制。
不说废话,请看代码
AppDelegate.m
创建一个本地推送的管理类 LocalNotificationManager
LocalNotificationManager.h 放出两个方法,供外部调用,可以根据工程适量增加API
LocalNotificationManager.m
在ViewController中设置参数就可以了,这里只是示范,具体的notification自己定义
ViewController.m
效果图:
初次打开,弹出提示框,向用户请求本地通知的权限
App在前端时候,AppDelegate里面会接受到一个notification,可以获取里面的信息用Alert来展示
弹框提醒,样式取决于用户在系统中设置的样式
在通知栏中的效果
总结:用完的本地推送,必须删除,然后没有推送的可以储存在数据库或者其他plsit中,对时间要求比较准确或者数量要求更多的,要么推送到系统日历,由日历去提醒。要么就要每次打开APP就去查询数据库,再去遍历数据库中满足条件的推送信息!!
不说废话,请看代码
AppDelegate.m
#import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //注册本地通知 [self registerLocalNotification]; return YES; } - (void)registerLocalNotification{ /** *iOS 8之后需要向系统注册通知,让用户开放权限 */ if (CurrenVersiongreaterThan(@"8.0")) { if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) { UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } } } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ UIApplicationState state = application.applicationState; if (state == UIApplicationStateActive) { if (CurrenVersiongreaterThan(@"9.0")) { UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"警告" message:notification.alertBody preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]; [alert addAction:okAction]; [self.window.rootViewController presentViewController:alert animated:YES completion:nil]; }else{ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"警告" message:notification.alertBody delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; } //清除已经推送的消息 [LocalNotificationManager compareFiretime:notification needRemove:^(UILocalNotification *item) { [[UIApplication sharedApplication] cancelLocalNotification:notification]; }]; } } @end
创建一个本地推送的管理类 LocalNotificationManager
LocalNotificationManager.h 放出两个方法,供外部调用,可以根据工程适量增加API
#import <Foundation/Foundation.h> @interface LocalNotificationManager : NSObject + (BOOL)insertLocalNotificationToSystemQueueWithNotificationID:(NSString *)notificationID; + (void)compareFiretime:(UILocalNotification *)notification needRemove:(void(^)(UILocalNotification * item))needRemove; @end
LocalNotificationManager.m
#import "LocalNotificationManager.h" #define KEY_NOTIFICATION @"this is a key for notification" @implementation LocalNotificationManager + (BOOL)insertLocalNotificationToSystemQueueWithNotificationID:(NSString *)notificationID{ //新增前先清楚已注册的相同ID的本地推送 [self deleteLocadNotificationWithNotificationID:notificationID]; //初始化 UILocalNotification * localNotification = [[UILocalNotification alloc] init]; //设置开火时间(演示为当前时间5秒后) localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; //设置时区,取手机系统默认时区 localNotification.timeZone = [NSTimeZone defaultTimeZone]; //重复次数 kCFCalendarUnitEra为不重复 localNotification.repeatInterval = kCFCalendarUnitEra; //通知的主要内容 localNotification.alertBody = @"人生苦短,我用Objcetive-C"; //小提示 localNotification.alertAction = @"查看详情"; //设置音效,系统默认为电子音,在系统音效中标号为1015 localNotification.soundName = UILocalNotificationDefaultSoundName; //or localNotification.soundName = @"send.caf" 自己的音频文件 //localNotification.applicationIconBadgeNumber = 1; Icon上的红点和数字 //查找本地系统通知的标识 localNotification.userInfo = @{KEY_NOTIFICATION: notificationID}; //提交到系统服务中,系统限制一个APP只能注册64条通知,已经提醒过的通知可以清除掉 /** *64条是重点,必需mark一下 */ [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; return YES; } #pragma mark - 查询符合条件的本地推送 + (UILocalNotification *)queryNotificationWithNotificatioID:(NSString *)notificatioID{ NSArray * notifications = [self queryAllSystemNotifications]; __block UILocalNotification * localnotification = nil; if (notifications.count > 0) { [notifications enumerateObjectsUsingBlock:^(UILocalNotification * obj, NSUInteger idx, BOOL * _Nonnull stop) { //查找符合条件的本地推送 if ([obj.userInfo[KEY_NOTIFICATION] isEqualToString:notificatioID]) { localnotification = obj; *stop = YES; } }]; } return localnotification; } #pragma mark - 查询所有已注册的本地推送 + (NSArray *)queryAllSystemNotifications{ return [[UIApplication sharedApplication] scheduledLocalNotifications]; } + (void)cleanFiretimeIsPastNofications:(NSArray *)notifications{ [notifications enumerateObjectsUsingBlock:^(UILocalNotification * notification, NSUInteger idx, BOOL * _Nonnull stop) { [self compareFiretime:notification needRemove:^(UILocalNotification *item) { /** *如果设置了重复的周期,这时候打印notificaion,会有个Next fire time字样 */ //销毁通知 [[UIApplication sharedApplication] cancelLocalNotification:item]; }]; }]; } #pragma mark - 对比,是否过期 + (void)compareFiretime:(UILocalNotification *)notification needRemove:(void(^)(UILocalNotification * item))needRemove{ NSComparisonResult result = [notification.fireDate compare:[NSDate date]]; if (result == NSOrderedAscending) { needRemove(notification); } } #pragma mark - 注销一条本地推送(用于更新同一个ID的推送) + (void)deleteLocadNotificationWithNotificationID:(NSString *)notificationID{ UILocalNotification * notification = [self queryNotificationWithNotificatioID:notificationID]; if (notification) { [[UIApplication sharedApplication] cancelLocalNotification:notification]; } } @end
在ViewController中设置参数就可以了,这里只是示范,具体的notification自己定义
ViewController.m
#import "ViewController.h" #import "LocalNotificationManager.h" #define CurrenVersiongreaterThan(X) ([[[UIDevice currentDevice] systemVersion] compare:X options:NSNumericSearch] != NSOrderedAscending) @interface ViewController () @property (strong, nonatomic) IBOutlet UIButton *pushBtn; @property (strong, nonatomic) IBOutlet UITextField *idTextField; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self commonInit]; } - (void)commonInit{ } - (IBAction)pushMessage:(UIButton *)sender { if (self.idTextField.text.length == 0) { if (CurrenVersiongreaterThan(@"9.0")) { UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"警告" message:@"请输入ID" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]; [alert addAction:okAction]; [self presentViewController:alert animated:YES completion:nil]; }else{ UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"请输入ID" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; } return; } [LocalNotificationManager insertLocalNotificationToSystemQueueWithNotificationID:self.idTextField.text]; } @end
效果图:
初次打开,弹出提示框,向用户请求本地通知的权限
App在前端时候,AppDelegate里面会接受到一个notification,可以获取里面的信息用Alert来展示
弹框提醒,样式取决于用户在系统中设置的样式
在通知栏中的效果
总结:用完的本地推送,必须删除,然后没有推送的可以储存在数据库或者其他plsit中,对时间要求比较准确或者数量要求更多的,要么推送到系统日历,由日历去提醒。要么就要每次打开APP就去查询数据库,再去遍历数据库中满足条件的推送信息!!
相关文章推荐
- iOS关于本地推送通知的简单用法
- 关于iOS GYDataCenter本地数据库解决方案的那些事儿--上卷
- iOS关于本地推送
- 关于iOS 本地推送的知识二三点
- 关于iOS 9之前的本地推送,本地推送杀掉进程后到底能不能收到?
- 关于ios 推送功能的终极解决
- iOS 推送,证书申请,本地推送
- 个人关于iOS推送通知优化的概念
- 个人关于iOS推送中心优化的概念
- ios 本地推送的添加和取消
- Ios关于推送消息的处理
- iOS推送:实现本地推送
- ios推送:本地通知UILocalNotification
- iOS推送:实现本地推送
- iOS推送:实现本地推送
- IOS本地推送
- ios本地推送方法
- IOS iOS本地推送---常用开发中,通过消息传递信息
- ios 关于推送发布的一些流程
- iOS推送:实现本地推送