19.0~19.11 Dates, Calendars, and Events 日历事件的处理

来源:互联网 发布:瓜瓜播放器mac版 编辑:程序博客网 时间:2024/06/16 12:31

测试代码

19.0. IntroductionDates, 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



修改不了,是不是没权限呢,嗨。。。





















  












0 0
原创粉丝点击