最近項(xiàng)目要使用提醒服務(wù),研究了一下EKEvent,記錄下來(lái),以備以后查找
首先 Info.plist文件中注冊(cè)權(quán)限
<key>NSCalendarsUsageDescription</key>
<string>調(diào)用日歷權(quán)限</string>
<key>NSRemindersUsageDescription</key>
<string>調(diào)用提醒事件</string>
申請(qǐng)了權(quán)限之后,就可以創(chuàng)建事件了,直接上代碼
首先導(dǎo)入頭文件
import <EventKit/EventKit.h>
第一步
///生成事件數(shù)據(jù)庫(kù)對(duì)象
EKEventStore *store = [[EKEventStore alloc] init];
第二步
//申請(qǐng)事件類型權(quán)限
//EKEntityTypeEvent 事件類型
//EKEntityTypeReminder 提醒類型
[store requestAccessToEntityType:(EKEntityTypeEvent) completion:^(BOOL granted, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
第三步
判斷時(shí)間類型權(quán)限結(jié)果,有權(quán)限情況下,去創(chuàng)建事件
if (error) {
NSLog(@"添加失敗,,錯(cuò)誤了。。。");
} else if (!granted) {
NSLog(@"不允許使用日歷,沒有權(quán)限");
} else {
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = @"這是一個(gè) title";
event.location = @"這是一個(gè) location";
event.notes = @"這是一個(gè) notes";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [formatter dateFromString:@"2019-04-13 11:22:33"];
// 提前一個(gè)小時(shí)開始
NSDate *startDate = [NSDate dateWithTimeInterval:-3600 sinceDate:date];
// 提前一分鐘結(jié)束
NSDate *endDate = [NSDate dateWithTimeInterval:60 sinceDate:date];
event.startDate = startDate;
event.endDate = endDate;
event.allDay = NO;
// 添加鬧鐘結(jié)合(開始前多少秒)若為正則是開始后多少秒。
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(@"添加時(shí)間成功");
//添加成功后需要保存日歷關(guān)鍵字
NSString *iden = event.eventIdentifier;
// 保存在沙盒,避免重復(fù)添加等其他判斷
[[NSUserDefaults standardUserDefaults] setObject:iden forKey:@"my_eventIdentifier"];
[[NSUserDefaults standardUserDefaults] synchronize];
}else{
NSLog(@"添加時(shí)間失敗:%@",error);
}
}
});
}];
另外我們可以根據(jù)id在事件數(shù)據(jù)庫(kù)中查詢事件
EKEventStore *myEventStore = [[EKEventStore alloc] init];
// 獲取上面的這個(gè)ID呀。
NSString *identifier = [NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"my_eventIdentifier"]];
EKEvent *event = [myEventStore eventWithIdentifier:identifier];
NSLog(@"查詢到的事件 :%@",event);
既然是數(shù)據(jù)庫(kù) 肯定增刪改查都是可以,上邊兩個(gè)是增加和查找,我們接著說修改和刪除,既然我們可以查找到事件,就可以拿當(dāng)前時(shí)間去修改,刪除。
修改
EKEvent *event = [self queryEKEventForIdentifier];
if (event) {
event.title = @"修改的標(biāo)題";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [formatter dateFromString:@"2019-05-13 11:22:33"];
// 提前一個(gè)小時(shí)開始
NSDate *startDate = [NSDate dateWithTimeInterval:-3600 sinceDate:date];
// 提前一分鐘結(jié)束
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(@"添加時(shí)間失敗:%@",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];
}
});
除了可以日歷事件,還可以添加提醒事件
//申請(qǐng)?zhí)嵝褭?quán)限
[self.myEventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
//創(chuàng)建一個(gè)提醒功能
EKReminder *reminder = [EKReminder reminderWithEventStore:self.myEventStore];
//標(biāo)題
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; //開始時(shí)間
reminder.dueDateComponents = dateComp; //到期時(shí)間
reminder.priority = 1; //優(yōu)先級(jí)
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];
}];
//創(chuàng)建重復(fù)需要用到 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]; //添加一個(gè)鬧鐘
[reminder addAlarm:alarm];
NSError *err;
[self.myEventStore saveReminder:reminder commit:YES error:&err];
if (err) {
}
}
}];
另外我們可以直接喚起系統(tǒng)的創(chuàng)建 事件UI,需要導(dǎo)入頭文件
import <EventKitUI/EventKitUI.h>
EKEventStore *eventStore = self.myEventStore;
if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
//EKEntityTypeEvent 事件頁(yè)面
//EKEntityTypeReminder 提醒頁(yè)面
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,NSError* error){
if(!granted){
dispatch_async(dispatch_get_main_queue(), ^{
//TODO: 提示需要權(quán)限
});
}else{
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = @"日歷標(biāo)題";
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;
}
}];
}
記得實(shí)現(xiàn)代理方法
#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地址