iOS Calendars and Reminders (向系統(tǒng)日歷添加事件)

Demo地址

一、簡介

蘋果官方關(guān)于日歷和提醒簡介

Important:An iOS app linked on or after iOS 10.0 must include in itsInfo.plistfile the usage description keys for the types of data it needs to access or it will crash. To access Reminders and Calendar data specifically, it must includeNSRemindersUsageDescriptionandNSCalendarsUsageDescription, respectively.

To access the user’s Calendar data

提示:iOS 10 之后如果app 想要訪問日歷和提醒事項(xiàng),我們必須在 我們的app 的Info.plist文件中添加NSRemindersUsageDescription和NSCalendarsUsageDescription的key否則app會閃退。

The EventKit framework helps you access users’ Calendar and Reminders information. Although two different apps display users’ calendar and reminder data, the same framework manipulates the data. Similarly, the database that stores this data, called the Calendar database, holds both calendar and reminder information.

EventKit 可以幫助你訪問用戶的日歷和提醒事項(xiàng)的信息,日歷和提醒事項(xiàng)使用相同的框架來訪問一個(gè)叫做Calendar database 的數(shù)據(jù)庫。

EventKit not only allows your app to retrieve users’ existing calendar and reminder data, but it also lets your app create new events and reminders for any of their calendars. In addition, EventKit lets users edit and delete their events and reminders (collectively known as “calendar items”). More advanced tasks, such as adding alarms or specifying recurring events, can be achieved with EventKit as well. If a change to the Calendar database occurs from outside of your app, EventKit is able to detect the change by notification so your app can act appropriately. Changes made to calendar items with EventKit are automatically synced to the associated calendar (CalDAV, Exchange, and so on).

This document describes EventKit concepts and common programming tasks. You should read this document if you want to display or edit calendar events and/or reminder data from within your app. EventKit provides limited access to a user’s Calendar database; it does not include everything that would be desired for implementing a full-featured calendar or reminder app, such as adding attendees or accounts.

EventKit? 允許你的app 訪問已經(jīng)存在于日歷和提醒里面的事件,同時(shí)也允許你的app創(chuàng)建一個(gè)提醒事件添加到日歷或者提醒中。用戶可以編輯刪除日歷和提醒里面的事件。EventKit 還可以添加鬧鈴,和重復(fù)提醒的事件。

注意:EKEvent 和 EKReminder都繼承于EKCalendarItem, EKCalendarItem類是日歷事件和提醒的抽象超類,此類提供常用的屬性和方法來訪問日歷項(xiàng)的屬性,例如設(shè)置日歷的功能,標(biāo)題和位置,以及支持附加注釋,顯示與會者,設(shè)置多個(gè)鬧鐘和指定重復(fù)規(guī)則。EKCalendarItem 的calendarItemIdentifier 是它唯一標(biāo)示,使用EKCalendarItem *item = [store calendarItemWithIdentifier:identifer];可以通過一個(gè)唯一標(biāo)示獲取一個(gè)EKCalendarItem對象。

二、讀取日歷和提醒中已存在的事件

??注意:因?yàn)?EventStore 是 Calendar database 的數(shù)據(jù)庫引擎,所以應(yīng)該盡量少的對他進(jìn)行創(chuàng)建和銷毀,所以推薦使用EventStore的時(shí)候使用單例模式

讀取日歷中的事件官方文檔

You can fetch, create, edit, and delete events from a user’s Calendar database using theEKEventStoreclass. You can fetch a custom set of events that match a predicate you provide, or you can fetch an individual event by its unique identifier. After you fetch an event, you can access its associated calendar information with the properties of theEKEventclass. Like wise, you can modify its calendar information by setting the properties of theEKEventclass.?

你可以使用EKEventStoreclass進(jìn)行 查詢、創(chuàng)建、編輯和刪除 用戶存于 Calendar database 中的事件,你可以使用謂詞來查詢出符合條件的事件集或者使用一個(gè)唯一標(biāo)示來查詢一個(gè)指定的事件。獲取事件之后你可以對他進(jìn)行一些操作。

1、使用謂詞查詢?nèi)諝v里面的某個(gè)時(shí)間范圍內(nèi)的事件

It’s common to fetch events that fall within a date range. TheEKEventStoremethodeventsMatchingPredicate:fetches all events that fall within the date range specified in the predicate you provide.(EKEventStore 可以查詢謂詞所提供的日期范圍內(nèi)的事件)。?

示例代碼如下

+(NSArray*)fetchEventsWithStartDate:(NSDate*)startDate endDate:(NSDate*)enDate{

EKEventStore*store = [STCalendarReminderToolshareinstance];

NSPredicate*predicate = [storepredicateForEventsWithStartDate:startDateendDate:enDatecalendars:nil];

NSArray*events = [storeeventsMatchingPredicate:predicate];

NSIntegeri =1;

for(EKEvent*eventinevents) {

NSLog(@"第%zd個(gè)提醒%@",i,event);

i++;

}

returnevents;

}

