最近项目要使用提醒服务,研究了一下EKEvent,记录下来,以备以后查找
首先 Info.plist文件中注册权限
<key>NSCalendarsUsageDescription</key>
<string>调用日历权限</string>
<key>NSRemindersUsageDescription</key>
<string>调用提醒事件</string>
申请了权限之后,就可以创建事件了,直接上代码
首先导入头文件
import <EventKit/EventKit.h>
第一步
///生成事件数据库对象
EKEventStore *store = [[EKEventStore alloc] init];
第二步
//申请事件类型权限
//EKEntityTypeEvent 事件类型
//EKEntityTypeReminder 提醒类型
[store requestAccessToEntityType:(EKEntityTypeEvent) completion:^(BOOL granted, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
第三步
判断时间类型权限结果,有权限情况下,去创建事件
if (error) {
NSLog(@"添加失败,,错误了。。。");
} else if (!granted) {
NSLog(@"不允许使用日历,没有权限");
} else {
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = @"这是一个 title";
event.location = @"这是一个 location";
event.notes = @"这是一个 notes";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [formatter dateFromString:@"2019-04-13 11:22:33"];
// 提前一个小时开始
NSDate *startDate = [NSDate dateWithTimeInterval:-3600 sinceDate:date];
// 提前一分钟结束
NSDate *endDate = [NSDate dateWithTimeInterval:60 sinceDate:date];
event.startDate = startDate;
event.endDate = endDate;
event.allDay = NO;
// 添加闹钟结合(开始前多少秒)若为正则是开始后多少秒。
EKAlarm *elarm2 = [EKAlarm alarmWithRelativeOffset:-20];
[event addAlarm:elarm2];
EKAlarm *elarm = [EKAlarm alarmWithRelativeOffset:-10];
[event addAlarm:elarm];
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *error = nil;
[store saveEvent:event span:EKSpanThisEvent error:&error];
if (!error) {
NSLog(@"添加时间成功");
//添加成功后需要保存日历关键字
NSString *iden = event.eventIdentifier;
// 保存在沙盒,避免重复添加等其他判断
[[NSUserDefaults standardUserDefaults] setObject:iden forKey:@"my_eventIdentifier"];
[[NSUserDefaults standardUserDefaults] synchronize];
}else{
NSLog(@"添加时间失败:%@",error);
}
}
});
}];
另外我们可以根据id在事件数据库中查询事件
EKEventStore *myEventStore = [[EKEventStore alloc] init];
// 获取上面的这个ID呀。
NSString *identifier = [NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"my_eventIdentifier"]];
EKEvent *event = [myEventStore eventWithIdentifier:identifier];
NSLog(@"查询到的事件 :%@",event);
既然是数据库 肯定增删改查都是可以,上边两个是增加和查找,我们接着说修改和删除,既然我们可以查找到事件,就可以拿当前时间去修改,删除。
修改
EKEvent *event = [self queryEKEventForIdentifier];
if (event) {
event.title = @"修改的标题";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [formatter dateFromString:@"2019-05-13 11:22:33"];
// 提前一个小时开始
NSDate *startDate = [NSDate dateWithTimeInterval:-3600 sinceDate:date];
// 提前一分钟结束
NSDate *endDate = [NSDate dateWithTimeInterval:60 sinceDate:date];
event.startDate = startDate;
event.endDate = endDate;
[event setCalendar:[self.myEventStore defaultCalendarForNewEvents]];
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
[self.myEventStore saveEvent:event span:EKSpanThisEvent error:&error];
if (!error) {
NSLog(@"修改成功");
}else{
NSLog(@"添加时间失败:%@",error);
}
});
}
删除
__block EKEvent *event = [self queryEKEventForIdentifier];
__block BOOL isDeleted = NO;
dispatch_async(dispatch_get_main_queue(), ^{
NSError *err = nil;
isDeleted = [self.myEventStore removeEvent:event span:EKSpanThisEvent commit:YES error:&err];
if (!err && isDeleted) {
NSLog(@"删除日历成功");
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"my_eventIdentifier"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
});
除了可以日历事件,还可以添加提醒事件
//申请提醒权限
[self.myEventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
//创建一个提醒功能
EKReminder *reminder = [EKReminder reminderWithEventStore:self.myEventStore];
//标题
reminder.title = title;
//添加日历
[reminder setCalendar:[self.myEventStore defaultCalendarForNewReminders]];
NSCalendar *cal = [NSCalendar currentCalendar];
[cal setTimeZone:[NSTimeZone systemTimeZone]];
NSInteger flags = NSCalendarUnitYear | NSCalendarUnitMonth |
NSCalendarUnitDay |NSCalendarUnitHour | NSCalendarUnitMinute |
NSCalendarUnitSecond;
NSDateComponents* dateComp = [cal components:flags fromDate:date];
dateComp.timeZone = [NSTimeZone systemTimeZone];
reminder.startDateComponents = dateComp; //开始时间
reminder.dueDateComponents = dateComp; //到期时间
reminder.priority = 1; //优先级
NSMutableArray *weekArr = [NSMutableArray array];
NSArray *weeks = @[@1,@2,@3];//1代表周日以此类推
// 也可以写成NSArray *weekArr = @[@(EKWeekdaySunday),@(EKWeekdayMonday),@(EKWeekdayTuesday)];
[weeks enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
EKRecurrenceDayOfWeek *daysOfWeek = [EKRecurrenceDayOfWeek dayOfWeek:obj.integerValue];
[weekArr addObject:daysOfWeek];
}];
//创建重复需要用到 EKRecurrenceRule
//EKRecurrenceFrequencyDaily, 周期为天
//EKRecurrenceFrequencyWeekly, 周期为周
//EKRecurrenceFrequencyMonthly, 周期为月
//EKRecurrenceFrequencyYearly 周期为年
// EKRecurrenceRule *rule = [[EKRecurrenceRule alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyWeekly interval:1 daysOfTheWeek:weekArr daysOfTheMonth:nil monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:nil];
//每天
EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:(EKRecurrenceFrequencyDaily) interval:1 end:nil];
[reminder addRecurrenceRule:rule];
EKAlarm *alarm = [EKAlarm alarmWithAbsoluteDate:date]; //添加一个闹钟
[reminder addAlarm:alarm];
NSError *err;
[self.myEventStore saveReminder:reminder commit:YES error:&err];
if (err) {
}
}
}];
另外我们可以直接唤起系统的创建 事件UI,需要导入头文件
import <EventKitUI/EventKitUI.h>
EKEventStore *eventStore = self.myEventStore;
if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
//EKEntityTypeEvent 事件页面
//EKEntityTypeReminder 提醒页面
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,NSError* error){
if(!granted){
dispatch_async(dispatch_get_main_queue(), ^{
//TODO: 提示需要权限
});
}else{
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = @"日历标题";
EKCalendar* calendar;
calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
NSError* error;
[eventStore saveCalendar:calendar commit:YES error:&error];
EKEventEditViewController *addController = [[EKEventEditViewController alloc] initWithNibName:nil bundle:nil];
addController.event = event;
addController.eventStore = eventStore;
[self presentViewController:addController animated:YES completion:nil];
addController.editViewDelegate = self;
}
}];
}
记得实现代理方法
#pragma mark - eventEditDelegates -
- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action{
if (action ==EKEventEditViewActionCanceled) {
[self dismissViewControllerAnimated:YES completion:nil];
}
if (action==EKEventEditViewActionSaved) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}
另附demo地址
demo地址