Unable to add event in calendar

2019-06-24 00:08发布

问题:

I want to add events in "someName" calendar. In case, a calendar with the given name doesn't exist then I will create one programatically. My problem is that the event does not get added when localSource (of type EKSource) turns out to be null. I added 3 checks to make sure that I get a value of localSource but even then in some cases localSource is nil. So on my phone events get added but on my friend's phone they don't.

I followed various posts and I understood that EKSource can be of 6 types: https://developer.apple.com/reference/eventkit/eksourcetype

What I fail to understand is in what cases localSource would be nil? What does this mean in normal language? Can I do something from the code to make it non-nil or something has to be done by the user on device?

- (void)setCalendar {
    NSArray *calendars = [self.eventStore calendarsForEntityType:nil];
    NSString *calendarTitle = someName;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title matches %@", calendarTitle];
    NSArray *filtered = [calendars filteredArrayUsingPredicate:predicate];
    if ([filtered count]) {
        self.calendar = [filtered firstObject];
    }
    else {
        self.calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:self.eventStore];
        self.calendar.title = calendarTitle;
        EKSource *localSource;
        for (EKSource *source in self.eventStore.sources)
        {

            //if iCloud account is setup then add the event in that calendar
            if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"])
            {
                localSource = source;
                break;
            }
        }
        if (localSource == nil)
        {
            for (EKSource *source in self.eventStore.sources)
            {
                //if iCloud is not setup then look for local source
                if (source.sourceType == EKSourceTypeLocal)
                {
                    localSource = source;
                    break;
                }
            }

        }
        if (!localSource) {
            localSource = [self.eventStore defaultCalendarForNewEvents].source;
        }
        self.calendar.source = localSource;
        NSError *calendarErr = nil;
        BOOL calendarSuccess = [self.eventStore saveCalendar:self.calendar commit:YES error:&calendarErr];
        if (!calendarSuccess) {
            NSLog(@"Error while updating calendar %@", calendarErr);
        }
    }

}

PS: I have permission to add calendar events.

回答1:

local source depicts the fields like 'on my iphone', 'icloud', 'gmail' in user's calendar. In my code, local source is null when the user has setup icloud account but did not give permissions to icloud account to write to calendar. So even if the app has the permission to write to calendar but local source is nil, hence, addition of event to calendar fails.

My code adds to calendar in the given 2 cases:

  1. user has signed into icloud and has given permission to icloud to write to calendar. In that case, local source is not nil and calendar is created with name 'someName' in 'iCloud'.
  2. user has not signed into icloud. Now, calendar is created with name 'someName' in 'on my iphone' local source.