Create new Reminders list with EventKit? - ios

My app uses EventKit to read and write new reminders to and from the Reminders app, which works well. However, I've only found a way to write reminders to the default list that the user selects in the Settings app... My question is, does anyone know if there's a way to create a whole new list, rather than use the default list.

Nope.
Apple doesn't allow apps to write to lists other than the default list - looking through the docs yields no way to do so.
YES!!!
Looking through some more literature, I found this!
It seems that the EKReminder objects can be added to any list - based on my limited understanding, this should work at least to write to a different list:
NSArray *calendars = [_eventStore
calendarsForEntityType:EKEntityTypeReminder];
for (EKCalendar *calendar in calendars)
{
NSLog(#"Calendar = %#", calendar.title);
}
EKCalendar *calendar = ... //pick one.
EKReminder *reminder = [EKReminder reminderWithEventStore:self.eventStore];
reminder.title = #"Go to the store and buy milk";
reminder.calendar = calendar;
NSError *error = nil;
[_eventStore saveReminder:reminder commit:YES error:&error];

Related

Deleting and recreating EKCalendar

In my app, I create events in an EKCalendar. I fetch the events online, and in order to refresh the events, I want to first delete the calendar (if it exists), recreate it, and then put the new events in there.
To instantiate the calendar I use
- (EKCalendar *)calendar {
if (!_calendar) {
NSArray *calendars = [self.store calendarsForEntityType:EKEntityTypeEvent];
NSString *calendarTitle = #"MyCalendar";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"title matches %#", calendarTitle];
NSArray *filtered = [calendars filteredArrayUsingPredicate:predicate];
if ([filtered count]) {
_calendar = [filtered firstObject];
} else {
_calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:self.store];
_calendar.title = calendarTitle;
_calendar.source = self.store.defaultCalendarForNewEvents.source;
NSError *calendarErr = nil;
BOOL calendarSuccess = [self.store saveCalendar:_calendar commit:YES error:&calendarErr];
if (!calendarSuccess) {
NSLog(#"Calendar Error = %#", [calendarErr localizedDescription]);
}
}
}
return _calendar;
}
To delete the calendar, I use
-(IBAction)deleteCalendar{
NSError *error = nil;
[self.store removeCalendar:_calendar commit:YES error:&error];
}
Both methods work fine individually.
So, when I start the creation of events, I do the following:
[self deleteCalendar];//delete calendar and its events, in case it already exists
[self calendar];//create calendar
[self importEvents];//put events in calendar
Now, what I observe is the following:
On the first run of the app
a calendar is created
events are imported. (This is expected, and works just fine)
While the app is running, I trigger the above methods again with a button. With the following, for me puzzling, result:
the calendar is deleted (expected result)
NO calendar is created (WHY? that is my main question).The "if (!_calendar)" part of the method is considered FALSE, and nothing is executed.
The 'importEvents' method runs through its regular hoopla, without any apparent errors, although I would expect something like a 'no source' error.
Please advise.
UPDATE:
This could be an indicator of what is happening, but I still don't get it:
After a while, the events appear in a different calendar, i.e. not the calendar called 'myCalendar', but another, iCloud based calendar, apparently the one that at that point is the defaultCalendarForNewEvents. However, that also doesn't make any sense to me.
OK, so, what is happening:
I have deleted the Calendar from the store, effectively, but a reference to that calendar actually was still hanging around in my app.
I solved it as follows:
-(IBAction)deleteCalendar:(id)sender{
NSError *error = nil;
if(_calendar){
[self.store removeCalendar:_calendar commit:YES error:&error];
}
_calendar = nil;
}
I hope this is useful to someone

Can't delete single ekevent of recurrent event in calendar iOS

I've developed an app that uses calendar using the eventkit.
The user can push a button and delete a specific event. Everything works just fine, except when it comes to recurrent events.
If the user itself created the recurrent events, it works as expected, the single event is deleted and the rest remains in calendar. But if the recurrent events is created by other and accepted by user and then try to delete one specific of those events, they all disappear from calendar. Why?
In this case iPad only uses one Exchange calendar, can the problem be Exchange specific?
/* Get the Exchange Calendar */
EKEventStore* store = [[EKEventStore alloc] init];
NSError* error = nil;
NSMutableArray* calendars = [[store calendarsForEntityType:EKEntityTypeEvent] mutableCopy];
NSMutableArray* cals = [[NSMutableArray alloc] init];
for (EKCalendar *cal in calendars) {
if (cal.type == EKCalendarTypeExchange) {
[cals addObject:cal];
break;
}
}
/* get the correct event, get Events with startDate & endDate and differ with eventId */
// (tappedEvent = event to remove)
NSPredicate *predicate = [store predicateForEventsWithStartDate:[tappedEvent valueForKey:#"from"] endDate:[tappedEvent valueForKey:#"to"] calendars:cals];
NSArray *theEvents=[store eventsMatchingPredicate:predicate];
NSString *recurrenceEventIdentifier = [tappedEvent valueForKey:#"appID"];
for(EKEvent * theEvent in theEvents){
if([theEvent.eventIdentifier isEqualToString: recurrenceEventIdentifier] && ![store removeEvent:theEvent span:EKSpanThisEvent error:&error]){
NSLog(#"Error in removing event: %#",error);
}
}
[store commit:&error];
if(error){
...
}

Can't retrieve event store calendars?

I have the iCloud calendars and some subscribed calendars on my device, all calendars apps including the native calendar app display the calendars correctly, but in my app i can't retrieve them.
I am trying to retrieve the event store calendars as follow:
A)
NSArray *calendarArray = [self.eventStore calendarsForEntityType:EKEntityTypeEvent];
// always return result an empty array
B)
NSMutableArray *calendars = [[NSMutableArray alloc]init];
for (EKSource *source in self.eventStore.sources) {
NSSet *sourceCalendars = [source calendarsForEntityType:EKEntityTypeEvent];
[calendars addObjectsFromArray:sourceCalendars.allObjects];
}
// always return result an empty array
The event store instance is allocated and initialized correctly, and the privacy for accessing calendars also granted.
What can I do ?
Regards
When you have more than 100 calendar and Reminder lists then event store stop working properly.
For more info check this link: http://support.apple.com/kb/HT4489?viewlocale=en_US

iOS - Can't add calendar event to Gmail calendar with EventKit

I want to add a new calendar event to the default iOS calendar. That works fine, until a user uses Gmail for syncing calendars.
I use the following code:
if (!calendar) {
calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
// set calendar name
[calendar setTitle:#"My calendar"];
EKSource *theSource = [eventStore defaultCalendarForNewEvents].source;
calendar.source = theSource;
// save this in NSUserDefaults data for retrieval later
NSString *calendarIdentifier = [calendar calendarIdentifier];
NSError *error = nil;
BOOL saved = [eventStore saveCalendar:calendar commit:YES error:&error];
if (saved) {
// saved successfuly, store it's identifier in NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:calendarIdentifier forKey:#"railplanner_calendar_identifier"];
} else {
// unable to save calendar
return NO;
}
}
This works fine when iCloud is enabled, or with local calendars.
But when a user uses Gmail for syncing calendars, my custom calendar doesn't appear in the calendars list. The local calendars disappear too.
Does anyone know how I can add a new calendar with a new event to a Gmail (or Google) Calendar?
Many thanks in advance.
This is likely to be impossible with the current Google Calendar synchronization, you could detect the type of the default calendar, and in the case of Google use the related Google iPhone API to create your new calendar (not really helpful I know)

Create a Calendar (in the ios native calendars) through an Application on the iphone

I want to know if it is possible to create a new calendar for your iphone through an application. I know you can set up event with an app, but can I make another calendar through the app to place all the events too.
EDIT:
IF it is not possible what would be the best work around, make a calendar and event store, and save that information with nscoding? Then retrieve afterwards?
If there is a possibilty to create a new calendar to integrate with the existing calendars, that is what I want to do.
This is how I have done this:
-(NSString*)createCal:(NSString*)myCalId;{
// Instantiate eventstore object
EKEventStore *store = [[EKEventStore alloc] init];
EKSource *localSource = nil;
for (EKSource *source in store.sources)
if (source.sourceType == EKSourceTypeLocal){
localSource = source;
break;
}
//this is you creating your calendar
EKCalendar *cal;
cal = [EKCalendar calendarWithEventStore:store];
cal.title = #"Name of calendar";
cal.source = localSource;
[store saveCalendar:cal commit:YES error:nil];
NSLog(#"cal id = %#", cal.calendarIdentifier);
return cal.calendarIdentifier;}
You will need to import <EventKit/EventKit.h>
This is powerful so you need to be careful and do a lot of verifications for example if the calendar already exist, and so on. Hope this helps.
Looking at the documentation for EventKit, it doesn't seem possible to create new calendars programatically. However, you can get a list of existing calendars and find out the default calendar.
Hope this helps.
You can't use the standard init-Method anymore; it's deprecated. Here the quote from the EKEventStore Class Reference:
"On iOS 5 and later, initialize an event store object with the default init method. On iOS 6 and later, you must request access to an entity type after the event store is initialized with requestAccessToEntityType:completion: for data to return.
On OS X, use initWithAccessToEntityTypes: instead of the default init method. Acceptable entity types are EKEntityMaskEvent for events and EKEntityMaskReminder for reminders."
So if you use iOS6, it's somethin like:
EKEventStore *store = [[EKEventStore alloc] initWithAccessToEntityTypes:completion:];
and
cal = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:store];
I need it for my MacOSX App. So i have to use this:
So in my Case (MacOSX) it's this solution. It's Sparqs code; just modify with the new init instead of the the standard one:
-(NSString*)createCal:(NSString*)myCalId;{
// Instantiate eventstore object
EKEventStore *store = [[EKEventStore alloc] initWithAccessToEntityTypes:EKEntityMaskEvent];
EKSource *localSource = nil;
for (EKSource *source in store.sources)
if (source.sourceType == EKSourceTypeLocal){
localSource = source;
break;
}
//this is you creating your calendar
EKCalendar *cal;
cal = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:store];
cal.title = #"Name of calendar";
cal.source = localSource;
[store saveCalendar:cal commit:YES error:nil];
NSLog(#"cal id = %#", cal.calendarIdentifier);
return cal.calendarIdentifier;}

Resources