diff --git a/README.md b/README.md index a024c348..feb53b2e 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,14 @@ Basic operations, you'll want to copy-paste this for testing purposes: var newTitle = "New title!"; window.plugins.calendar.modifyEvent(title,eventLocation,notes,startDate,endDate,newTitle,eventLocation,notes,startDate,endDate,success,error); + // or to add a reminder, make it recurring, change the calendar, or the url, use this one: + var filterOptions = window.plugins.calendar.getCalendarOptions(); // or {} or null for the defaults + filterOptions.calendarName = "Bla"; // only filter option currently implemented (iOS only) + var newOptions = window.plugins.calendar.getCalendarOptions(); + newOptions.calendaName = "New Bla"; // make sure this calendar exists before moving the event to it + newOptions.firstReminderMinutes = 120; // etc + window.plugins.calendar.modifyEventWithOptions(title,eventLocation,notes,startDate,endDate,newTitle,eventLocation,notes,startDate,endDate,filterOptions,newOptions,success,error); + // delete an event (you can pass nulls for irrelevant parameters, note that on Android `notes` is ignored). The dates are mandatory and represent a date range to delete events in. // note that on iOS there is a bug where the timespan must not be larger than 4 years, see issue 102 for details.. call this method multiple times if need be // since 4.3.0 you can match events starting with a prefix title, so if your event title is 'My app - cool event' then 'My app -' will match. diff --git a/src/ios/Calendar.h b/src/ios/Calendar.h index b48bc4ef..569fb2cc 100644 --- a/src/ios/Calendar.h +++ b/src/ios/Calendar.h @@ -26,8 +26,7 @@ - (void)createEventInteractively:(CDVInvokedUrlCommand*)command; - (void)createEventInNamedCalendar:(CDVInvokedUrlCommand*)command; -- (void)modifyEvent:(CDVInvokedUrlCommand*)command; -- (void)modifyEventInNamedCalendar:(CDVInvokedUrlCommand*)command; +- (void)modifyEventWithOptions:(CDVInvokedUrlCommand*)command; - (void)findEventWithOptions:(CDVInvokedUrlCommand*)command; - (void)findAllEventsInNamedCalendar:(CDVInvokedUrlCommand*)command; diff --git a/src/ios/Calendar.m b/src/ios/Calendar.m index 4393100f..e378d170 100644 --- a/src/ios/Calendar.m +++ b/src/ios/Calendar.m @@ -48,18 +48,18 @@ - (void)createEventWithCalendar:(CDVInvokedUrlCommand*)command NSString* notes = [options objectForKey:@"notes"]; NSNumber* startTime = [options objectForKey:@"startTime"]; NSNumber* endTime = [options objectForKey:@"endTime"]; - + NSTimeInterval _startInterval = [startTime doubleValue] / 1000; // strip millis NSDate *myStartDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; - + NSTimeInterval _endInterval = [endTime doubleValue] / 1000; // strip millis - + EKEvent *myEvent = [EKEvent eventWithEventStore: self.eventStore]; myEvent.title = title; myEvent.location = location; myEvent.notes = notes; myEvent.startDate = myStartDate; - + int duration = _endInterval - _startInterval; int moduloDay = duration % (60*60*24); if (moduloDay == 0) { @@ -69,18 +69,18 @@ - (void)createEventWithCalendar:(CDVInvokedUrlCommand*)command myEvent.endDate = [NSDate dateWithTimeIntervalSince1970:_endInterval]; } myEvent.calendar = calendar; - + // if a custom reminder is required: use createCalendarWithOptions EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*60*60]; [myEvent addAlarm:reminder]; - + NSError *error = nil; [self.eventStore saveEvent:myEvent span:EKSpanThisEvent error:&error]; - + if (error) { CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.userInfo.description]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - + } else { NSLog(@"Reached Success"); CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; @@ -102,38 +102,70 @@ -(EKRecurrenceFrequency) toEKRecurrenceFrequency:(NSString*) recurrence { return EKRecurrenceFrequencyDaily; } --(void)modifyEventWithCalendar:(CDVInvokedUrlCommand*)command - calendar: (EKCalendar *) calendar { - +-(void)modifyEventWithOptions:(CDVInvokedUrlCommand*)command { + NSDictionary* options = [command.arguments objectAtIndex:0]; NSString* title = [options objectForKey:@"title"]; NSString* location = [options objectForKey:@"location"]; NSString* notes = [options objectForKey:@"notes"]; NSNumber* startTime = [options objectForKey:@"startTime"]; NSNumber* endTime = [options objectForKey:@"endTime"]; - + NSString* ntitle = [options objectForKey:@"newTitle"]; NSString* nlocation = [options objectForKey:@"newLocation"]; NSString* nnotes = [options objectForKey:@"newNotes"]; NSNumber* nstartTime = [options objectForKey:@"newStartTime"]; NSNumber* nendTime = [options objectForKey:@"newEndTime"]; - + NSTimeInterval _startInterval = [startTime doubleValue] / 1000; // strip millis NSDate *myStartDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; - + NSTimeInterval _endInterval = [endTime doubleValue] / 1000; // strip millis NSDate *myEndDate = [NSDate dateWithTimeIntervalSince1970:_endInterval]; - + NSDateFormatter *df = [[NSDateFormatter alloc] init]; [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + + NSDictionary* calOptions = [options objectForKey:@"options"]; + // the only search param we're currently matching against is the calendarName, so ignoring any passed reminder values etc + NSString* calendarName = [calOptions objectForKey:@"calendarName"]; + EKCalendar* calendar; + if (calendarName == (id)[NSNull null]) { + calendar = self.eventStore.defaultCalendarForNewEvents; + if (calendar == nil) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No default calendar found. Is access to the Calendar blocked for this app?"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + } else { + calendar = [self findEKCalendar:calendarName]; + if (calendar == nil) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Could not find calendar"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + } // Find matches NSArray *matchingEvents = [self findEKEventsWithTitle:title location:location notes:notes startDate:myStartDate endDate:myEndDate calendar:calendar]; - + if (matchingEvents.count == 1) { + // Presume we have to have an exact match to modify it! // Need to load this event from an EKEventStore so we can edit it EKEvent *theEvent = [self.eventStore eventWithIdentifier:((EKEvent*)[matchingEvents lastObject]).eventIdentifier]; + + NSDictionary* newCalOptions = [options objectForKey:@"newOptions"]; + NSString* newCalendarName = [newCalOptions objectForKey:@"calendarName"]; + if (newCalendarName != (id)[NSNull null]) { + theEvent.calendar = [self findEKCalendar:calendarName]; + if (theEvent.calendar == nil) { + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Could not find calendar passed in newOptions object"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + } + if (ntitle) { theEvent.title = ntitle; } @@ -151,11 +183,43 @@ -(void)modifyEventWithCalendar:(CDVInvokedUrlCommand*)command NSTimeInterval _nendInterval = [nendTime doubleValue] / 1000; // strip millis theEvent.endDate = [NSDate dateWithTimeIntervalSince1970:_nendInterval]; } + + NSNumber* firstReminderMinutes = [newCalOptions objectForKey:@"firstReminderMinutes"]; + if (firstReminderMinutes != (id)[NSNull null]) { + EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*firstReminderMinutes.intValue*60]; + [theEvent addAlarm:reminder]; + } + + NSNumber* secondReminderMinutes = [newCalOptions objectForKey:@"secondReminderMinutes"]; + if (secondReminderMinutes != (id)[NSNull null]) { + EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*secondReminderMinutes.intValue*60]; + [theEvent addAlarm:reminder]; + } + NSString* recurrence = [newCalOptions objectForKey:@"recurrence"]; + if (recurrence != (id)[NSNull null]) { + EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: [self toEKRecurrenceFrequency:recurrence] + interval: 1 + end: nil]; + NSString* recurrenceEndTime = [newCalOptions objectForKey:@"recurrenceEndTime"]; + if (recurrenceEndTime != nil) { + NSTimeInterval _recurrenceEndTimeInterval = [recurrenceEndTime doubleValue] / 1000; // strip millis + NSDate *myRecurrenceEndDate = [NSDate dateWithTimeIntervalSince1970:_recurrenceEndTimeInterval]; + EKRecurrenceEnd *end = [EKRecurrenceEnd recurrenceEndWithEndDate:myRecurrenceEndDate]; + rule.recurrenceEnd = end; + } + [theEvent addRecurrenceRule:rule]; + } + NSString* url = [newCalOptions objectForKey:@"url"]; + if (url != (id)[NSNull null]) { + NSURL* myUrl = [NSURL URLWithString:url]; + theEvent.URL = myUrl; + } + // Now save the new details back to the store NSError *error = nil; [self.eventStore saveEvent:theEvent span:EKSpanThisEvent error:&error]; - + // Check error code + return result if (error) { CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.userInfo.description]; @@ -174,28 +238,28 @@ -(void)modifyEventWithCalendar:(CDVInvokedUrlCommand*)command - (void)deleteEventFromCalendar:(CDVInvokedUrlCommand*)command calendar: (EKCalendar *) calendar { - + NSDictionary* options = [command.arguments objectAtIndex:0]; NSString* title = [options objectForKey:@"title"]; NSString* location = [options objectForKey:@"location"]; NSString* notes = [options objectForKey:@"notes"]; NSNumber* startTime = [options objectForKey:@"startTime"]; NSNumber* endTime = [options objectForKey:@"endTime"]; - + NSTimeInterval _startInterval = [startTime doubleValue] / 1000; // strip millis NSDate *myStartDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; - + NSTimeInterval _endInterval = [endTime doubleValue] / 1000; // strip millis NSDate *myEndDate = [NSDate dateWithTimeIntervalSince1970:_endInterval]; - + NSArray *matchingEvents = [self findEKEventsWithTitle:title location:location notes:notes startDate:myStartDate endDate:myEndDate calendar:calendar]; - + NSError *error = NULL; for (EKEvent * event in matchingEvents) { // NOTE: as per issue #150 you can delete this event AND future events by passing span:EKSpanFutureEvents [self.eventStore removeEvent:event span:EKSpanThisEvent error:&error]; } - + if (error) { CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.userInfo.description]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -211,7 +275,7 @@ -(NSArray*)findEKEventsWithTitle: (NSString *)title startDate: (NSDate *)startDate endDate: (NSDate *)endDate calendar: (EKCalendar *) calendar { - + NSMutableArray *predicateStrings = [NSMutableArray arrayWithCapacity:3]; if (title != (id)[NSNull null] && title.length > 0) { title = [title stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]; @@ -225,27 +289,27 @@ -(NSArray*)findEKEventsWithTitle: (NSString *)title notes = [notes stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]; [predicateStrings addObject:[NSString stringWithFormat:@"notes == '%@'", notes]]; } - + NSString *predicateString = [predicateStrings componentsJoinedByString:@" AND "]; - + NSPredicate *matches; NSArray *calendarArray, *datedEvents, *matchingEvents; - + if (predicateString.length > 0) { matches = [NSPredicate predicateWithFormat:predicateString]; calendarArray = [NSArray arrayWithObject:calendar]; - + datedEvents = [self.eventStore eventsMatchingPredicate:[eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarArray]]; - + matchingEvents = [datedEvents filteredArrayUsingPredicate:matches]; } else { calendarArray = [NSArray arrayWithObject:calendar]; - + datedEvents = [self.eventStore eventsMatchingPredicate:[eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarArray]]; - + matchingEvents = datedEvents; } - + return matchingEvents; } @@ -267,7 +331,7 @@ -(EKSource*)findEKSource { return source; } } - + // ok, not found.. so it's a local calendar for (EKSource *source in self.eventStore.sources) { if (source.sourceType == EKSourceTypeLocal) { @@ -279,10 +343,10 @@ -(EKSource*)findEKSource { -(NSMutableArray*)eventsToDataArray: (NSArray*)matchingEvents { NSMutableArray *results = [[NSMutableArray alloc] initWithCapacity:matchingEvents.count]; - + NSDateFormatter *df = [[NSDateFormatter alloc] init]; [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; - + for (EKEvent * event in matchingEvents) { NSMutableDictionary *entry = [[NSMutableDictionary alloc] initWithObjectsAndKeys: event.title, @"title", @@ -300,11 +364,11 @@ -(NSMutableArray*)eventsToDataArray: (NSArray*)matchingEvents { if (event.attendees != nil) { NSMutableArray * attendees = [[NSMutableArray alloc] init]; for (EKParticipant * participant in event.attendees) { - + NSString *role = [[NSArray arrayWithObjects:@"Unknown", @"Required", @"Optional", @"Chair", @"Non Participant", nil] objectAtIndex:participant.participantRole]; NSString *status = [[NSArray arrayWithObjects:@"Unknown", @"Pending", @"Accepted", @"Declined", @"Tentative", @"Delegated", @"Completed", @"In Process", nil] objectAtIndex:participant.participantStatus]; NSString *type = [[NSArray arrayWithObjects:@"Unknown", @"Person", @"Room", @"Resource", @"Group", nil] objectAtIndex:participant.participantType]; - + NSMutableDictionary *attendeeEntry = [[NSMutableDictionary alloc] initWithObjectsAndKeys: participant.name, @"name", [participant.URL absoluteString], @"URL", @@ -326,11 +390,11 @@ -(NSMutableArray*)eventsToDataArray: (NSArray*)matchingEvents { - (void)openCalendar:(CDVInvokedUrlCommand*)command { NSDictionary* options = [command.arguments objectAtIndex:0]; NSNumber* date = [options objectForKey:@"date"]; - + NSTimeInterval _startInterval = [date doubleValue] / 1000; // strip millis NSDate *openDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; NSInteger interval = [openDate timeIntervalSinceReferenceDate]; - + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"calshow:%ld", interval]]; [[UIApplication sharedApplication] openURL:url]; } @@ -347,7 +411,7 @@ - (void)listCalendars:(CDVInvokedUrlCommand*)command { nil]; [finalResults addObject:entry]; } - + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsArray:finalResults]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @@ -369,13 +433,13 @@ - (void)listEventsInRange:(CDVInvokedUrlCommand*)command { - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command { NSDictionary* options = [command.arguments objectAtIndex:0]; - + NSString* title = [options objectForKey:@"title"]; NSString* location = [options objectForKey:@"location"]; NSString* notes = [options objectForKey:@"notes"]; NSNumber* startTime = [options objectForKey:@"startTime"]; NSNumber* endTime = [options objectForKey:@"endTime"]; - + NSDictionary* calOptions = [options objectForKey:@"options"]; NSNumber* firstReminderMinutes = [calOptions objectForKey:@"firstReminderMinutes"]; NSNumber* secondReminderMinutes = [calOptions objectForKey:@"secondReminderMinutes"]; @@ -383,23 +447,23 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command { NSString* recurrenceEndTime = [calOptions objectForKey:@"recurrenceEndTime"]; NSString* calendarName = [calOptions objectForKey:@"calendarName"]; NSString* url = [calOptions objectForKey:@"url"]; - + EKEvent *myEvent = [EKEvent eventWithEventStore: self.eventStore]; if (url != (id)[NSNull null]) { NSURL* myUrl = [NSURL URLWithString:url]; myEvent.URL = myUrl; } - + NSTimeInterval _startInterval = [startTime doubleValue] / 1000; // strip millis NSDate *myStartDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; - + NSTimeInterval _endInterval = [endTime doubleValue] / 1000; // strip millis - + myEvent.title = title; myEvent.location = location; myEvent.notes = notes; myEvent.startDate = myStartDate; - + int duration = _endInterval - _startInterval; int moduloDay = duration % (60*60*24); if (moduloDay == 0) { @@ -408,7 +472,7 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command { } else { myEvent.endDate = [NSDate dateWithTimeIntervalSince1970:_endInterval]; } - + EKCalendar* calendar = nil; if (calendarName == (id)[NSNull null]) { calendar = self.eventStore.defaultCalendarForNewEvents; @@ -426,17 +490,17 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command { } } myEvent.calendar = calendar; - + if (firstReminderMinutes != (id)[NSNull null]) { EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*firstReminderMinutes.intValue*60]; [myEvent addAlarm:reminder]; } - + if (secondReminderMinutes != (id)[NSNull null]) { EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*secondReminderMinutes.intValue*60]; [myEvent addAlarm:reminder]; } - + if (recurrence != (id)[NSNull null]) { EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: [self toEKRecurrenceFrequency:recurrence] interval: 1 @@ -449,10 +513,10 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command { } [myEvent addRecurrenceRule:rule]; } - + NSError *error = nil; [self.eventStore saveEvent:myEvent span:EKSpanThisEvent error:&error]; - + if (error) { CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.userInfo.description]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -465,13 +529,13 @@ - (void)createEventWithOptions:(CDVInvokedUrlCommand*)command { - (void)createEventInteractively:(CDVInvokedUrlCommand*)command { NSDictionary* options = [command.arguments objectAtIndex:0]; - + NSString* title = [options objectForKey:@"title"]; NSString* location = [options objectForKey:@"location"]; NSString* notes = [options objectForKey:@"notes"]; NSNumber* startTime = [options objectForKey:@"startTime"]; NSNumber* endTime = [options objectForKey:@"endTime"]; - + NSDictionary* calOptions = [options objectForKey:@"options"]; NSNumber* firstReminderMinutes = [calOptions objectForKey:@"firstReminderMinutes"]; NSNumber* secondReminderMinutes = [calOptions objectForKey:@"secondReminderMinutes"]; @@ -479,23 +543,23 @@ - (void)createEventInteractively:(CDVInvokedUrlCommand*)command { NSString* recurrenceEndTime = [calOptions objectForKey:@"recurrenceEndTime"]; NSString* calendarName = [calOptions objectForKey:@"calendarName"]; NSString* url = [calOptions objectForKey:@"url"]; - + EKEvent *myEvent = [EKEvent eventWithEventStore: self.eventStore]; if (url != (id)[NSNull null]) { NSURL* myUrl = [NSURL URLWithString:url]; myEvent.URL = myUrl; } - + NSTimeInterval _startInterval = [startTime doubleValue] / 1000; // strip millis NSDate *myStartDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; - + NSTimeInterval _endInterval = [endTime doubleValue] / 1000; // strip millis - + myEvent.title = title; myEvent.location = location; myEvent.notes = notes; myEvent.startDate = myStartDate; - + int duration = _endInterval - _startInterval; int moduloDay = duration % (60*60*24); if (moduloDay == 0) { @@ -504,7 +568,7 @@ - (void)createEventInteractively:(CDVInvokedUrlCommand*)command { } else { myEvent.endDate = [NSDate dateWithTimeIntervalSince1970:_endInterval]; } - + EKCalendar* calendar = nil; if (calendarName == (id)[NSNull null]) { calendar = self.eventStore.defaultCalendarForNewEvents; @@ -522,17 +586,17 @@ - (void)createEventInteractively:(CDVInvokedUrlCommand*)command { } } myEvent.calendar = calendar; - + if (firstReminderMinutes != (id)[NSNull null]) { EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*firstReminderMinutes.intValue*60]; [myEvent addAlarm:reminder]; } - + if (secondReminderMinutes != (id)[NSNull null]) { EKAlarm *reminder = [EKAlarm alarmWithRelativeOffset:-1*secondReminderMinutes.intValue*60]; [myEvent addAlarm:reminder]; } - + if (recurrence != (id)[NSNull null]) { EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: [self toEKRecurrenceFrequency:recurrence] interval: 1 @@ -545,9 +609,9 @@ - (void)createEventInteractively:(CDVInvokedUrlCommand*)command { } [myEvent addRecurrenceRule:rule]; } - + self.interactiveCallbackId = command.callbackId; - + EKEventEditViewController* controller = [[EKEventEditViewController alloc] init]; controller.event = myEvent; controller.eventStore = self.eventStore; @@ -578,31 +642,6 @@ -(void)deleteEvent:(CDVInvokedUrlCommand*)command { } } - --(void)modifyEventInNamedCalendar:(CDVInvokedUrlCommand*)command { - NSDictionary* options = [command.arguments objectAtIndex:0]; - NSString* calendarName = [options objectForKey:@"calendarName"]; - EKCalendar* calendar = [self findEKCalendar:calendarName]; - if (calendar == nil) { - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Could not find calendar"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } else { - [self modifyEventWithCalendar:command calendar:calendar]; - } -} - - --(void)modifyEvent:(CDVInvokedUrlCommand*)command { - EKCalendar* calendar = self.eventStore.defaultCalendarForNewEvents; - if (calendar == nil) { - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No default calendar found. Is access to the Calendar blocked for this app?"]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } else { - [self modifyEventWithCalendar:command calendar: calendar]; - } -} - - -(void)findAllEventsInNamedCalendar:(CDVInvokedUrlCommand*)command { NSDictionary* options = [command.arguments objectAtIndex:0]; NSString* calendarName = [options objectForKey:@"calendarName"]; @@ -629,17 +668,17 @@ -(void)findEventWithOptions:(CDVInvokedUrlCommand*)command { NSString* notes = [options objectForKey:@"notes"]; NSNumber* startTime = [options objectForKey:@"startTime"]; NSNumber* endTime = [options objectForKey:@"endTime"]; - + // actually the only option we're currently using is calendarName NSDictionary* calOptions = [options objectForKey:@"options"]; NSString* calendarName = [calOptions objectForKey:@"calendarName"]; - + NSTimeInterval _startInterval = [startTime doubleValue] / 1000; // strip millis NSDate *myStartDate = [NSDate dateWithTimeIntervalSince1970:_startInterval]; - + NSTimeInterval _endInterval = [endTime doubleValue] / 1000; // strip millis NSDate *myEndDate = [NSDate dateWithTimeIntervalSince1970:_endInterval]; - + EKCalendar* calendar = nil; if (calendarName == (id)[NSNull null]) { calendar = self.eventStore.defaultCalendarForNewEvents; @@ -656,7 +695,7 @@ -(void)findEventWithOptions:(CDVInvokedUrlCommand*)command { return; } } - + NSArray *matchingEvents = [self findEKEventsWithTitle:title location:location notes:notes startDate:myStartDate endDate:myEndDate calendar:calendar]; NSMutableArray * eventsDataArray = [self eventsToDataArray:matchingEvents]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsArray:eventsDataArray]; @@ -668,7 +707,7 @@ -(void)createCalendar:(CDVInvokedUrlCommand*)command { NSDictionary* options = [command.arguments objectAtIndex:0]; NSString* calendarName = [options objectForKey:@"calendarName"]; NSString* hexColor = [options objectForKey:@"calendarColor"]; - + EKCalendar *cal = [self findEKCalendar:calendarName]; if (cal == nil) { cal = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:self.eventStore]; @@ -678,7 +717,7 @@ -(void)createCalendar:(CDVInvokedUrlCommand*)command { cal.CGColor = theColor.CGColor; } cal.source = [self findEKSource]; - + // if the user did not allow permission to access the calendar, the error Object will be filled NSError* error; [self.eventStore saveCalendar:cal commit:YES error:&error]; @@ -691,7 +730,7 @@ -(void)createCalendar:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Calendar could not be created. Is access to the Calendar blocked for this app?"]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - + } else { // ok, it already exists CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString:@"OK, Calendar already exists"]; @@ -711,9 +750,9 @@ - (UIColor *)colorFromHexString:(NSString *)hexString { -(void)deleteCalendar:(CDVInvokedUrlCommand*)command { NSDictionary* options = [command.arguments objectAtIndex:0]; NSString* calendarName = [options objectForKey:@"calendarName"]; - + EKCalendar *thisCalendar = [self findEKCalendar:calendarName]; - + if (thisCalendar == nil) { CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -733,33 +772,33 @@ -(void)deleteCalendar:(CDVInvokedUrlCommand*)command { } - (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action { - NSError *error = nil; - - switch (action) { - case EKEventEditViewActionCanceled: - break; - - case EKEventEditViewActionSaved: - [controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error]; - break; - - case EKEventEditViewActionDeleted: - break; - - default: - break; - } - - [controller dismissViewControllerAnimated:YES completion:nil]; - - if (error) { - CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.userInfo.description]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.interactiveCallbackId]; - } else { - NSLog(@"Reached Success"); - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.interactiveCallbackId]; - } + NSError *error = nil; + + switch (action) { + case EKEventEditViewActionCanceled: + break; + + case EKEventEditViewActionSaved: + [controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error]; + break; + + case EKEventEditViewActionDeleted: + break; + + default: + break; + } + + [controller dismissViewControllerAnimated:YES completion:nil]; + + if (error) { + CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.userInfo.description]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.interactiveCallbackId]; + } else { + NSLog(@"Reached Success"); + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:self.interactiveCallbackId]; + } } @end diff --git a/www/Calendar.js b/www/Calendar.js index 1626bff5..0abe19e8 100644 --- a/www/Calendar.js +++ b/www/Calendar.js @@ -187,12 +187,32 @@ Calendar.prototype.deleteEventFromNamedCalendar = function (title, location, not }]) }; -Calendar.prototype.modifyEvent = function (title, location, notes, startDate, endDate, newTitle, newLocation, newNotes, newStartDate, newEndDate, successCallback, errorCallback) { +Calendar.prototype.modifyEventWithOptions = function (title, location, notes, startDate, endDate, newTitle, newLocation, newNotes, newStartDate, newEndDate, options, newOptions, successCallback, errorCallback) { if (!(newStartDate instanceof Date && newEndDate instanceof Date)) { errorCallback("newStartDate and newEndDate must be JavaScript Date Objects"); return; } - cordova.exec(successCallback, errorCallback, "Calendar", "modifyEvent", [{ + // merge passed options with defaults + var mergedOptions = Calendar.prototype.getCalendarOptions(); + for (var val in options) { + if (options.hasOwnProperty(val)) { + mergedOptions[val] = options[val]; + } + } + if (options.recurrenceEndDate != null) { + mergedOptions.recurrenceEndTime = options.recurrenceEndDate.getTime(); + } + // and also merge passed newOptions with defaults + var newMergedOptions = Calendar.prototype.getCalendarOptions(); + for (var val2 in newOptions) { + if (newOptions.hasOwnProperty(val2)) { + newMergedOptions[val2] = newOptions[val2]; + } + } + if (newOptions.recurrenceEndDate != null) { + newMergedOptions.recurrenceEndTime = newOptions.recurrenceEndDate.getTime(); + } + cordova.exec(successCallback, errorCallback, "Calendar", "modifyEventWithOptions", [{ "title": title, "location": location, "notes": notes, @@ -202,28 +222,20 @@ Calendar.prototype.modifyEvent = function (title, location, notes, startDate, en "newLocation": newLocation, "newNotes": newNotes, "newStartTime": newStartDate instanceof Date ? newStartDate.getTime() : null, - "newEndTime": newEndDate instanceof Date ? newEndDate.getTime() : null + "newEndTime": newEndDate instanceof Date ? newEndDate.getTime() : null, + "options": mergedOptions, + "newOptions": newMergedOptions }]) }; +Calendar.prototype.modifyEvent = function (title, location, notes, startDate, endDate, newTitle, newLocation, newNotes, newStartDate, newEndDate, successCallback, errorCallback) { + Calendar.prototype.modifyEventWithOptions(title, location, notes, startDate, endDate, newTitle, newLocation, newNotes, newStartDate, newEndDate, {}, successCallback, errorCallback); +}; + Calendar.prototype.modifyEventInNamedCalendar = function (title, location, notes, startDate, endDate, newTitle, newLocation, newNotes, newStartDate, newEndDate, calendarName, successCallback, errorCallback) { - if (!(newStartDate instanceof Date && newEndDate instanceof Date)) { - errorCallback("newStartDate and newEndDate must be JavaScript Date Objects"); - return; - } - cordova.exec(successCallback, errorCallback, "Calendar", "modifyEventInNamedCalendar", [{ - "title": title, - "location": location, - "notes": notes, - "startTime": startDate instanceof Date ? startDate.getTime() : null, - "endTime": endDate instanceof Date ? endDate.getTime() : null, - "newTitle": newTitle, - "newLocation": newLocation, - "newNotes": newNotes, - "newStartTime": newStartDate instanceof Date ? newStartDate.getTime() : null, - "newEndTime": newEndDate instanceof Date ? newEndDate.getTime() : null, - "calendarName": calendarName - }]) + var options = Calendar.prototype.getCalendarOptions(); + options.calendarName = calendarName; + Calendar.prototype.modifyEventWithOptions(title, location, notes, startDate, endDate, newTitle, newLocation, newNotes, newStartDate, newEndDate, options, successCallback, errorCallback); }; Calendar.prototype.listEventsInRange = function (startDate, endDate, successCallback, errorCallback) {