您的位置:首页 > 移动开发 > IOS开发

关于iOS本地推送的那些事儿

2016-08-11 17:42 316 查看
最近在做一个项目,需要大量的本地推送,本地推送有一个坑,就是iOS系统限制了注册本地推送的数量,最大的注册量为64条,没有那么多的容量供我们挥霍。网上相关的文章比较少提到推送数量限制。

不说废话,请看代码

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就去查询数据库,再去遍历数据库中满足条件的推送信息!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: