19.0~19.11 Dates, Calendars, and Events 日历事件的处理
来源:互联网 发布:瓜瓜播放器mac版 编辑:程序博客网 时间:2024/06/16 12:31
测试代码
19.0. Introduction(Dates, Calendars, and Events)
Event Kit and Event Kit UI frameworks 允许你访问日历数据库,你可以插入、读取、修改events。Event Kit UI framework是你能够呈现内置SDKGUI给用户,让用户修改日历数据库。本章我们先专注于EventKit 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 = [icloudEventSourcecalendarsForEntityType: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.
24 hours, 60 minutes per hour and 60 seconds per minute
hence 24 * 60 * 60 */
NSDate *endDate = [startDate dateByAddingTimeInterval:24 *60 *60];
/* Create the new event */
BOOL createdSuccessfully = [self createEventWithTitle:@"My Concert"
startDate:startDate
endDate:endDate
inCalendar:calendar
inEventStore:paramStore
notes:nil];
if (createdSuccessfully){
NSLog(@"Successfully created the event.");
}else {
NSLog(@"Failed to create the event.");
}
}
- (BOOL)createEventWithTitle:(NSString *)paramTitle
startDate:(NSDate *)paramStartDate
endDate:(NSDate *)paramEndDate
inCalendar:(EKCalendar *)paramCalendar
inEventStore:(EKEventStore *)paramStore
notes:(NSString *)paramNotes{
BOOL result = NO;
/* If a calendar does not allow modification of its contents
then we cannot insert an event into it */
if (paramCalendar.allowsContentModifications ==NO){
NSLog(@"The selected calendar does not allow modifications.");
return NO;
}
/* Create an event */
EKEvent *event = [EKEvent eventWithEventStore:paramStore];
event.calendar = paramCalendar;
/* Set the properties of the event such as its title,
start date/time, end date/time, etc. */
event.title = paramTitle;
event.notes = paramNotes;
event.startDate = paramStartDate;
event.endDate = paramEndDate;
/* Finally, save the event into the calendar */
NSError *saveError = nil;
result = [paramStoresaveEvent:event
span:EKSpanThisEvent
error:&saveError];
if (result == NO){
NSLog(@"An error occurred = %@", saveError);
}
return result;
}
- (EKSource *) sourceInEventStore:(EKEventStore *)paramEventStore
sourceType:(EKSourceType)paramType
sourceTitle:(NSString *)paramSourceTitle{
for (EKSource *source in paramEventStore.sources){
if (source.sourceType == paramType && [source.titlecaseInsensitiveCompare:paramSourceTitle] ==NSOrderedSame){
return source;
}
}
return nil;
}
- (EKCalendar *) calendarWithTitle:(NSString *)paramTitle
type:(EKCalendarType)paramType
inSource:(EKSource *)paramSource
forEventType:(EKEntityType)paramEventType{
for (EKCalendar *calendar in [paramSource calendarsForEntityType:paramEventType]){
if ([calendar.title caseInsensitiveCompare:paramTitle] == NSOrderedSame && calendar.type == paramType){
return calendar;
}
}
return nil;
}
打印:
2014-07-28 17:38:09.590 cookbook7_19_1[2274:907] icloudSource=EKSource <0x208bc910> {UUID = 912FBAEA-98BD-4865-9CB4-7A827FA6C102; type = CalDAV; title = iCloud; externalId = 912FBAEA-98BD-4865-9CB4-7A827FA6C102}
2014-07-28 17:38:09.603 cookbook7_19_1[2274:907] calendar=EKCalendar <0x208beef0> {title = calendar; type = CalDAV; allowsModify = YES; color = #f64f00;}
2014-07-28 17:38:09.665 cookbook7_19_1[2274:907] Successfully created the event.
运行结果表明,calendar的标题不区分大小写。
再到日历应用中看下
19.4. Accessing the Contents of Calendars
检索事件
- (void) readEvents{
/* Instantiate the event store */
EKEventStore *eventStore = [[EKEventStorealloc]init];
EKSource *icloudSource = [self sourceInEventStore:eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
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;
}
/* The start date will be today */
NSDate *startDate = [NSDate date];
/* The end date will be 1 day from today */
NSDate *endDate = [startDate dateByAddingTimeInterval:24 *60 *60];
/* Create the predicate that we can later pass to the
event store in order to fetch the events */
NSPredicate *searchPredicate =
[eventStore predicateForEventsWithStartDate:startDate
endDate:endDate
calendars:@[calendar]];
/* Make sure we succeeded in creating the predicate */
if (searchPredicate == nil){
NSLog(@"Could not create the search predicate.");
return;
}
/* Fetch all the events that fall between
the starting and the ending dates */
NSArray *events = [eventStore eventsMatchingPredicate:searchPredicate];
/* Go through all the events and print their information
out to the console */
if (events != nil){
NSUInteger counter = 1;
for (EKEvent *event in events){
NSLog(@"Event %lu Start Date = %@", (unsignedlong)counter,
event.startDate);
NSLog(@"Event %lu End Date = %@", (unsignedlong)counter,
event.endDate);
NSLog(@"Event %lu Title = %@", (unsignedlong)counter,
event.title);
counter++;
}
} else {
NSLog(@"The array of events for this start/end time is nil.");
}
}
打印:
2014-07-28 18:01:30.908 cookbook7_19_1[2296:907] Event 1 Start Date = 2014-07-28 09:38:09 +0000
2014-07-28 18:01:30.910 cookbook7_19_1[2296:907] Event 1 End Date = 2014-07-29 09:38:09 +0000
2014-07-28 18:01:30.912 cookbook7_19_1[2296:907] Event 1 Title = My Concert
19.5. Removing Events from Calendars
删除事件
-(void)testDeleteEvent
{
EKEventStore * eventStore = [[EKEventStorealloc]init];
[selfdeleteEventInStore:eventStore];
}
- (void) deleteEventInStore:(EKEventStore *)paramEventStore{
EKSource *icloudSource = [self sourceInEventStore:paramEventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
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;
}
/* Create the event first */
/* The event starts from today, right now */
NSDate *startDate = [NSDate date];
/* And the event ends this time tomorrow.
24 hours, 60 minutes per hour and 60 seconds per minute
hence 24 * 60 * 60 */
NSDate *endDate = [startDate dateByAddingTimeInterval:24 *60 *60];
NSString *eventTitle = @"My Event";
BOOL createdSuccessfully = [self createEventWithTitle:eventTitle
startDate:startDate
endDate:endDate
inCalendar:calendar
inEventStore:paramEventStore
notes:nil];
if (createdSuccessfully == NO){
NSLog(@"Could not create the event.");
}
[selfreadEvents];
BOOL removedSuccessfully = [self removeEventWithTitle:eventTitle
startDate:startDate
endDate:endDate
inEventStore:paramEventStore
inCalendar:calendar
notes:nil];
if (removedSuccessfully){
NSLog(@"Successfully created and deleted the event");
} else {
NSLog(@"Failed to delete the event.");
}
}
- (BOOL)removeEventWithTitle:(NSString *)paramTitle
startDate:(NSDate *)paramStartDate
endDate:(NSDate *)paramEndDate
inEventStore:(EKEventStore *)paramEventStore
inCalendar:(EKCalendar *)paramCalendar
notes:(NSString *)paramNotes{
BOOL result = NO;
/* If a calendar does not allow modification of its contents
then we cannot insert an event into it */
if (paramCalendar.allowsContentModifications ==NO){
NSLog(@"The selected calendar does not allow modifications.");
return NO; }
NSPredicate *predicate = [paramEventStore predicateForEventsWithStartDate:paramStartDate
endDate:paramEndDate
calendars:@[paramCalendar]];
/* Get all the events that match the parameters */
NSArray *events = [paramEventStore eventsMatchingPredicate:predicate];
if ([events count] > 0){
/* Delete them all */
for (EKEvent *event in events){
NSError *removeError = nil;
/* Do not commit here, we will commit in batch after we have
removed all the events that matched our criteria */
if ([paramEventStore removeEvent:event
span:EKSpanThisEvent
commit:NO
error:&removeError] ==NO){
NSLog(@"Failed to remove event %@ with error = %@",event, removeError);
}
}
NSError *commitError = nil;
if ([paramEventStore commit:&commitError]){
result =YES;
} else {
NSLog(@"Failed to commit the event store.");
}
} else {
NSLog(@"No events matched your input.");
}
return result;
}
打印:
2014-07-29 10:56:31.337 cookbook7_19_1[2764:907] Event 1 Start Date = 2014-07-29 02:56:31 +0000
2014-07-29 10:56:31.341 cookbook7_19_1[2764:907] Event 1 End Date = 2014-07-30 02:56:31 +0000
2014-07-29 10:56:31.345 cookbook7_19_1[2764:907] Event 1 Title = My Event
2014-07-29 10:56:31.377 cookbook7_19_1[2764:907] Successfully created and deleted the event
19.6. Adding Recurring Events to Calendars
增加循环事件
本例创建一个每月同一天触发的事件
-(void)testCreateRecurringEvent
{
EKEventStore * eventStore = [[EKEventStorealloc]init];
EKSource *icloudSource = [self sourceInEventStore:eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
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;
}
[selfcreateRecurringEventInStore:eventStoreinCalendar:calendar];
}
- (BOOL) createRecurringEventInStore:(EKEventStore *)paramStore inCalendar:(EKCalendar *)paramCalendar{
/* Create an event */
EKEvent *event = [EKEvent eventWithEventStore:paramStore];
/* Create an event that happens today and happens every month for a year from now */
NSDate *eventStartDate = [NSDate date];
/* The event's end date is one hour from the moment it is created */
NSTimeInterval NSOneHour = 1 * 60 * 60;
NSDate *eventEndDate = [eventStartDate dateByAddingTimeInterval:NSOneHour];
/* Assign the required properties, especially
the target calendar */
event.calendar = paramCalendar;
event.title =@"My Event";
event.startDate = eventStartDate;
event.endDate = eventEndDate;
/* The end date of the recurring rule
is one year from now */
NSTimeInterval NSOneYear = 365 * 24 * 60 * 60;
NSDate *oneYearFromNow = [eventStartDate dateByAddingTimeInterval:NSOneYear];
/* Create an Event Kit date from this date */
EKRecurrenceEnd *recurringEnd =[EKRecurrenceEndrecurrenceEndWithEndDate:oneYearFromNow];
/* And the recurring rule. This event happens every
month (EKRecurrenceFrequencyMonthly), once a month (interval:1)
and the recurring rule ends a year from now (end:RecurringEnd) */
EKRecurrenceRule *recurringRule = [[EKRecurrenceRulealloc]
initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly
interval:1
end:recurringEnd];
/* Set the recurring rule for the event */
event.recurrenceRules =@[recurringRule];
NSError *saveError = nil;
/* Save the event */
if ([paramStoresaveEvent:eventspan:EKSpanFutureEvents
error:&saveError]){
NSLog(@"Successfully created the recurring event.");
return YES;
} else {
NSLog(@"Failed to create the recurring event %@", saveError);
}
return NO;
}
打印:
2014-07-29 11:28:01.269 cookbook7_19_1[2791:907] Successfully created the recurring event.
19.7. Retrieving the Attendees of an Event
检索时间参与人
-(void)testEnumerateTodayEventsInStore
{
EKEventStore * eventStore = [[EKEventStorealloc]init];
EKSource *icloudSource = [self sourceInEventStore:eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
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;
}
[selfenumerateTodayEventsInStore:eventStorecalendar:calendar];
}
- (void) enumerateTodayEventsInStore:(EKEventStore *)paramStore calendar:(EKCalendar *)paramCalendar{
/* Construct the starting date for today */
NSDate *startDate = [NSDate date];
/* The end date will be 1 day from now */
NSTimeInterval NSOneDay = 1 * 24 * 60 * 60;
NSDate *endDate = [startDate dateByAddingTimeInterval:NSOneDay];
/* Create the predicate that we can later pass to
the event store in order to fetch the events */
NSPredicate *searchPredicate =
[paramStore predicateForEventsWithStartDate:startDate
endDate:endDate
calendars:@[paramCalendar]];
/* Make sure we succeeded in creating the predicate */
if (searchPredicate == nil){
NSLog(@"Could not create the search predicate.");
return;
}
/* Fetch all the events that fall between the
starting and the ending dates */
NSArray *events = [paramStore eventsMatchingPredicate:searchPredicate];
/* Array of NSString equivalents of the values
in the EKParticipantRole enumeration */
NSArray *attendeeRole = @[
@"Unknown",
@"Required",
@"Optional",
@"Chair",
@"Non Participant",
];
/* Array of NSString equivalents of the values
in the EKParticipantStatus enumeration */
NSArray *attendeeStatus = @[
@"Unknown",
@"Pending",
@"Accepted",
@"Declined",
@"Tentative",
@"Delegated",
@"Completed",
@"In Process",
];
/* Array of NSString equivalents of the values
in the EKParticipantType enumeration */
NSArray *attendeeType = @[
@"Unknown",
@"Person",
@"Room",
@"Resource",
@"Group"
];
/* Go through all the events and print their information
out to the console */
if (events != nil){
NSUInteger eventCounter = 0;
for (EKEvent *thisEvent in events){
eventCounter++;
NSLog(@"Event %lu Start Date = %@", (unsignedlong)eventCounter, thisEvent.startDate);
NSLog(@"Event %lu End Date = %@", (unsignedlong)eventCounter, thisEvent.endDate);
NSLog(@"Event %lu Title = %@", (unsignedlong)eventCounter, thisEvent.title);
if (thisEvent.attendees == nil || [thisEvent.attendees count] == 0){
NSLog(@"Event %lu has no attendees", (unsignedlong)eventCounter);
continue;
}
NSUInteger attendeeCounter = 1;
for (EKParticipant *participant in thisEvent.attendees){
NSLog(@"Event %lu Attendee %lu Name = %@", (unsignedlong)eventCounter, (unsignedlong)attendeeCounter, participant.name);
NSLog(@"Event %lu Attendee %lu Role = %@", (unsignedlong)eventCounter,
(unsignedlong)attendeeCounter, attendeeRole[participant.participantRole]);
NSLog(@"Event %lu Attendee %lu Status = %@", (unsignedlong)eventCounter,
(unsignedlong)attendeeCounter, attendeeStatus[participant.participantStatus]);
NSLog(@"Event %lu Attendee %lu Type = %@", (unsignedlong)eventCounter,
(unsignedlong)attendeeCounter, attendeeType[participant.participantType]);
NSLog(@"Event %lu Attendee %lu URL = %@", (unsignedlong)eventCounter, (unsignedlong)attendeeCounter, participant.URL);
attendeeCounter++;
}
}
} else {
NSLog(@"The array of events is nil.");
}
}
打印:
2014-07-29 15:12:54.432 cookbook7_19_1[2899:907] Event 1 Start Date = 2014-07-29 07:12:25 +0000
2014-07-29 15:12:54.435 cookbook7_19_1[2899:907] Event 1 End Date = 2014-07-30 07:12:25 +0000
2014-07-29 15:12:54.437 cookbook7_19_1[2899:907] Event 1 Title = My Concert
2014-07-29 15:12:54.440 cookbook7_19_1[2899:907] Event 1 has no attendees
测试手机,没有联系人的,参与者就不加了
19.8. Adding Alarms to Calendars
增加闹钟
-(void)testAddAlarm
{
EKEventStore * eventStore = [[EKEventStorealloc]init];
EKSource *icloudSource = [self sourceInEventStore:eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
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;
}
[selfaddAlarmToCalendar:calendarinStore:eventStore];
}
- (void) addAlarmToCalendar:(EKCalendar *)paramCalendar inStore:(EKEventStore *)paramStore{
/* The event starts 60 seconds from now */
NSDate *startDate = [NSDatedateWithTimeIntervalSinceNow:60.0];/* And end the event 20 seconds after its start date */
NSDate *endDate = [startDate dateByAddingTimeInterval:20.0];
EKEvent *eventWithAlarm = [EKEvent eventWithEventStore:paramStore];
eventWithAlarm.calendar = paramCalendar;
eventWithAlarm.startDate = startDate;
eventWithAlarm.endDate = endDate;
/* The alarm goes off 2 seconds before the event happens */
EKAlarm *alarm = [EKAlarmalarmWithRelativeOffset:-2.0];
eventWithAlarm.title =@"Event with Alarm";
[eventWithAlarmaddAlarm:alarm];
NSError *saveError = nil;
if ([paramStore saveEvent:eventWithAlarm
span:EKSpanThisEvent
error:&saveError]){
NSLog(@"Saved an event that fires 60 seconds from now.");
} else {
NSLog(@"Failed to save the event. Error = %@", saveError);
}
}
打印:
2014-07-29 15:27:55.820 cookbook7_19_1[2924:907] Saved an event that fires 60 seconds from now.
19.9. Handling Event Changed Notifications
处理事件改变通知
当用户修改日历数据库内容时,应用得到通知
-(void)testHandleNotificationsInStore
{
EKEventStore * eventStore = [[EKEventStorealloc]init];
EKSource *icloudSource = [self sourceInEventStore:eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
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;
}
[selfaddAlarmToCalendar:calendarinStore:eventStore];
[selfhandleNotificationsInStore:eventStore];
}
- (void) eventsChanged:(NSNotification *)paramNotification{
NSMutableArray *invalidatedEvents = [[NSMutableArrayalloc]init];
NSLog(@"Refreshing array of events...");
for (EKEvent *event in self.eventsForOneYear){
if ([event refresh] == NO){
[invalidatedEventsaddObject:event];
}
}
if ([invalidatedEvents count] > 0){
[self.eventsForOneYearremoveObjectsInArray:invalidatedEvents];
}
NSLog(@"self.eventsForOneYear=%@",self.eventsForOneYear);
}
- (void) handleNotificationsInStore:(EKEventStore *)paramStore{
EKSource *icloudSource = [selfsourceInEventStore:paramStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
EKCalendar *calendar = [selfcalendarWithTitle:@"Calendar"
type:EKCalendarTypeCalDAV
inSource:icloudSource
forEventType:EKEntityTypeEvent];
if (calendar == nil){
NSLog(@"Could not find the calendar we were looking for.");
return;
}
NSTimeInterval NSOneYear =1 *365 * 24 * 60 * 60;
NSDate *startDate = [NSDatedate];
NSDate *endDate = [startDate dateByAddingTimeInterval:NSOneYear];
NSPredicate *predicate =
[paramStore predicateForEventsWithStartDate:startDate
endDate:endDate
calendars:@[calendar]];
NSArray *events = [paramStore eventsMatchingPredicate:predicate];
self.eventsForOneYear = [[NSMutableArray alloc] initWithArray:events];
NSLog(@"self.eventsForOneYear=%@",self.eventsForOneYear);
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(eventsChanged:)
name:EKEventStoreChangedNotification
object:nil];
}
打印:
2014-07-29 15:53:20.519 cookbook7_19_1[3011:907] Saved an event that fires 60 seconds from now.
2014-07-29 15:53:20.540 cookbook7_19_1[3011:907] self.eventsForOneYear=(
"EKEvent <0x1cd6dba0> {EKEvent <0x1cd6dba0> {title = Event with Alarm; location = (null); calendar = EKCalendar <0x1cd6bed0> {title = calendar; type = CalDAV; allowsModify = YES; color = #f64f00;}; alarms = (\n \"EKAlarm <0x1cd6ebf0> {triggerInterval = -2.000000}\"\n); URL = (null); lastModified = 2014-07-29 07:53:20 +0000; timeZone = Asia/Shanghai (GMT+0800) offset 28800}; location = (null); startDate = 2014-07-29 07:54:20 +0000; endDate = 2014-07-29 07:54:40 +0000; allDay = 0; floating = 0; recurrence = (null); attendees = (null)}"
)
没有触发eventsChanged: 这是怎么回事呢?
在应用中获取所有的事件后,切换到日历应用,删除事件,iOS这将广播EKEventStoreChangedNotification消息,你的应用收到消息,可我的例子怎么没触发消息通知呢。关于应用状态以及如何处理消息,请参见相关章节。
19.10. Presenting Event View Controllers
使用内置的视图控制器显示日历事件
#import "ViewController.h"
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
@interface ViewController () <EKEventViewDelegate>
@property (nonatomic,strong)EKEventStore *eventStore;
@end
@implementation ViewController
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) viewDidAppear:(BOOL)animated{
[superviewDidAppear:animated];
static BOOL beenHereBefore = NO;
if (beenHereBefore){
return;
} else {
beenHereBefore =YES;
}
self.eventStore = [[EKEventStorealloc]init];
switch ([EKEventStoreauthorizationStatusForEntityType:EKEntityTypeEvent]){
caseEKAuthorizationStatusAuthorized:{
[selfdisplayEventViewController];
break;
}
caseEKAuthorizationStatusDenied:{
// [self displayAccessDenied];
NSLog(@"EKAuthorizationStatusDenied");
break;
}
caseEKAuthorizationStatusNotDetermined:{
[self.eventStorerequestAccessToEntityType:EKEntityTypeEventcompletion:^(BOOL granted,NSError *error) {
if (granted){
[selfdisplayEventViewController];
}else {
// [self displayAccessDenied];
NSLog(@"EKAuthorizationStatusDenied");
}
}];
break;
}
caseEKAuthorizationStatusRestricted:{
// [self displayAccessRestricted];
NSLog(@"EKAuthorizationStatusRestricted");
break;
}
}
}
- (void) displayEventViewController{
EKSource *icloudSource = [self sourceInEventStore:self.eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
NSSet *calendars = [icloudSourcecalendarsForEntityType:EKEntityTypeEvent];
NSTimeInterval NSOneYear = 1 * 365 * 24.0f * 60.0f * 60.0f;
NSDate *startDate = [[NSDate date] dateByAddingTimeInterval:-NSOneYear];
NSDate *endDate = [NSDate date];
NSPredicate *predicate =
[self.eventStorepredicateForEventsWithStartDate:startDate
endDate:endDate
calendars:calendars.allObjects];
NSArray *events = [self.eventStoreeventsMatchingPredicate:predicate];
if ([events count] > 0){
EKEvent *event = events[0];
EKEventViewController *controller = [[EKEventViewControlleralloc]init];
controller.event = event;
controller.allowsEditing =YES;
controller.allowsCalendarPreview =YES;
controller.delegate =self;
self.navigationItem.backBarButtonItem =
[[UIBarButtonItemalloc]initWithTitle:@"Go Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
// [self.navigationController pushViewController:controller
// animated:YES];
[selfpresentViewController:controlleranimated:YEScompletion:nil];
}
}
- (void)eventViewController:(EKEventViewController *)controller didCompleteWithAction:(EKEventViewAction)action{
switch (action){
caseEKEventViewActionDeleted:{
NSLog(@"User deleted the event.");
break;
}
caseEKEventViewActionDone:{
NSLog(@"User finished viewing the event.");
break;
}
caseEKEventViewActionResponded:{
NSLog(@"User responsed to the invitation in the event.");
break;
}
}
}
- (EKSource *) sourceInEventStore:(EKEventStore *)paramEventStore
sourceType:(EKSourceType)paramType
sourceTitle:(NSString *)paramSourceTitle{
for (EKSource *source in paramEventStore.sources){
if (source.sourceType == paramType && [source.titlecaseInsensitiveCompare:paramSourceTitle] ==NSOrderedSame){
return source;
}
}
return nil;
}
@end
19.11. Presenting Event Edit View Controllers
使用内置事件编辑器让用户在你的程序里编辑事件
#import "ViewController0.h"
#import <EventKitUI/EventKitUI.h>
#import <EventKit/EventKit.h>
@interface ViewController0 ()<EKEventEditViewDelegate>
@property (nonatomic,strong)EKEventStore *eventStore;
- (IBAction)buttonAction:(id)sender;
@end
@implementation ViewController0
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view.
self.eventStore = [[EKEventStorealloc]init];
}
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action{
switch (action){
caseEKEventEditViewActionCanceled:{
NSLog(@"Cancelled");
break;
}
caseEKEventEditViewActionSaved:{
NSLog(@"Saved");
break; }
caseEKEventEditViewActionDeleted:{
NSLog(@"Deleted");
break;
}
}
// [self.navigationController dismissViewControllerAnimated:YES
// completion:nil];
[selfdismissViewControllerAnimated:YEScompletion:nil];
}
- (void) displayEventEditController{
EKSource *icloudSource = [self sourceInEventStore:self.eventStore
sourceType:EKSourceTypeCalDAV
sourceTitle:@"iCloud"];
if (icloudSource == nil){
NSLog(@"You have not configured iCloud for your device.");
return;
}
NSSet *calendars = [icloudSourcecalendarsForEntityType:EKEntityTypeEvent];
NSTimeInterval NSOneYear = 1 * 365 * 24.0f * 60.0f * 60.0f;
NSDate *startDate = [[NSDate date] dateByAddingTimeInterval:-NSOneYear];
NSDate *endDate = [NSDate date];
NSPredicate *predicate =
[self.eventStorepredicateForEventsWithStartDate:startDate
endDate:endDate
calendars:calendars.allObjects];
NSArray *events = [self.eventStoreeventsMatchingPredicate:predicate];
if ([events count] > 0){
EKEvent *event = events[0];
EKEventEditViewController *controller = [[EKEventEditViewControlleralloc]init];
controller.event = event;
controller.editViewDelegate =self;
// [self.navigationController presentViewController:controller
// animated:YES
// completion:nil];
[selfpresentViewController:controller
animated:YES
completion:nil];
}
}
- (EKSource *) sourceInEventStore:(EKEventStore *)paramEventStore
sourceType:(EKSourceType)paramType
sourceTitle:(NSString *)paramSourceTitle{
for (EKSource *source in paramEventStore.sources){
if (source.sourceType == paramType && [source.titlecaseInsensitiveCompare:paramSourceTitle] ==NSOrderedSame){
return source;
}
}
return nil;
}
- (IBAction)buttonAction:(id)sender {
[selfdisplayEventEditController];
}
@end
打印:
2014-07-29 17:13:57.789 cookbook7_19_1[3226:907] Cancelled
2014-07-29 17:14:01.988 cookbook7_19_1[3226:907] Cancelled
2014-07-29 17:14:16.393 cookbook7_19_1[3226:907] Calendar: unable to save: (null)
2014-07-29 17:14:22.549 cookbook7_19_1[3226:907] Remove failed: (null)
2014-07-29 17:14:22.551 cookbook7_19_1[3226:907] Deleted
修改不了,是不是没权限呢,嗨。。。
- 19.0~19.11 Dates, Calendars, and Events 日历事件的处理
- 精彩控件源码(2)-Farsi Library - Working with Dates, Calendars, and DatePickers
- Calendars - 日历插件
- 简单化的事件与委托 Events and Delegates simplified
- 23.5 Application events and listeners Application 的事件监听器
- Android 日历管理 Calendars的(日程、提醒)增删改查
- 复杂事件处理(Complex Events Processing) --2. 复杂事件处理的功能和应用场景
- 拦截器与事件(Interceptors and events)
- Events and Delegates(事件和委托)
- tkinter: 事件 & 绑定 (Events and Bindings)
- Oracle Dates and Times
- Oracle Dates and Timestamps
- Dates and Timestamps
- Dates and Times
- 如何在DataTemplate中处理事件Events
- Nodejs学习 2 -- events事件处理EventEmitter
- AMI的Events 事件分析
- (4)事件处理——(12)事件的缩写(Shorthand events)
- hdoj.2021 发工资咯:) 20140726
- Maven:Non-resolvable parent POM: Failure to find错误
- 网络存储ISCSI配置
- The Triangle (poj 1163)
- 【C++基础 05】友元函数和友元类
- 19.0~19.11 Dates, Calendars, and Events 日历事件的处理
- ASIHttpRequest详解
- ArrayList删除集合中某一属性相同的元素
- Amazon DynamoDB, 面向互联网应用的高性能、可扩展的NoSQL数据库
- [Unity-2] Unity播放音乐
- SOAP Webservice和RESTful Webservice(转载)
- SQL Server Profiler使用方法
- samba服务器的配置 Window --- Linux文件共享 (国嵌笔记)
- MySQL server version for the right syntax to use near 'OPTION SQL_SELECT_LIMIT=DEFAULT' at line 1