Event Kit框架使你能访问用户的Calendar.app和Reminders.app信息。虽然这是两个不同的app,但是他们使用相同的框架处理数据。类似地,存储这些数据的数据库,被称为日历数据库,持有calendar和reminder信息。

Event Kit除了允许你检索用户已经存在的calendar和reminder数据外,还允许你创建新的事件和提醒。另外,还允许你修改和删除事件和提醒。更高级的任务,例如添加警报或指定重复发生的事件,也可以。



一、Reading and Writing Calendar Events:

使用EKEventStore类来获取、创建、修改和删除事件,使用EKEvent类来表示事件。

1、连接到Event Store:

实例化EKEventStore对象:

EKEventStore *store=[[EKEventStore alloc] initWithAccessToEntityTypes:EKEntityMaskEvent];

一个EKEventStore对象需要一段明显的时间来初始化和释放。因此,你不应该为每个事件相关的任务都初始化和释放一个单独的event store。取而代之的,在你的应用加载时,初始化一个event store,并且重复使用它。

event store必须不能在其它的Event Kit对象之前被release,否则未定义的行为可能发生。



2、检索事件

有2个方法检索事件。使用predicate或search query,将返回0或多个事件来匹配给定的查询条件。使用唯一标识符将返回一个单独的事件。

注意:检索的事件不一定按照年代排序。要通过日期排序一组EKEvent对象,调用sortedArrayUsingSelector:方法,并使用selector为compareStartDateWithEvent:方法。



3、使用Predicates:

EKEventStore的方法eventsMatchingPredicate:检索所有的在你提供的日期范围内的事件。



注意:虽然eventsMatchingPredicate:方法接收NSPredicate类型的参数,但是这个NSPredicate必须是通过EKEventStore的方法predicateForEventsWithStartDate:endDate:calendars:方法创建的。



// Get the appropriate calendar

NSCalendar *calendar = [NSCalendar currentCalendar];

 

// Create the start date components

NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];

oneDayAgoComponents.day = -1;

NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents

                                              toDate:[NSDate date]

                                             options:0];

 

// Create the end date components

NSDateComponents *oneYearFromNowComponents = [[NSDateComponents alloc] init];

oneYearFromNowComponents.year = 1;

NSDate *oneYearFromNow = [calendar dateByAddingComponents:oneYearFromNowComponents

                                                   toDate:[NSDate date]

                                                  options:0];

 

// Create the predicate from the event store's instance method

NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo

                                                        endDate:oneYearFromNow

                                                      calendars:nil];

 

// Fetch all events that match the predicate

NSArray *events = [store eventsMatchingPredicate:predicate];



你可以为predicateForEventsWithStartDate:endDate:calendars:方法指定一组EKCalendar对象作为calendars的参数。你可以使用evnet store的calendarsForEntityType:方法 获得用户的calendars.传递nil值告诉方法从用户所有的calendars中获取数据。



因为eventsMatchingPredicate:方法是同步的,所以应该在另外的线程执行。



4、使用唯一标识符

使用EKEventStore的方法eventWithIdentifier:来获取事件。如果这是一个重复发生的事件,这个方法将返回第一个将要发生的事件。你可以通过EKEvent的eventIdentifier属性来获得唯一标识符。



5、创建和修改事件

使用EKEvent类的eventWithEventStore:方法创建一个新的事件

你可以编辑新事件或你之前获得的事件的细节.包括:

1)title属性

2)startDate和endDate属性

3)calendar属性:事件关联的日历

4)alarm属性

5)recurrenceRules属性:默认是不重复的




6、保存和移除事件

如果你要修改用户的日历数据库,必须得到用户的确认。

你对事件所做的更改在你保存它们之前不会永久有效。使用EKEventStore的方法saveEvent:span:commit:error:方法来保存事件。使用removeEvent:span:commit:error:来移除事件。

如果你正在保存一个重复发生的事件,你的更改可以通过指定span参数为EKSpanFutureEvents来将其应用到所有将来发生的事件。同样的,通过指定span参数为EKSpanFutureEvents,你可以移除所有将来发生的事件。



注意:如果你传递NO给commit参数,确保你之后调用commit:方法来永久保存你的更改。



7、执行事件批处理操作:

EKEventStore的enumerateEventsMatchingPredicate:usingBlock:方法允许你执行所有匹配Predicate的事件的批处理操作。你提供的operation是一个block,其类型为EKEventSearchCallback。

