关于Calendar和Reminder(日历和提醒)编程指南
Event Kit框架使你能访问用户的Calendar.app和Reminders.app信息。虽然这是两个不同的app,但是他们使用相同的框架处理数据。类似地,存储这些数据的数据库,被称为日历数据库,持有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(日历和提醒)编程指南的更多相关文章
- iCloud 包括文稿与数据、日历、提醒事项、 通讯录、备忘录、Safari书签
iCloud 能够为用户在设备间同步数据和在服务器上保存数据.当前 iCloud 包括文稿与数据.日历.提醒事项. 通讯录.备忘录.Safari书签.阅读列表.iCloud Tabs.iBooks书签 ...
- Java Calendar实现控制台日历
public static void main(String[] args) throws IOException { //初始化日历对象 Calendar calendar = Calendar.g ...
- [转]ODBC编程指南
DM4 ODBC编程指南本章结合DM4数据库的特点,比较全面系统的介绍ODBC的基本概念以及DM4 ODBC DRIVER的使用方法,以便用户更好地使用DM4 ODBC编写应用程序.ODBC提供给你访 ...
- 如何:使用 as 和 is 运算符安全地进行强制转换(C# 编程指南)
如何:使用 as 和 is 运算符安全地进行强制转换(C# 编程指南) 由于对象是多态的,因此基类类型的变量可以保存派生类型.若要访问派生类型的方法,需要将值强制转换回该派生类型.不过,在这些情况下, ...
- OpenGL编程指南(第七版)
OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...
- 编译opengl编程指南第八版示例代码通过
最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...
- 高质量C++/C编程指南(林锐)
推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐 2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐 20 ...
- iOS ---Extension编程指南
当iOS 8.0和OS X v10.10发布后,一个全新的概念出现在我们眼前,那就是应用扩展.顾名思义,应用扩展允许开发者扩展应用的自定义功能和内容,能够让用户在使用其他app时使用该项功能.你可以开 ...
- Lambda 表达式(C# 编程指南) 微软microsoft官方说明
Visual Studio 2013 其他版本 Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地 ...
随机推荐
- 山西汽车销量(hive)
1.创建数据库create database db_cart; 2.使用数据库use db_cart; 3.创建表create table t_cart(province STRING,month I ...
- Python文件读写基本操作
https://www.jianshu.com/p/eab35af27e1c 1.打开文件操作 方法一: f = open('/mypy/test.txt') print f # 输出:<ope ...
- 应用安全 - 安全设备 - WAF原理/检测/绕过
原理 基于Cookie值 Citrix Netscaler(2013年使用广泛) “Citrix Netscaler”会在HTTP返回头部Cookie位置加入“ns_af”的值,可以以此判断为Citr ...
- ToolProvider.getSystemJavaCompiler()方法空指针的排坑
起因: 我在做一个编译Java代码的功能,基本写的差不多了,我就想把它打包部署到我服务器上跑一跑,但是这不做不知道,一做果然就出了问题.我在IDEA上跑一点问题都没有,但是打包成Jar后,后台就显示空 ...
- gitlab上传代码及报错总结
将目录变成git可管理的仓库 git init 将文件添加到暂存区中 git add README.md 将文件提交到仓库 git commit -m "fisrt commit" ...
- mysql-schema-sync同步两个实例
参考:https://github.com/hidu/mysql-schema-sync 需求:测试环境表结构变动同步到开发环境,两个实例各有数百个库,不适合每个库写一个配置文件 环境:操作系统ubu ...
- PHP 中的 $this, static , self ,parent 等等关键字的总结
先说结论: self 和 __CLASS__,都是对当前类的静态引用,取决于定义当前方法所在的类.也就是说,self 写在哪个类里面, 它引用的就是谁.$this 指向的是实际调用时的对象,也就是说, ...
- Flash存储模块调试
Flash存储模块 Flash存储模块之前SPI一直读deviceID有问题原因如下: 用正点原子的例程是可以的,但是转移到自己的工程项目里就不行!!原因是正点原子没有在SPI初始化里 RCC ...
- Bloxorz I (poj3322) (BFS)
[题目描述] It's a game about rolling a box to a specific position on a special plane. Precisely, the pla ...
- SQLServer查看及设置最大连接数
很多时候自己本地开发会遇到 ,打开几个连接正常访问 之后就报错误,这时候需要调整sqlserver 最大连接数. 1. 查询最大连接数 SELECT value_in_useFROM sys.conf ...