How to create and save EKCalendar on ios 6

后端 未结 7 1176
自闭症患者
自闭症患者 2020-12-05 03:42

I\'m having an issue where I create my EKCalendar and everything looks good but then when I go to list my calendars, it doesn\'t show up. I also go to check my calendar list

相关标签:
7条回答
  • 2020-12-05 03:48

    The local store may not support events. This is reproducible if iCloud is enabled.

    This is the most reliable solution I could find, without hard-coding any assumptions:

        let calendar = EKCalendar(forEntityType: .Event, eventStore: eventStore)
    
        if eventStore.sources.count == 0 { // reproducible after Reset Content and Settings
            calendar.source = EKSource()
        }
        else {
            calendar.source = eventStore.defaultCalendarForNewEvents.source
        }
    
        eventStore.saveCalendar(calendar, commit: true)
    
    0 讨论(0)
  • 2020-12-05 03:50

    I would not recommend the top answer, since it relies on checking for "iCloud" as the name, something which can be changed by the user. If you just want to make sure the calendar gets saved and you don't necessarily care what source it gets, you could do this:

    EKCalendar *calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
    calendar.title = @"Calendar name";
    
    NSError *calendarError = nil;
    for (EKSource *source in eventStore.sources) {
        // We know the birthday source is read-only
        if (source.sourceType == EKSourceTypeBirthdays) {
            continue;
        }
    
        calendar.source = source;
        [eventStore saveCalendar:calendar commit:YES error:&calendarError];
    
        // If saving succeeded, we break, otherwise we try a new source
        if (!calendarError) {
            break;
        }
    }
    
    0 讨论(0)
  • 2020-12-05 03:52

    I found a solution. The problem is that when iCloud calendars switched on, it hides the locally created ones from the calendar app. To bypass this problem the solution is to add a new calendar to iCloud source:

        for (EKSource *source in self.eventStore.sources)
        {
            if (source.sourceType == EKSourceTypeCalDAV && 
               [source.title isEqualToString:@"iCloud"]) //Couldn't find better way, if there is, then tell me too. :)
            {
                localSource = source;
                break;
            }
        }
    
        if (localSource == nil)
        {
            for (EKSource *source in self.eventStore.sources)
            {
                if (source.sourceType == EKSourceTypeLocal)
                {
                    localSource = source;
                    break;
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-05 03:55

    Have you tried checking authorization setting first to make sure the user has given permission to access the store?

    For EKEventStore documentation:

    + (EKAuthorizationStatus)authorizationStatusForEntityType:(EKEntityType)entityType
    
    - (void)requestAccessToEntityType:(EKEntityType)entityType completion:(EKEventStoreRequestAccessCompletionHandler)completion
    

    Important: If your app has never requested access before, you must request access to events or reminders before attempting to fetch or create them. If you request data before prompting the user for access with this method, you'll need to reset the event store with the reset method in order to start receiving data once the user grants access.

    0 讨论(0)
  • 2020-12-05 03:56

    The solution Massimo Oliviero did not work for me. I had the same issue. I was creating Calendar after calling requestAccessToEntityType.
    What worked for me is after getting the permission I reinitialised the EventStore object. It was like the permissions were never upadted.

    [[CalendarManager sharedManager].eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
        if (granted && error == nil) {
            // Store the returned granted value.
            [CalendarManager sharedManager].eventsAccessGranted = granted;
            if (![CalendarManager sharedManager].calendarCreated) {
                [[CalendarManager sharedManager] createCalendar];
            }
        }
        else{
            // In case of error, just log its description to the debugger.
            DebugLog(@"%@", [error localizedDescription]);
        }
    }];
    

    In CalendarManager

    - (void)createCalendar {
    
    _eventStore = nil;
    _eventStore = [EKEventStore new];
    
    // Create a new calendar.
    EKCalendar *calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent
                                                  eventStore:self.eventStore];
    
    // Set the calendar title.
    calendar.title = CALENDAR_NAME;
    
    EKSource *theSource;
    
    // First: Check if the user has an iCloud source set-up.
    for (EKSource *source in self.eventStore.sources) {
        if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"]) {
            theSource = source;
            break;
        }
    }
    
    // Second: If no iCloud source is set-up / utilised, then fall back and use the local source.
    if (theSource == nil) {
        for (EKSource *source in self.eventStore.sources) {
            if (source.sourceType == EKSourceTypeLocal)  {
                theSource = source;
                break;
            }
        }
    }
    
    calendar.source = theSource;
    
    // Save and commit the calendar.
    NSError *error;
    [_eventStore saveCalendar:calendar commit:YES error:&error];
    
    // If no error occurs then turn the editing mode off, store the new calendar identifier and reload the calendars.
    if (error == nil) {
        self.calendarCreated = YES;
    }
    else {
        self.calendarCreated = NO;
        // Display the error description to the debugger.
        DebugLog(@"%@", [error localizedDescription]);
    }}
    
    0 讨论(0)
  • 2020-12-05 03:58

    I had this problem too. My solution is nearly like other answers, but I use another way to get the instance of EKSource.

    As written in documentation:

    /* 
     * Returns the calendar that events should be added to by default, 
     * as set in the Settings application.
     */
    @property EKCalendar *defaultCalendarForNewEvents; 
    

    So, I use this code to get the proper EKSource:

    EKSource *theSource = [self.eventStore defaultCalendarForNewEvents].source;
    

    BUT if you use another calendar like Gmail (or Yahoo etc.), you can't add your calendar to its source.

    In this rare case I use a full search:

    EKSource *theSource;
    for (EKSource *source in eventStore.sources) {
        if (source.sourceType == EKSourceTypeSubscribed) {
            theSource = source;
            break; // stop when source is found
        }
    }
    
    0 讨论(0)
提交回复
热议问题