typedef void (^EKEventSearchCallback)(EKEvent *event,BOOL *stop)

这个方法同样也会消耗一段时间,建议在另外的线程执行。



二、Reading and Writing Reminders:

Reminder是绑定到特定时间或位置的任务。他们和Calendar事件类似,但是可以被标记为完成,并且可能不需要span一个精确的时间周期。

因为EKReminder继承自EKCalendarItem,因此你可以在一个reminder上执行如同你在事件上执行的相同的方法,例如addAlarm:或通过addRecurrenceRule:来设置recurrence规则.

1、检索Reminders:

要访问Reminders,还是实例化EVEventStore,传递EKEntityMaskReminder 而不是EKEntityMaskEvent

EKEventStore *store=[[EKEventStore alloc] initWithAccessToEntityTypes:EKEntityMaskReminder];



1)使用Predicate检索:

你可以调用fetchRemindersMatchingPredicate:completion:方法。传递的Predicate使用下面方法创建:

a)predicateForInCompleteRemindersWithDueDateStarting:ending:calendars:来查找未完成的reminders

b)predicateForCompleteRemindersWithCompletionDateStarting:ending:calendars:来查找已经完成的reminders

c)predicateForRemindersInCalendars:来查找所有的reminders



你可以在completion block中遍历找到的EKReminder对象

例子:

NSPredicate *predicate = [store predicateForRemindersInCalendars:nil];

 

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

    for (EKReminder *reminder in reminders) {

        // do something for each reminder

    }

}];



2)使用唯一标识符

calendarItemWithIdentifier:方法可以查找所有的calendar item(包括Reminder和Events),而eventWithIdentifier:只查询events。



2、创建和编辑Reminders:

你可以使用EKEventStore的reminderWithEventStore:类方法来创建reminder,title和calendar属性是必须的。

startDateComponents和dueDateComponents属性。

要完成一个reminder,设置completed属性为YES,这回自动地设置completionDate为当前日期。



3、保存和移除Reminders:

这也需要用户确认。

saveReminder:commit:error:方法和removeReminder:commit:error:方法。

记住,在你保存你的reminder之前,必须设置title和calendar属性。



三、配置Alarms

不管当前运行的是哪个程序,alarm会作为一个通知来到前台来提醒用户。如果一个alarm被设置到一个日历事件中,那么通知来自于Calendar.app;如果alarm被设置到一个reminder中,那么通知来自于Reminders.app。Alarms可以是基于时间的,在某个特定的时间发射,或基于位置的,当经过某个迪兰围栏(geofence)时发射。

事件和Reminder都可以设置alarm。



1、Attaching and Removing Alarms:

addAlarm:方法。Alarm可以使用绝对日期和相对日期创建。

removeAlarm:方法来移除。

在OS X中,你可以触发一个alarm动作。例如,设置:

1)emailAddress属性来发送一封邮件

2)soundName属性来播放一个声音

3)url属性来打开一个URL。



2、设置Geofences:

注意:OS X和iOS都支持Geofence,但是他们在移动设备上更有效。

一个geofence是一个虚拟的包围一个地理位置的border,当穿越它时,可以触发一个事件的alarm。作为一个开发者,你需要控制center的纬度和经度,和geofence的半径。

调用locationWithTItle:方法来创建一个结构化的location。要设置经度和纬度 coordinates,传递一个CLLocation给结构化的location的geoLocation属性。radius属性为0表示系统默认的半径;单位为米。

这对Reminders很有实际意义。



四、创建重复发生的事件:

重复发生的规则使用EKRecurrenceRule类来表示。

calendar event和reminder都可以使用Recurrence。



1、使用基本的规则:

你可以创建一个简单recurrence规则,使用daily、weekly、monthly或yearly,使用initRecurrenceWithFrequency:interval:end:方法。你可以在这个方法中提供3个值:

1)recurrence frequency:这个值是EKRecurrenceFrequency类型,指示recurrence是daily、weekly、monthly或yearly.

2)recurrence interval: 这是一个大于0的整数,来制定重复的间隔。例如,如果recurrence rule是weekly,并且recurrence interval是1,然后重复模式为每星期都重复。如果recurrence interval是3,那么是每3个星期重复一次。

3)recurrence end: 这是个可选参数,是一个EKRecurrenceEnd类的对象,它指示recurrence rules何时终止。



