关于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 表达式,可以写入可作为参数传递或作为函数调用值返回的本地 ...
随机推荐
- 券商VIP交易通道
打新不成就炒新.随着新股发行上市的再次重启,巨大的获利机会引来投资者的争相竞逐,可并非所有投资者都能抢到新股筹码.“每天都在涨停板追这些新股,但从来没有买到过.”证券时报记者在采访中听到不少中小散户如 ...
- python实现建立soap通信(调用及测试webservice接口)
实现代码如下: #调用及测试webservice接口 import requests class SoapConnect: def get_soap(self,url,data): r = reque ...
- 002/区块链核心概念与原理详解(Mooc)
1.课程介绍 (一).区块链前世今生 密码朋克--神秘组织(邮件组) 2.区块链核心概念与原理 (一)比特币是数字货币 为什么叫区块链? 因为比特币系统里面的数据是一个个的区块来存储,并且通过hash ...
- RocketMQ安装部署及整合Springboot
消息中间件的功能: 通过学习ActiveMq,kafka,rabbitMq这些消息中间件,我们大致能为消息中间件的功能做一下以下定义:可以先从基本的需求开始思考 最基本的是要能支持消息的发送和接收,需 ...
- new String创建了几个对象
String str = new String(“abc”) 到底创建了几个对象? 首先String str是定义了一个字符串变量,并未产生对象,=不产生对象,那么只有后面的new String(& ...
- MySQL-第十二篇管理结果集
1.ResultSet 2.可更新的结果集,使用ResultSet的updateRow()方法.
- FZUOJ-2273 Triangles
Problem 2273 Triangles Accept: 109 Submit: 360 Time Limit: 1000 mSec Memory Limit : 262144 KB ...
- 利用vsftpd在Linux构建安全的FTP服务
最近在机房搭建Linux环境,需要用到了FTP服务,查看了许多的资料,在这里做一下笔记 一.安装 方法一,使用yum命令安装,需要能够连接外网 # yum install vsftpd 方法二,使用安 ...
- [书接上一回]在Oracle Enterprise Linux (v5.7) 中安装DB - (3/4)
安装p10404530_112030_Linux-x86-64_6of7.zip解压下的example. 修改软件路径,为dbhome_1. 安装好数据,则可以进行快照操作! 删除安装文件. 输入db ...
- Eclipse创建maven的war工程没有web.xml解决方式
当我们使用Eclipse创建maven的web项目时,会缺少xml文件,在这里我提供两种自动创建xml的方法: 1.方法一 右键项目→Java EE Tools→Generate Deployment ...