In my Application i need to attach(show iphone inbuilt calender) in-built iphone calendar on the UIButton action. More, The text from my UIViewControllers UILabel, I need attach that text in iphones in built calendar as reminder, where user is free to select date according his need.
I had found like EventKIt framework may be useful to me, But i am not sure. And i am also not familiar with EventKit framework.
Just Use this example with EventKit framwork.
-(IBAction)buttonAction:(id)sender
{
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEventStore *eventStore = [[[EKEventStore alloc] init] autorelease];
if([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
// iOS 6 and later
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted){
//---- codes here when user allow your app to access theirs' calendar.
[self performCalendarActivity:eventStore];
}else
{
//----- codes here when user NOT allow your app to access the calendar.
}
}];
}
else {
//---- codes here for IOS < 6.0.
[self performCalendarActivity:eventStore];
}
}
-(void)performCalendarActivity:(EKEventStore *)eventStore
{
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = #"EVENT TITLE";
event.startDate = [[NSDate alloc] init];
event.endDate = [[NSDate alloc] initWithTimeInterval:600 sinceDate:event.startDate];
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
}
Don't forget to import #import <EventKit/EventKit.h> to your view controller.
Related
I am trying to open calendar with specific event, I have added events programmatically and all the IDs of these event are persistent.
This is how i add event
-(IBAction)addEvent:(id)sender{
EKEventStore *store = [[EKEventStore alloc]init];
[store requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = #"Demo Title";
NSDateComponents *comps=[[NSDateComponents alloc]init];
[comps setDay:4];
[comps setMonth:10];
[comps setYear:2016];
[comps setHour:12];
[comps setMinute:1];
NSDate *date=[[[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian] dateFromComponents:comps];
_date=date;
event.startDate = date;
event.endDate=date;
event.notes=#"This is event description";
EKAlarm *alarm=[EKAlarm alarmWithAbsoluteDate:date];
[event addAlarm:alarm];
event.calendar = [store defaultCalendarForNewEvents];
NSError *err=nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
}];
}
The event is added successfully and i'm also able to open calendar app but the thing is i can't navigate inside the event detail in calendar
here is how i open calendar
-(IBAction)openCalender:(id)sender{
NSInteger interval = [_date timeIntervalSinceReferenceDate];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"calshow:%ld?eventid=%#", (long)interval,_eventID]];
NSLog(#"%#",url);
[[UIApplication sharedApplication] openURL:url];
}
What i want is in below screenshot
What i'm getting is
any idea?
To answer my own question, this isn't possible with any of public API
I searched over a year but this is not possible with any public API, but i guess there might be some private API to do this (and probably doing that will get our app rejected).
Widget of calendar app is doing the same what i want to do but it's Apple's API wont allow us to use it. lol
I really don't think there's a way to do this. Even when creating a new calendar event from the default Mail app opens the calendar day view. If this functionality was possible I'm sure they would have at least implemented it in the default mail app.
I am trying to add event in iOS app using Event kit with following code:
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
dispatch_async(dispatch_get_main_queue(), ^{
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = eventName;
event.startDate = [NSDate dateFromString:[NSString stringWithFormat:#"%# %#",[arrEvent objectAtIndex:1],[arrEvent objectAtIndex:2]] withFormat:#"MM/dd/yyyy HH:mm"];
event.endDate = [NSDate dateFromString:[NSString stringWithFormat:#"%# %#",[arrEvent objectAtIndex:1],[arrEvent objectAtIndex:3]] withFormat:#"MM/dd/yyyy HH:mm"];
[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
NSLog(#"%#",savedEventId);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Event added to calendar" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:#"View Calendar", nil];
alert.tag = 101;
[alert show];
});
}];
But I am getting granted as false so it doesn't add the event. It is not working in my simulator and device both, even after I reset my simulator. Same code works in another app of mine. Can someone please suggest me what I should do?
Edit: Error is always nil
When app launched for first time, a message asking for permissions will be shown to the user, and app will be able to access the calendar if only the user granted permission. In your case you have declined permission for calendar.
For fixing this issue, Go to Settings -> -> Allow to access calendar = YES.
Seems like you're requesting to get the access every time. You should better check the authorisation status first and if it's not determined, only then request for the authorisation. First check this using "authorizationStatusForEntityType" and create a new method to save the event, not inside "requestAccessToEntityType".
I have added an event on the default calendar on iPhone using the following code:
EKEventStore *store=[[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) {
return ;
}
EKEvent *event=[EKEvent eventWithEventStore:store];
event.title=#"This is the event";
event.startDate=[NSDate date];
event.endDate =[event.startDate dateByAddingTimeInterval:60*60];
event.allDay=YES;
NSURL *url=[NSURL URLWithString:#"http://www.google.com"];
event.URL=url;
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *errr=nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&errr]; // NSLog(#"%#",errr); // NSLog(#"%#",event.eventIdentifier);
}];
Now I want to delete this event.
The code I tried is this:
EKEventStore *store1=[[EKEventStore alloc]init];
NSPredicate *predicate=[store1 predicateForEventsWithStartDate:[[tableViewScheduleArray objectAtIndex:btn.tag] objectForKey:#"Schedule_Date"] endDate:[[tableViewScheduleArray objectAtIndex:btn.tag] objectForKey:#"Schedule_End_Time"] calendars:nil];
NSArray *arr=[store eventsMatchingPredicate:predicate];
dispatch_async(dispatch_get_main_queue(), ^{
[store1 removeEvent:[arr objectAtIndex:0] span:EKSpanThisEvent commit:YES error:nil];
});
It didn't work, but it didn't result in an error either.
I have tried several pieces of code from Stack Overflow but neither of them worked.
I got the solution,
It was a silly mistakes by me.
the property "store" which is not declare as strong.
as i changed it worked.
And Above code is working properly.
I would like to have the actual event, which is synchronised on my calendar app.
The actual event is the event which is happening now.
I would like, at first, to make an app which tells me how much time remains before the end of my event.
The event is my calendar synchronized to my iphone.
In my Main.StoryBoard, I declared a Label:
#property (strong, nonatomic) IBOutlet UILabel *currentEvent;
I declared a EKEventStore:
EKEventStore *store = [[EKEventStore alloc] init];
From now, I know how to create an event, with start date, end date.. but I would like to retrieve the information from my current event, to be able to do: endDate - timeActual;
Next, in my Label, it will be written : 57 minutes before the end of the event.
NSLog(#"%i minutes before the end of the event.", remainTime );
I don't know if I'm clear, tell me if you don't understand what I'm asking?
Thank you for your help! :)
[Update]
I know how to have the identier of my calendar :
EKEventStore *store = [[EKEventStore alloc] init];
store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted)
NSLog(#"Access to store not granted");
}];
NSArray *calendars = [store calendarsForEntityType:EKEntityTypeEvent];
for (EKCalendar *calendar in calendars)
{
NSLog(#"Calendar = %#", calendar.description);
self.currentEvent.text = [NSString stringWithFormat:#"%#", calendar.calendarIdentifier];
}
EKCalendar *myCalendar = calendars[0];
NSLog(#"My Calendar = %#", myCalendar);
EKEvent *actualEvent = [EKEvent eventWithEventStore:store];
I know how to set event on my calendar, but no have events which are in my calendar!
Have you got any ideas ?
I am trying to delete an event from the Calendar on user request. This is what I've come up with:
// Deleting Event
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = appDelegate.title1;
event.startDate = appDelegate.recAddDate;
event.endDate = appDelegate.currentDateName;
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
[eventStore removeEvent:event span:EKSpanThisEvent error:&err];
Below is the function I'm calling to remove the event from the event array. Items array is used to fetch events from iPhone calendar
- (BOOL)removeEvent:(EKEvent *)event span:(EKSpan)span error:(NSError **)error{
VoiceRecorderAppDelegate *appDelegate = (VoiceRecorderAppDelegate *)[[UIApplication sharedApplication] delegate];
[items removeObjectAtIndex:appDelegate.objectindexpath];
}
Firstly, save the eventId for the event while adding/saving events to the calendar.
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
NSString* str = [[NSString alloc] initWithFormat:#"%#", event.eventIdentifier];
[arrayofEventId addObject:str];
and then identify the event you want to remove ande then remove that event.
EKEventStore* store = [[EKEventStore alloc] init];
EKEvent* eventToRemove = [store eventWithIdentifier:[arrayofEventId objectAtIndex:i]];
if (eventToRemove != nil) {
NSError* error = nil;
[store removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
}
Also don't forget to remove that event from arrayofEventId as well.
You can achieve this in the following ways:
By creating an NSpredicate using the date range withing which you
want to delete events, 86400 being the duration of a day in events, in
this piece of code I am deleting month old events. I am using a
dispatch queue, as the no. of events fetched may be large, and to keep the UI free.
First Create the event store and check access(access check required only iOS6 onwards):
- (void)addEventsToCalendar {
EKEventStore *eventStore = [[EKEventStore alloc] init];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
//implementation for devices running OS version iOS 6.0 onwards.
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted) {
[self removeEventsFromStore:eventStore];
} else {
//perform for No Access using Error
}];
} else {
//implementation for devices running OS version lower than iOS 6.0.
[self removeEventsFromStore:eventStore];
}
}
Then remove events from the store:
- (void)removeEventsFromStore:(EKEventStore*)eventStore {
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-30 * 86400];
NSDate *endDate = [NSDate date];
dispatch_queue_t queue = dispatch_queue_create("com.arc.calendar", NULL);
dispatch_async(queue, ^{
NSArray *calendarArray = [NSArray arrayWithObject:[PWCCalendar getCalendarForEventStore:eventStore]];
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:startDate endDate:[NSDate dateWithTimeInterval:ONE_DAY_DURATION sinceDate:endDate] calendars:calendarArray];
NSArray *eventArray = [eventStore eventsMatchingPredicate:predicate];
for (EKEvent *event in eventArray) {
[eventStore removeEvent:event span:EKSpanThisEvent commit:YES error:NULL];
}
dispatch_async(dispatch_get_main_queue(), ^{
//Get the main Queue and perform UPdates
});
});
}
This is the Long way, use it to delete events in bulk. But if you need to delete only One event, then save the events identifier to `NSUserDefaults(after generating the event)
[eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:NULL];
[[NSUserDefaults standardUserDefaults] setObject:[event eventIdentifier] forKey:#"Event ID"];
and then fetch it back while removing using
[eventStore eventWithIdentifier:#"Event ID"];
and then remove it from the store using
[eventStore removeEvent:event span:EKSpanThisEvent commit:YES error:NULL];
For more clarifications on the other methods to fetch events or calendar, pelase refer to EventStore docs: http://developer.apple.com/library/ios/#documentation/EventKit/Reference/EKEventStoreClassRef/Reference/Reference.html#//apple_ref/doc/uid/TP40009567 or to the Calendar and Reminder Programming guide: http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009765