Delete all future recurring event from iPhone calendar - ios

Can any one having idea how to delete recurring event from iPhone calendar?
I am using this code for store event which is repeat every week.
EKEventStore *eventSotre = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventSotre];
EKRecurrenceRule *recurrenceRule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyWeekly interval:1 end:nil];
[event addRecurrenceRule:recurrenceRule];
[event setCalendar:[eventSotre defaultCalendarForNewEvents]];
event.title= #"EventTitle";
NSDate *duedate = [NSDate date];
event.startDate =duedate;
event.endDate= duedate;
NSArray *arrAlarm = [NSArray arrayWithObject:[EKAlarm alarmWithAbsoluteDate:duedate]];
event.alarms= arrAlarm;
NSError *err;
BOOL isSuceess=[eventSotre saveEvent:event span:EKSpanThisEvent error:&err];
strIdentifier = [[NSString alloc] initWithFormat:#"%#", event.eventIdentifier];;
if(isSuceess){
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:#"Event added in calendar" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertview show];
}
else{
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:[err description] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertview show];
}
Now I want to delete all future events from the iPhone calendar.
Thanks!

Got Solution my self.
For delete all future events I am using this code
EKEventStore* store = [[EKEventStore alloc] init] ;
EKEvent* eventToRemove = [store eventWithIdentifier:strIdentifier];
if (eventToRemove != nil) {
NSError* error = nil;
[store removeEvent:eventToRemove span:EKSpanFutureEvents error:&error];
}
For Delete current day entry we have to use "EKSpanThisEvent" and for delete future events we have to use "EKSpanFutureEvents"

Related

Remove duplicate entries in calendar iOS

I'm trying to save the events in native calendar. However, my events are being saved in the calendar but every time I run the code on device or simulator it creates duplicate entries. I have used everything needed to avoid it but couldn't get any help.
Here is my code.
-(void )addEvents :(NSMutableArray *)sentarray{
for ( int i =0; i<sentarray.count; i++) {
Schedule *schdeule = [events objectAtIndex:i];
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error)
{
NSLog(#"Error in dispatching data in the queue");
}
else if (!granted) {
NSLog(#"NoPermission to access the calendar");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Cannot sync data with your calendar" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
else{
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title =schdeule.title;
event.startDate = schdeule.startDate; //today
event.endDate = schdeule.endDate; //set 1 hour meeting
event.calendar = [store defaultCalendarForNewEvents];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
// Store this so you can access this event later for editing
savedEventId = event.eventIdentifier;
if (!err) {
NSPredicate *predicateForEventsOnMeetingDate = [store predicateForEventsWithStartDate:schdeule.startDate endDate:schdeule.endDate calendars:nil]; // nil will search through all calendars
NSArray *eventsOnMeetingDate = [store eventsMatchingPredicate:predicateForEventsOnMeetingDate];
__block BOOL eventExists = NO;
[eventsOnMeetingDate enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
for (EKEvent *eventToCheck in eventsOnMeetingDate) {
if ([eventToCheck.title isEqualToString:schdeule.title]) {
eventExists = YES;
}
}
if (eventExists == NO) {
EKEvent *addEvent = [EKEvent eventWithEventStore:store];
addEvent.title = schdeule.title;
addEvent.startDate = schdeule.startDate;
addEvent.endDate =schdeule.endDate;
[addEvent setCalendar:[store defaultCalendarForNewEvents]];
[store saveEvent:addEvent span:EKSpanThisEvent commit:YES error:nil];
}
}];
NSLog(#"saved");
if (i == sentarray.count-1) {
// [[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"calshow://"]];
}
}
else {
NSLog(#"%#",[err localizedDescription]);
}
}
});
}];
}
}
apply break after eventExists = YES; like
... // other code
for (EKEvent *eventToCheck in eventsOnMeetingDate) {
if ([eventToCheck.title isEqualToString:schdeule.title]) {
eventExists = YES;
break;
}
}
... //other code

iOS - Add custom URI of our app to the event stored in calendar programmatically