2、使用唯一標(biāo)示來查詢事件

Using Unique Identifiers

If you know the event’s unique identifier because you fetched it previously with a predicate, you can use theEKEventStoremethodeventWithIdentifier:to fetch the event. If it is a recurring event, this method will return the first occurrence of the event. You can get an event’s unique identifier with theeventIdentifierproperty.

??這種方式只能用來查詢?nèi)諝v里面的事件

?示例代碼:

+(EKEvent*)fetchEventWithIdentifer:(NSString*)eventidentifer{

EKEventStore*store = [STCalendarReminderToolshareinstance];

EKEvent*event = [storeeventWithIdentifier:eventidentifer];

returnevent;

}

三、向日歷中添加一個(gè)新的事件

添加新的事件官方文檔

Create a new event with the eventWithEventStore: method of the EKEvent class.

You can edit the details of a new event or an event you previously fetched from the Calendar database by setting the event’s corresponding properties. Some of the details you can edit include:

The event’s title with the title property

The event’s start and end dates with the startDate and endDate properties

The calendar with which the event is associated with the calendar property

The alarms associated with the event with the alarms property (see Configuring Alarms for more details)

The event’s recurrence rule, if it is a repeating event, with the recurrenceRules property (see Creating Recurring Events for more details)

示例代碼如下:

/**

* STCalendarReminderToolSaveSuccessBlock

* eventIdentifier

*/

typedef void (^STCalendarReminderToolSaveSuccessBlock)(NSString* eventIdentifier);

typedef void (^STCalendarReminderToolSaveFailBlock)(NSError *err);

/** 向日歷添加一個(gè)事件

* title? 事件標(biāo)題

* notes? 事件備注

* location 事件地址

* startDate 開始日期

* endDate? 結(jié)束日期

* alarms 鬧鐘

* availability 事件調(diào)度

*/

+(void)saveEventWithTitle:(NSString *)title? ? ? ? ? ? ? ? ?

?? notes:(NSString *)notes? ? ? ? ? ? ?

?? location:(NSString *)location? ? ? ? ? ?

?? ? startDate:(NSDate *)startDate? ? ? ? ? ?

?? ? ? endDate:(NSDate *)endDate? ? ? ? ? ? ? ?

?? alarms:(NSArray*)alarms{

URL:(NSURL *)URL

availability:(EKEventAvailability)availability

successBlock:(STCalendarReminderToolSaveSuccessBlock)successBlock

failBlock:(STCalendarReminderToolSaveFailBlock)failBlock{

EKEventStore *store = [STCalendarReminderTool shareinstance];

[store requestAccessToEntityType:EKEntityTypeEvent

completion:

^(BOOL granted, NSError *error) {

dispatch_async(dispatch_get_main_queue(), ^{

if (error) {

//錯(cuò)誤信息

return;

}

if (!granted) {

//被用戶拒絕,不允許訪問日歷

return;

}

EKEvent *event = [EKEvent eventWithEventStore:store];

event.title = title;

event.notes = notes;

event.availability = availability;

event.startDate = startDate;

event.endDate = endDate;

event.location? = location;

event.alarms = alarms;

event.calendar = store.defaultCalendarForNewEvents;

event.URL = URL;

NSError *err = nil;

[store saveEvent:event span:EKSpanThisEvent error:&err];

if (!err) {

if (successBlock) {

successBlock(event.eventIdentifier);

}

}else{

if (failBlock) {

failBlock(err);

}

}

NSLog(@"eventIdentifier %@",event.eventIdentifier);

});

}];

}

四、刪除事件


+(BOOL)deleteEventWithEventIdentifier:(NSString *)eventIdentifier{

EKEventStore *store = [STCalendarReminderTool shareinstance];

EKEvent *event = [store eventWithIdentifier:eventIdentifier];

// YES立即刪除事件;否則,更改將批處理,直到調(diào)用commit:方法。

return? [store removeEvent:event span:EKSpanThisEvent commit:YES error:nil];

}

五、查詢提醒

5.1 使用謂詞查詢一個(gè)時(shí)間范圍里的提醒

EKEventStore *store = [STCalendarReminderTool shareinstance];

NSPredicate *predicate = [store predicateForIncompleteRemindersWithDueDateStarting:starDate

ending:endDate

calendars:[store calendarsForEntityType:EKEntityTypeReminder]];

[store fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {

}];

5.2使用謂詞 查詢所有的提醒

EKEventStore *store? ? ? = [STCalendarReminderTool shareinstance];

NSPredicate? *predicate? = [store predicateForRemindersInCalendars:nil];

[store fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {

NSInteger i = 1;

for (EKReminder *reminder in reminders) {

}

}];

5.3 使用唯一標(biāo)示查詢提醒

EKReminder 是繼承于EKCalendarItem的(??我這里也沒有查到用唯一標(biāo)示查詢返回EKReminder的方法相關(guān)資料,我的做法是查詢到EKCalendarItem然后把它強(qiáng)轉(zhuǎn)成EKReminder),使用這個(gè)方法也可以查詢?nèi)諝v里面的事件。

