19.0. Introduction(Dates, Calendars, and Events)
Event Kit and Event Kit UI frameworks 允许你访问日历数据库,你可以插入、读取、修改events。Event Kit UI framework是你能够呈现内置SDKGUI给用户,让用户修改日历数据库。本章我们先专注于Event Kit framework,并学习Event Kit UI framework。
利用Event Kit framework,程序可以偷偷的修改用户的日历数据库。然而这不是好的做法。事实上,苹果公司禁止这样做,他要求我们对日历数据库的任何修改都要通知用户。苹果官方是这么说的:
“如果你的程序需要修改日历数据库,你必须获得用户的许可。应用不应该未在用户的特许下就修改日历数据库”。
iOS有内置日历应用,可以有不同类型的日历。本章中,我们也需要用到不同的日历。为了确保你可以运行本章的代码,你需要创建个iCloud账户,并在手持设备上登陆。
登陆后,可以在日历应用中看到iCloud部分。
为了运行本章代码,你需要引用Event Kit framework,有时候还需要引用Event Kit UI framework,
代码中
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
iOS模拟器不能模拟日历应用,你需要在真机上测试
本章中得大部分代码专注于读取,处理日历事件。如果你想是使用内置的功能让用户处理日历事件,参看19.10 和19.11
19.1. Requesting Permission to Access Calendars
请求访问许可
调用EKEventStore类的authorizationStatusForEntityType:方法
参数:
EKEntityTypeEvent : 请求访问日历的事件
EKEntityTypeReminder:请求访问日历的提醒
返回值:
EKAuthorizationStatusAuthorized :授权
EKAuthorizationStatusDenied:拒绝
EKAuthorizationStatusNotDetermined :未定
EKAuthorizationStatusRestricted:受限
处于保护用户隐私的需要,在访问事件仓库(event store)时需要获得用户许可也就不奇怪了。实际上,如果你没有先获得用户许可,而去访问日历,iOS将锁定应用的的执行并显示授权提示框。
作为苹果王国上的良好居民,你应该先获得用户的许可再去访问数据,
使用EKEventStore类的requestAccessToEntityType:completion:方法来请求
#pragma mark - Events Kit
-(void)testEKAuthorize
{
EKEventStore *eventStore = [[EKEventStorealloc] init];
switch ([EKEventStoreauthorizationStatusForEntityType:EKEntityTypeEvent]){
caseEKAuthorizationStatusAuthorized:{
[selfextractEventEntityCalendarsOutOfStore:eventStore];
break;
}
caseEKAuthorizationStatusDenied:{
[selfdisplayAccessDenied];
break;
}
caseEKAuthorizationStatusNotDetermined:{
[eventStore requestAccessToEntityType:EKEntityTypeEventcompletion:^(BOOL granted,NSError *error) {
if (granted){
[selfextractEventEntityCalendarsOutOfStore:eventStore];
}else {
[selfdisplayAccessDenied];
}
}];
break;
}
caseEKAuthorizationStatusRestricted:{
[selfdisplayAccessRestricted];
break;
}
}
}
- (void) displayMessage:(NSString *)paramMessage{
UIAlertView *alertView = [[UIAlertViewalloc] initWithTitle:nil
message:paramMessage
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"OK",nil];
[alertViewshow];
}
- (void) displayAccessDenied{
[selfdisplayMessage:@"Access to the event store is denied."];
}
- (void) displayAccessRestricted{
[selfdisplayMessage:@"Access to the event store is restricted."];
}
- (void) extractEventEntityCalendarsOutOfStore:(EKEventStore *)paramStore{
NSArray *calendarTypes = @[
@"Local",
@"CalDAV",
@"Exchange",
@"Subscription",
@"Birthday",
];
NSArray *calendars = [paramStorecalendarsForEntityType:EKEntityTypeEvent];
NSUInteger counter = 1;
for (EKCalendar *calendarin calendars){
/* The title of the calendar */
NSLog(@"Calendar %lu Title = %@",
(unsignedlong)counter, calendar.title);
/* The type of the calendar */
NSLog(@"Calendar %lu Type = %@", (unsignedlong)counter,
calendarTypes[calendar.type]);
/* The color that is associated with the calendar */
NSLog(@"Calendar %lu Color = %@", (unsignedlong)counter,
[UIColorcolorWithCGColor:calendar.CGColor]);
/* And whether the calendar can be modified or not */
if ([calendarallowsContentModifications]){
NSLog(@"Calendar %lu can be modified.", (unsignedlong)counter);
}else {
NSLog(@"Calendar %lu cannot be modified.", (unsignedlong)counter);
}
counter++;
}
}
打印:
2014-07-25 11:12:26.334 cookbook7_19_1[1033:1103] Calendar 1 Title =工作
2014-07-25 11:12:26.338 cookbook7_19_1[1033:1103] Calendar 1 Type = CalDAV
2014-07-25 11:12:26.340 cookbook7_19_1[1033:1103] Calendar 1 Color = UIDeviceRGBColorSpace 0.8 0.45098 0.882353 1
2014-07-25 11:12:26.342 cookbook7_19_1[1033:1103] Calendar 1 can be modified.
2014-07-25 11:12:26.345 cookbook7_19_1[1033:1103] Calendar 2 Title = Birthdays
2014-07-25 11:12:26.348 cookbook7_19_1[1033:1103] Calendar 2 Type = Birthday
2014-07-25 11:12:26.350 cookbook7_19_1[1033:1103] Calendar 2 Color = UIDeviceRGBColorSpace 0.509804 0.584314 0.686275 1
2014-07-25 11:12:26.352 cookbook7_19_1[1033:1103] Calendar 2 cannot be modified.
2014-07-25 11:12:26.353 cookbook7_19_1[1033:1103] Calendar 3 Title =家庭
2014-07-25 11:12:26.355 cookbook7_19_1[1033:1103] Calendar 3 Type = CalDAV
2014-07-25 11:12:26.357 cookbook7_19_1[1033:1103] Calendar 3 Color = UIDeviceRGBColorSpace 0.203922 0.666667 0.862745 1
2014-07-25 11:12:26.359 cookbook7_19_1[1033:1103] Calendar 3 can be modified.
19.2. Retrieving Calendar Groups on an iOS Device
检索日历组
用户有不同的日历账号,比如iCloud账号和其他独立账号
- (void) findIcloudEventSource{
EKSource *icloudEventSource = nil;
EKEventStore *eventStore = [[EKEventStorealloc] init];
for (EKSource *sourcein eventStore.sources){
NSLog(@"source=%@",source);
if (source.sourceType ==EKSourceTypeCalDAV && [source.titlecaseInsensitiveCompare:@"iCloud"]==NSOrderedSame){
icloudEventSource = source;
// break;
}
}
if (icloudEventSource != nil){
NSLog(@"The iCloud event source was found = %@", icloudEventSource);
NSSet *calendars = [icloudEventSource calendarsForEntityType:EKEntityTypeEvent];
for (EKCalendar *calendarin calendars){
NSLog(@"Calendar = %@", calendar);
}
}else {
NSLog(@"Could not find the iCloud event source");
}
}
2014-07-28 17:02:20.630 cookbook7_19_1[2219:907] source=EKSource <0x1c587c90> {UUID = 912FBAEA-98BD-4865-9CB4-7A827FA6C102; type = CalDAV; title = iCloud; externalId = 912FBAEA-98BD-4865-9CB4-7A827FA6C102}
2014-07-28 17:02:20.636 cookbook7_19_1[2219:907] source=EKSource <0x1c587a70> {UUID = C080AFE7-2C99-4975-863A-04152F585707; type = Local; title = Default; externalId = (null)}
2014-07-28 17:02:20.639 cookbook7_19_1[2219:907] source=EKSource <0x1c587be0> {UUID = C6E67576-3F80-4935-8605-A699743C63FA; type = Other; title = Other; externalId = (null)}
2014-07-28 17:02:20.641 cookbook7_19_1[2219:907] The iCloud event source was found = EKSource <0x1c587c90> {UUID = 912FBAEA-98BD-4865-9CB4-7A827FA6C102; type = CalDAV; title = iCloud; externalId = 912FBAEA-98BD-4865-9CB4-7A827FA6C102}
2014-07-28 17:02:20.648 cookbook7_19_1[2219:907] Calendar = EKCalendar <0x1d0a7a70> {title =工作; type = CalDAV; allowsModify = YES; color = #CC73E1FF;}
2014-07-28 17:02:20.650 cookbook7_19_1[2219:907] Calendar = EKCalendar <0x1c5893d0> {title =家庭; type = CalDAV; allowsModify = YES; color = #34AADCFF;}
打开日历软件看下吧
19.3. Adding Events to Calendars
给日历增加事件
从上一节可以看出,日历应用的iCloud中只有工作和家庭两个Calendar,运行本节代码之前再增加一个名字就叫“calendar”
-(void)testInsertEvent
{
EKEventStore * eventStore = [[EKEventStorealloc] init];
[selfinsertEventIntoStore:eventStore];
}
- (void) insertEventIntoStore:(EKEventStore *)paramStore{
EKSource *icloudSource = [self sourceInEventStore:paramStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}else{
NSLog(@"icloudSource=%@",icloudSource);
}
EKCalendar *calendar = [self calendarWithTitle:@"Calendar"
type:EKCalendarTypeCalDAV
inSource:icloudSource
forEventType:EKEntityTypeEvent];
if (calendar == nil){
NSLog(@"Could not find the calendar we were looking for.");
return;
}else{
NSLog(@"calendar=%@",calendar);
}
/* The event starts from today, right now */
NSDate *startDate = [NSDate date];
/* And the event ends this time tomorrow.