i have a scenario where i am adding the event in calendar from my application. i have a custom url scheme for my app as myapp://
the code i am using to store the event in calendar is
-(void)addEventToCalender
{
NSDateComponents *components = [[NSDateComponents alloc]init];
[components setYear:2014];
[components setMonth:6];
[components setDay:15];
[components setHour:10];
[components setMinute:15];
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *eventDateAndTime = [cal dateFromComponents:components];
NSLog(#"Event Date and Time : %#",eventDateAndTime);
EKEventStore *store = [[EKEventStore alloc]init];
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = #"ttrrpp Trip";
event.notes = #"Go to application myapp://";
event.startDate = eventDateAndTime;
event.endDate = [[NSDate alloc]initWithTimeInterval:600 sinceDate:eventDateAndTime];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
NSString *savedEventId = event.eventIdentifier;
NSLog(#"Saved Event ID : %#",savedEventId);
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"ttrrpp" message:#"You have denied to provide access to calender. No events will be added." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}];
}
The event is added in calendar but i want to pass the url of my app to the notes so that it opens my app when the link in event notes is clicked. Kindly help me.
Thanks in advance.
You are very close ;-) . Assuming you have defined your custom URL scheme in your .plist, add a 'host' and 'path' to your custom URL scheme being placed in event.notes. (eg. myapp://myhost/mypath) Then something like...
-(BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url { - deprecated
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if (!url) {
return NO;
}
if([[url host] isEqualToString:#"myhost"])
{
//can also check [url path] if you want to
//do whatever
}
return YES;
}
PS: deprecated method worked for me with iOS6/7, haven't tried new method.

UiKit should be called from the main thread only warning

I am adding an event to a calendar on the click of a button. Whenever I click on that button the Xcode gives me a warning and hangs the app for about few seconds and then add the event into the calendar. the warning is as follows:
void _WebThreadLockFromAnyThread(bool), 0x175bd5c0: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.
the code which I am using for adding the event is as follows:
- (IBAction)btn_reminder_click:(id)sender{
[self addEventTocalendar];
}
- (void)addEventTocalendar{
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
if (btn_appointment.isSelected) {
event.title = #"Appointment Reminder.";
}
else if (btn_pickup.isSelected){
event.title = #"Pickup Reminder";
}
event.startDate = self.selectedDate;
event.endDate = [event.startDate dateByAddingTimeInterval:60*60];//set 1 hour meeting
event.notes = txt_notes.text;
event.recurrenceRules = EKRecurrenceFrequencyDaily;
[event addAlarm:[EKAlarm alarmWithRelativeOffset:60.0f * -5.0f]];
if (selectedIndex == 1) {
[event addRecurrenceRule:[[EKRecurrenceRule alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyDaily interval:1 end:Nil]];
}
else if (selectedIndex == 2){
[event addRecurrenceRule:[[EKRecurrenceRule alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyWeekly interval:1 end:Nil]];
}
else if (selectedIndex == 3){
[event addRecurrenceRule:[[EKRecurrenceRule alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly interval:1 end:Nil]];
}
else if (selectedIndex == 4){
[event addRecurrenceRule:[[EKRecurrenceRule alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyYearly interval:1 end:Nil]];
}
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
NSString *savedEventId = event.eventIdentifier; //this is so you can access this event later
BOOL isSuceess=[store saveEvent:event span:EKSpanThisEvent error:&err];
if(isSuceess){
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:#"Event added in calendar" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertview show];
}
else{
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:[err description] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertview show];
}
}];
}
cam Somebody help me o this as I am not able to solve this problem.
Your UIAlertView needs to be shown on the main thread. Try this:
if(isSuceess){
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:#"Event added in calendar" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[alertview show];
});
}
else {
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:[err description] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[alertview show];
});
}
UI Code must always run on the main thread.
You need to dispatch your code to the main thread. You can use something like this:
Swift
DispatchQueue.main.async
{
// Your code to execute
}

How to fix EKErrorDomain Code=1 "No calendar has been set

I want to create a calendar entry to the iPhone calendar, I have tried the following code
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = self.selectedPost.postTitle;
event.notes = self.selectedPost.postContent;
event.startDate = self.selectedPost.startDate;
event.endDate = self.selectedPost.endDate;
EKCalendar *targetCalendar = nil;
targetCalendar = [eventStore defaultCalendarForNewEvents];
NSLog(#"%#",targetCalendar);
[event setCalendar:targetCalendar];
NSError *err;
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
UIAlertView *alert = nil;
NSLog(#"err %#",err);
if (err) {
alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[err localizedDescription] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
}
else{
alert = [[UIAlertView alloc] initWithTitle:#"Success" message:#"Added to calender" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
}
[alert show];
but result is
2013-01-15 22:31:34.682 Project[40863:907] defaultCalendarForNewEvents failed: Error Domain=EKCADErrorDomain Code=1013 "The operation couldn’t be completed. (EKCADErrorDomain error 1013.)"
2013-01-15 22:31:34.683 Project[40863:907] (null)
2013-01-15 22:31:34.690 Project[40863:907] err Error Domain=EKErrorDomain Code=1 "No calendar has been set." UserInfo=0x1d535ba0 {NSLocalizedDescription=No calendar has been set.}
I know this is because of
[eventStore defaultCalendarForNewEvents];
returns null.
I have tried
[eventStore calendarWithIdentifier:event.calendarItemIdentifier];
and some other code but same result how to fix this
Any idea
If this is on iOS 6.0 or later, you'll have to first request access to the user's calendars before EventKit will hand them to you by using the method -[EKEventStore requestAccessToEntityType:completion:]
Check out the example given in the Calendar and Reminders Programming Guide
For the sake of not-wasting-your-time just make sure, that you are using the bit masks in -[EKEventStore requestAccessToEntityType:completion:]
like this
EKEventStore *eventStore = [[EKEventStore alloc] init];
[eventStore requestAccessToEntityType:EKEntityMaskEvent completion:^(BOOL granted, NSError *error) {
// ...
}];
I fixed it by making sure that the title wasn't the same as the one that i was creating, for example I have dance on several nights so for one night i would do Dance and the other one with a period at the beginning .Dance.
Add those lines
if(eventStore.defaultCalendarForNewEvents==nil)
*eventStore = [[EKEventStore alloc] init];
Second line will execute only first time when you grant access
Your code should look like this below
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = self.selectedPost.postTitle;
event.notes = self.selectedPost.postContent;
event.startDate = self.selectedPost.startDate;
event.endDate = self.selectedPost.endDate;
EKCalendar *targetCalendar = nil;
if(eventStore.defaultCalendarForNewEvents==nil)
*eventStore = [[EKEventStore alloc] init];
targetCalendar = [eventStore defaultCalendarForNewEvents];
NSLog(#"%#",targetCalendar);
[event setCalendar:targetCalendar];
NSError *err;
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
UIAlertView *alert = nil;
NSLog(#"err %#",err);
if (err) {
alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[err localizedDescription] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
}
else{
alert = [[UIAlertView alloc] initWithTitle:#"Success" message:#"Added to calender" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
}
[alert show];
this works for me

Why is my core data saving slow?

Every time I try to save my NSManagedObjectContex, it takes 1-8 seconds each time. Here is my code:
- (IBAction)save
{
if (self.managedObjectContext == nil) {
self.managedObjectContext = [(RootAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
if (self.brandText.text.length == 0 || self.modelText.text.length == 0) {
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Please fill out the required fields" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(125, 40, 31, 7)];
NSString *path = [[NSString alloc] initWithString:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"bullet.png"]];
UIImage *bkgImg = [[UIImage alloc] initWithContentsOfFile:path];
[imageView setImage:bkgImg];
[alertView addSubview:imageView];
[alertView show];
} else {
Hand *a = [NSEntityDescription insertNewObjectForEntityForName:#"Hand" inManagedObjectContext:self.managedObjectContext];
a.brand = self.brandText.text;
a.caliber = self.cText.text;
self.managedObjectContext = self.app.managedObjectContext;
a.notes = self.notesView.text;
a.serialNumber = self.serialNumberText.text;
a.nickname = self.nicknameText.text;
a.model = self.modelText.text;
a.gunImage = self.image.image;
a.roundsFired = [NSString stringWithFormat:#"0"];
a.cleanRounds = [NSString stringWithFormat:#"500"];
a.showBadge = [NSNumber numberWithBool:YES];
[self dismissViewControllerAnimated:YES completion:nil];
NSError *error;
if (![self.managedObjectContext save:&error]) {
UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"There was an internal error. \n Please restart the app and try again, Thank You" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[errorAlert show];
}
}
}
The code just saves the all of the textFields text. What is the reason its so slow? Any help is greatly appreciated.
Based on your question is quite difficult to understand what is going on but I would modify the else statement as follows...
else {
Hand *a = [NSEntityDescription insertNewObjectForEntityForName:#"Hand" inManagedObjectContext:self.managedObjectContext];
a.brand = self.brandText.text;
a.caliber = self.cText.text;
// why this?
// self.managedObjectContext = self.app.managedObjectContext;
a.notes = self.notesView.text;
a.serialNumber = self.serialNumberText.text;
a.nickname = self.nicknameText.text;
a.model = self.modelText.text;
a.gunImage = self.image.image;
a.roundsFired = [NSString stringWithFormat:#"0"];
a.cleanRounds = [NSString stringWithFormat:#"500"];
a.showBadge = [NSNumber numberWithBool:YES];
NSError *error;
if (![self.managedObjectContext save:&error]) { // error during saving
UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"There was an internal error. \n Please restart the app and try again, Thank You" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[errorAlert show];
} else { // the save completes correctly, dismiss the view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
}
If you want to monitor Core Data you should do it through Instrument. In addition you could set up Xcode as follows: XCode4 and Core Data: How to enable SQL Debugging.
Edit
Since the slow saving is due (based on your comment) to images, you should relies on these rules.
Core Data - Storing Images (iPhone)
Edit 2
Ok, since you don't know in advance about the size (in bytes) of your image, I really suggest to store the image in the filesystem and not in the Core Data store. In the db save only the path to your image. The image will be saved in background. This to prevent the UI to block.
Otherwise, if iOS 5 is the minimum requirement, use the External Storage flag.
How to enable External Storage for Binary Data in Core Data
Hope that helps.

Resources