2、使用复合规则:

使用

initRecurrenceWithFrequency:interval:daysOfTheWeek:daysOfTheMonth:monthsOfTheYear:weeksOfTheYear::daysOfTheYear:setPostions:end:

方法。在这个方法里,你可以提供额外的可选值的组合来描述一个特定的规则:



days   为 一组 EKRecurrenceDayOfWeek对象,      可以和除了daily recurrence以外的rule组合  ,例子:一个包含EKTuesday和EKFriday对象的array将创建一个每个周二和周五发生的规则。



monthDays  为一组非0的NSNumber对象,从-31到31.负值表示从当前月的结尾向前计算,可以和Monthly 规则组合,例子:一个包含1和-1的array,将创建每个月第一天和最后一天发生的规则。



months 为一组1到12的NSNumber对象,对应格里高里日历的月份,可以和Yearly组合。



weeksOfTheYear 为一组非0的NSNumber对象,从-53到53。负值表示从一年的最后一个礼拜向前计算。可以和Yearly组合。



daysOfTheYear 为一组非0NSNumber对象,从-366到366. 可以和Yearly组合



setPositions: 为一组非0NSNumber对象,从-366到366.负值表示反向计算。可以和除了daily规则之外的所有规则组合。例子:如果你提供了一个包含1和-1的array到一个yearly规则,并且指定了周一到周五的daysOfTheWeek,那么重复发生只在第一周和最后一周。也就是说这个参数过滤其它规则的过滤器。



你可以提供任意的number参数值,不能应用的参数会被忽略。If you provide a value for more than one of the above parameters, the recurrence occurs only on days that apply to all provided values.



一旦你创建了一个recurrence rule,你可以应用它到事件和reminder上,通过EKCalendarItem的addRecurrenceRule:实例方法。



五、观察外部的日历数据库的更改:

1、注册通知:

一个EKEventStore对象发布EKEventStoreChangedNotification通知。

[[NSNotificationCenter defaultCenter] addObserver:self

                                         selector:@selector(storeChanged:)

                                             name:EKEventStoreChangedNotification

                                           object:eventStore];



2、响应通知:

当你收到一个EKEventStoreChangedNotification通知时,可能你已经获取到的对象--例如EKEvent、EKReminder或EKCalendar--已经改变了。这些更改的效果基于事件是添加、修改还是删除。

1)如果一个event被添加了。这不影响你现有的获取到的事件和reminder,但是新添加的event可能不会显示给用户(因为你是在新添加的event之前获取的数据)。

2)如果event被修改了或删除了,表示那个event的EKEvent和EKReminder对象的属性将变得过期。



因为在你收到EKEventStoreChangedNotification通知时,也就是在日历数据库发生更改时,你的本地数据经常被无效或未完成,所以你应该重新获取你当前日期范围的events。如果你正在修改一个event并且你不想重新获取它除非绝对需要这样做,你可以调用日历事件的refresh方法。如果这个方法返回YES,你可以继续使用这个日历事件,否则,你应该重新获取它。



六、提供事件的Interface

注意:这章讨论的Event Kit UI 框架只适用于iOS,在OS X中,你需要自己创建界面。



Event Kit UI 框架提供了两种类型的View Controller来管理事件:

1)EKEventViewController: 来显示一个已经存在的事件

2)EKEventEditViewController: 来创建、修改和删除事件




1、显示Event数据:

使用EKEventViewController。你需要在显示view controller之前,设置event属性,和其它显示属性。例子:

    EKEventViewController *eventViewController = [[EKEventViewController alloc] init];

    eventViewController.event = myEvent;

    eventViewController.allowsEditing = YES;

    navigationController = [[UINavigationController alloc] initWithRootViewController:eventViewController];



你需要指定一个delegate给event view controller,在用户完成查看事件时接收通知。代理遵循EKEventViewDelegate协议并且必须实现eventViewController:didCompleteWithAction:方法。



2、修改Event数据:

使用EKEventEditViewController和EKEventEditViewDelegate协议。像创建EKEventViewController一样创建EKEventEditViewController,除了你必须设置eventStore属性(设置event属性为可选的)

1)如果event属性为nil,那么用户创建一个新的event,在默认的calendar并保存它到指定的event store。

2)如果event属性不为nil,那么用户编辑这个event。这个event必须存在于指定的event store。否则发生异常。