+(EKCalendarItem *)fetchReminderWithIdentier:(NSString *)identifer{

EKEventStore *store = [STCalendarReminderTool shareinstance];

EKCalendarItem *item = [store calendarItemWithIdentifier:identifer];

NSLog(@"item? item %@",item);

return item;

}

六、添加新的提醒和刪除提醒

6.1添加新的提醒

示例代碼:

/**

* STCalendarReminderToolSaveSuccessBlock

* eventIdentifier

*/

typedef void (^STCalendarReminderToolSaveSuccessBlock)(NSString* eventIdentifier);

typedef void (^STCalendarReminderToolSaveFailBlock)(NSError *err);

/*

* title? 事件標(biāo)題

* notes? 事件備注

* startDate 開始日期

* endDate? 結(jié)束日期

* alarms 鬧鐘

* priority 事件調(diào)度(1-4 高 5中? 6-9低? 0 不設(shè)置)

* completed

*/

+(void)saveEventIntoReminderWithTitle:(NSString *)title

notes:(NSString *)notes

startDate:(NSDate *)startDate

endDate:(NSDate *)endDate

alarm:(EKAlarm *)alarm

priority:(NSInteger)priority

completed:(BOOL)completed

successBlock:(STCalendarReminderToolSaveSuccessBlock)successBlock

failBlock:(STCalendarReminderToolSaveFailBlock)failBlock{

EKEventStore *store = [STCalendarReminderTool shareinstance];

[store requestAccessToEntityType:EKEntityTypeReminder

completion:

^(BOOL granted, NSError *error) {

dispatch_async(dispatch_get_main_queue(), ^{

if (error) {

if (failBlock) {

failBlock(error);

}

return;

}

if (!granted) {

//被用戶拒絕,不允許訪問提醒

return;

}

EKReminder *reminder = [EKReminder reminderWithEventStore:store];

[reminder setCalendar:[store defaultCalendarForNewReminders]];

reminder.title? ? ? = title;

reminder.notes? ? ? = notes;

reminder.completed? = completed;

reminder.priority? ? = priority;

[reminder addAlarm:alarm];

NSCalendar *calender = [NSCalendar currentCalendar];

[calender setTimeZone:[NSTimeZone systemTimeZone]];

NSInteger flags? ? ? = NSCalendarUnitYear | NSCalendarUnitMonth |

NSCalendarUnitDay |NSCalendarUnitHour | NSCalendarUnitMinute |

NSCalendarUnitSecond;

NSDateComponents* startDateComp = [calender components:flags fromDate:startDate];

startDateComp.timeZone = [NSTimeZone systemTimeZone];

reminder.startDateComponents = startDateComp;

NSDateComponents* endDateComp = [calender components:flags fromDate:startDate];

endDateComp.timeZone? = [NSTimeZone systemTimeZone];

reminder.dueDateComponents = endDateComp;

NSError *err;

[store saveReminder:reminder commit:YES error:&err];

if (!err) {

if (successBlock) {

successBlock(reminder.calendarItemIdentifier);

}

}else{

if (failBlock) {

failBlock(err);

}

}

});

}];

}

6.2 刪除一個(gè)提醒

+(BOOL)deleteReminderWithIdentifer:(NSString *)identifier{

EKEventStore *store = [STCalendarReminderTool shareinstance];

EKCalendarItem *item = [store calendarItemWithIdentifier:identifier];

EKReminder *reminder = (EKReminder *)item;

return? [store removeReminder:reminder commit:YES error:nil];

}

七、使用系統(tǒng)提供的視圖控制器添加、修改或刪除事件


先導(dǎo)入#import <EventKitUI/EventKitUI.h>

7.1添加一個(gè)事件

EKEventEditViewController *editVC = [[EKEventEditViewController alloc] init];

editVC.eventStore = [STCalendarReminderTool shareStoreinstance];

editVC.editViewDelegate = self;

[self presentViewController:editVC animated:YES completion:nil];

遵循EKEventEditViewDelegate 代理

實(shí)現(xiàn)代理方法

#pragma -mark EKEventEditViewDelegate

-(void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action{

[self dismissViewControllerAnimated:YES completion:^{

}];

}

7.2 修改事件

如果要修改一個(gè)事件直接把他傳給EKEventEditViewController,如下:

EKEventEditViewController *editVC = [[EKEventEditViewController alloc] init];

editVC.eventStore = [STCalendarReminderTool shareStoreinstance];

editVC.editViewDelegate = self;

editVC.event? ? ? = event;

[self presentViewController:editVC animated:YES completion:nil];

其他操作和新加一個(gè)事件的一致。

八、總結(jié)

寫的有不好的地方希望大家指出,我會修正的,大家有什么看不明白的也可以在評論里面提問,我會盡力解答。

Demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容