关于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 表达式,可以写入可作为参数传递或作为函数调用值返回的本地 ...
随机推荐
- Python uuid库中 几个uuid的区别
在用到uuid库的时候,发现uuid有很多个,比较好奇,就查了一下他们的区别 uuid1()——基于时间戳 uuid2()——基于分布式计算环境DCE(Python中没有这个函数) uuid3()—— ...
- flutter dialog异常Another exception was thrown: No MaterialLocalizations found
flutter dialog异常Another exception was thrown: No MaterialLocalizations found import 'package:flutter ...
- 如何快速查找到多个字典中的公共键(Key)---Python数据结构与算法相关问题与解决技巧
如何快速查找到多个字典中的公共键(Key)-? 实际案例: 西班牙足球甲级联赛,每轮球员进球统计: 第1轮: { '苏亚雷斯':1,'梅西':2,'本泽马':1,...} 第2轮: { '苏亚雷斯 ...
- 练习2:python-把excel表格中某张表的内容导入sqlite
前言:最新需要用到大批量的数据,在excel造好数据之后,存储在数据库库中,方便调用数据,于是就想着用python语言写一下这个过程 python有个openpyxl的模块,可以直接用来对于excel ...
- 使用K近邻算法改进约会网站的配对效果
1 定义数据集导入函数 import numpy as np """ 函数说明:打开并解析文件,对数据进行分类:1 代表不喜欢,2 代表魅力一般,3 代表极具魅力 Par ...
- react 样式的写法之一 ---》styled-components的基本使用
[react]---styled-components的基本使用---[WangQi] 一.官网地址 https://www.styled-components.com/ 二.styled-com ...
- [Python3] 015 冰冻集合的内置方法
目录 0. 前言 英文名 元素要求 使用限制 返回 方法数量 1. 如何查看 frozenset() 的内置方法 2. 少废话,上例子 2.1 copy() 2.2 difference() 2.3 ...
- HDFS数据流——写数据流程
剖析HDFS文件写入 假设文件ss.avi共200m,其写入HDFS指定路径/user/atguigu/ss.avi流程如下: 1)客户端向namenode请求上传文件到指定路径,namenode通过 ...
- ZOJ-1610 线段树+两种查询方法(弥补我线段树区间填充的短板)
ZOJ-1610 线段树+两种查询方法(弥补我线段树区间填充的短板) 题意 题意:给一个n,代表n次操作,接下来每次操作表示把[l,r]区间的线段涂成k的颜色其中,l,r,k的范围都是0到8000 这 ...
- 牛客练习赛51 C 勾股定理https://ac.nowcoder.com/acm/contest/1083/C
题目描述 给出直角三角形其中一条边的长度n,你的任务是构造剩下的两条边,使这三条边能构成一个直角三角形. 输入描述: 一个整数n. 输出描述: 另外两条边b,c.答案不唯一,只要输出任意一组即为合理, ...