例子:

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

    controller.eventStore = myEventStore;

    controller.editViewDelegate = self;

    [self presentModalViewController:controller animated:YES];



代理函数:eventEditViewController:didCompleteWithAction: 一般在这个函数中取消modal的view controller。

action参数指定用户是cancel还是save,还是delete。

关于Calendar和Reminder(日历和提醒)编程指南的更多相关文章

  1. iCloud 包括文稿与数据、日历、提醒事项、 通讯录、备忘录、Safari书签

    iCloud 能够为用户在设备间同步数据和在服务器上保存数据.当前 iCloud 包括文稿与数据.日历.提醒事项. 通讯录.备忘录.Safari书签.阅读列表.iCloud Tabs.iBooks书签 ...

  2. Java Calendar实现控制台日历

    public static void main(String[] args) throws IOException { //初始化日历对象 Calendar calendar = Calendar.g ...

  3. [转]ODBC编程指南

    DM4 ODBC编程指南本章结合DM4数据库的特点,比较全面系统的介绍ODBC的基本概念以及DM4 ODBC DRIVER的使用方法,以便用户更好地使用DM4 ODBC编写应用程序.ODBC提供给你访 ...

  4. 如何:使用 as 和 is 运算符安全地进行强制转换(C# 编程指南)

    如何:使用 as 和 is 运算符安全地进行强制转换(C# 编程指南) 由于对象是多态的,因此基类类型的变量可以保存派生类型.若要访问派生类型的方法,需要将值强制转换回该派生类型.不过,在这些情况下, ...

  5. OpenGL编程指南(第七版)

    OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...

  6. 编译opengl编程指南第八版示例代码通过

    最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...

  7. 高质量C++/C编程指南(林锐)

    推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐   2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐   20 ...

  8. iOS ---Extension编程指南

    当iOS 8.0和OS X v10.10发布后,一个全新的概念出现在我们眼前,那就是应用扩展.顾名思义,应用扩展允许开发者扩展应用的自定义功能和内容,能够让用户在使用其他app时使用该项功能.你可以开 ...

  9. Lambda 表达式(C# 编程指南) 微软microsoft官方说明

    Visual Studio 2013 其他版本 Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地 ...

随机推荐

  1. HDU 4014 Jimmy’s travel plan(图计数)

    Jimmy’s travel plan Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Oth ...

  2. Keyboarding (bfs+预处理+判重优化)

    # #10030. 「一本通 1.4 练习 2」Keyboarding [题目描述] 给定一个 $r$ 行 $c$ 列的在电视上的"虚拟键盘",通过「上,下,左,右,选择」共 $5 ...

  3. 2019 Multi-University Training Contest 3 - 1006 - Fansblog - 打表 - 暴力

    http://acm.hdu.edu.cn/showproblem.php?pid=6608 题意:给一个比较大的质数P(1e14以内),求比它小的最大的质数Q(貌似保证存在的样子,反正我没判不存在) ...

  4. 回溯---N皇后

    N 皇后 51. N-Queens (Hard) 题目描述:   在n*n的矩阵中摆放n个皇后,并且每个皇后不能在同一列,同一个对角线上,求所有的n皇后解. 思路分析:   一行一行地摆放,在确定一行 ...

  5. Elasticsearch7.X 入门学习第二课笔记----基本api操作和CRUD

    原文:Elasticsearch7.X 入门学习第二课笔记----基本api操作和CRUD 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链 ...

  6. 剑指offer--字符串

    C/C++中每个字符串都以字符'\0'作为结尾,这样我们就可以很方便的找到字符串最后的尾部.由于这个特点,每个字符串中都有一个额外字符的开销,稍不留神就会造成字符串的越界. 为了节省内存,C/C++把 ...

  7. adb 链接网络 connect 安装apk install 断开IP链接 kill-server 连接数devices

    https://blog.csdn.net/zhonglunshun/article/details/78362439 ./adb connetc 192.168.1.11 ./adb install ...

  8. python OpenCV视频的读取及保存

    import cv2 cap = cv2.VideoCapture('rtsp://admin:hik12345@192.168.3.160/Streaming/Channels/1') fourcc ...

  9. 安装运行谷歌开源的TensorFlow Object Detection API视频物体识别系统

    Linux安装 参照官方文档:https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/inst ...

  10. atomic,nonatomic

    atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作.         atomic 设置成员变量的@property属性时,默认为atomic,提供多线程安全 ...