iOS - allow user to add Calendar Event with some fields filled in - ios

Is it possible in Objective-C in xCode to open up the native iPhone "Add Event" calendar prompt with a couple of fields already filled in? For instance name, address and start/end date? If so, how?
This would allow the user to still change a couple of parameters: when does he want to be alerted, etc.
I have looked around but all I have found are methods to automatically add the event without the confirmation of the user.

Step 1
First take Calendar Permission
dispatch_async(dispatch_get_main_queue(), ^{
[self.eventManager.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if(granted==NO)
{
BOOL permission=[[NSUserDefaults standardUserDefaults] boolForKey:#"CalendarPermissionAlert"];
if(permission==NO) {
kAppDelegateObject.eventManager.eventsAccessGranted=NO;
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:#"CalendarPermissionAlert"];
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Calendar Access is OFF"
message:kCalenderResetMessage
delegate:self
cancelButtonTitle:#"CANCEL"
otherButtonTitles:#"SETTING",nil];
[alert show];
alert.tag=101;
return ;
}
}
Step 2
//Add Event
-(void)addEventWithMessage:(NSString*)eventMessage withEventDate:(NSDate *)eventDate
EKEventStore *eventStore;
eventStore = [[EKEventStore alloc] init];
// Create a new event object.
EKEvent *event = [EKEvent eventWithEventStore: eventStore];
// Set the event title.
event.title = eventMessage;
// Set its calendar.
NSString *identifier=[[NSUserDefaults standardUserDefaults]objectForKey:#"calenderId"]; //your application id
// NSLog(#"cal identifier: %#",identifier);
event.calendar = [eventStore calendarWithIdentifier:identifier];
//set Alarm
NSTimeInterval secondsInOneHours = 1 * 60 * 60;
NSDate *dateOneHoursAhead = [eventDate dateByAddingTimeInterval:secondsInOneHours];
// Set the start and end dates to the event.
event.startDate = eventDate;
event.endDate = dateOneHoursAhead; //
NSError *error;
if ([eventStore saveEvent:event span:EKSpanFutureEvents commit:YES error:&error]) {
// NSLog(#"Event Added");
}
else{
// An error occurred, so log the error description.
// NSLog(#"%#", [error localizedDescription]);
}

Here is how I handled it...with EKEventEditViewController!
First:
#import EventKitUI;
At the very top of your .m file.
Then set the EKEventEditViewDelegate
Then, when you want to add the event, use the following method:
- (IBAction)addToCalendar:(id)sender {
EKEventStore *eventStore = [[EKEventStore alloc] init];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
// the selector is available, so we must be on iOS 6 or newer
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error)
{
NSLog(#"%#", error);
// display error message here
}
else if (!granted)
{
NSLog(#"%# acce sdenied", error);
// display access denied error message here
}
else
{
EKEvent *event = [EKEvent eventWithEventStore: eventStore];
event.title = nom;
event.location = adresse;
// Set the start and end dates to the event.
event.startDate = startDate;
event.endDate = endDate; //
EKEventEditViewController *eventViewController = [[EKEventEditViewController alloc] init];
eventViewController.event = event;
eventViewController.eventStore=eventStore;
eventViewController.editViewDelegate = self;
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
[eventViewController setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:eventViewController animated:YES completion:NULL];
}
});
}];
}
}
Finally, add this delegate method to handle the completion action:
-(void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action {
NSError *error;
switch (action) {
case EKEventEditViewActionCancelled:
// User tapped "cancel"
NSLog(#"Canceled");
break;
case EKEventEditViewActionSaved:
NSLog(#"Saved");
[controller.eventStore saveEvent:controller.event span: EKSpanFutureEvents error:&error];
[calendarBouton setTitle:#"Ajouté!" forState:UIControlStateDisabled];
calendarBouton.enabled = NO;
break;
case EKEventEditViewActionDeleted:
// User tapped "delete"
NSLog(#"Deleted");
break;
default:
NSLog(#"Default");
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}

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

Deleting event from iCal not working when iCal is not in background

Am trying to delete the event from iCal as soon as I get the notification. The event is getting deleted only if iCal is in background. If the same notification is sent after closing iCal, the event is not deleted. Am trying to access iCal using this method in MyCalendar.m
+ (void)requestAccess:(void (^)(BOOL granted, NSError *error))callback {
if (eventStore == nil) {
eventStore = [[EKEventStore alloc] init];
}
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:callback];
}
And am trying to delete the event using following method in Appdelegate.m
[MyCalendar requestAccess:^(BOOL granted, NSError *error) {
if (granted) {
if ([[self.launchOptions objectForKey:#"type"] isEqualToString:#"remainder"] || [[self.launchOptions objectForKey:#"type"] isEqualToString:#"cancelAppointment"]) {
if ([[self.launchOptions objectForKey:#"type"]
isEqualToString:#"cancelAppointment"]) {
if (![MyCalendar removeEventWithEventIdentifier:
[self.launchOptions objectForKey:#"eventId"]]) {
}
}
}
}
}];
Am deleting the event from iCal using following method in MyCalendar.m
+ (BOOL)removeEventWithEventIdentifier:(NSString *)identifier {
EKEvent *event2 = [eventStore eventWithIdentifier:identifier];
BOOL result = NO;
if (event2 != nil) {
NSError *error = nil;
result = [eventStore removeEvent:event2 span:EKSpanThisEvent error:&error];
}
return result;
}
Thanks in advance!
You have to initialize the event store object before using.
+ (BOOL)removeEventWithEventIdentifier:(NSString *)identifier {
EKEventStore* eventStore = [[EKEventStore alloc] init];
EKEvent *event2 = [eventStore eventWithIdentifier:identifier];
BOOL result = NO;
if (event2 != nil) {
NSError *error = nil;
result = [eventStore removeEvent:event2 span:EKSpanThisEvent error:&error];
}
return result;
}

How do I add an Event Title (from a UI Text View) to a Calendar Event created by my APP?

I've developed an App and my App needs to create an event at device's calendar. I've been trough EventKitProgGuide and studied the SimpleEKDemo.
By simplifying the code from SimpleEKDemo I generated the code shown below that opens an 'calendar's event screen' straight from my app and generates the event properly. I'm OK with that.
Now I need to use the text content of an UITextView as the Event Title!
Could somebody help my with that code?
Thanks,
Marcos
Here's my code:
#.h
#import <EventKitUI/EventKitUI.h>
#import <EventKit/EventKit.h>
#property (nonatomic, strong) EKEventStore *eventStore;
#property (nonatomic, strong) EKEvent *event;
#property (nonatomic, strong) EKCalendar *defaultCalendar;
#property (nonatomic, strong)
IBOutlet UITextView *textView1;
- (IBAction)agendar:(UIButton *)sender;
#.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.eventStore = [[EKEventStore alloc]init];
self.textView1.text = #"hello world!";
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self checkEventStoreAccessForCalendar];
}
- (IBAction)agendar:(UIButton *)sender {
EKEventEditViewController *addController = [[EKEventEditViewController alloc] init];
addController.eventStore = self.eventStore;
addController.editViewDelegate = self;
[self presentViewController:addController animated:YES completion:nil];
self.event = [EKEvent eventWithEventStore:self.eventStore];
// Jeff's suggested code:
self.event.title = self.textView1.text;
// Jeff's SaveEvent Sugestion
NSError *err;
[self.eventStore saveEvent:self.event span:EKSpanThisEvent error:&err];
}
-(void)checkEventStoreAccessForCalendar
{
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status)
{
case EKAuthorizationStatusAuthorized: [self accessGrantedForCalendar];
break;
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alerta de Privacidade" message:#"Permissão de acesso ao calendário não concedida."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
}
}
-(void)requestCalendarAccess
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
Tela8ViewController * weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf accessGrantedForCalendar];
});
}
}];
}
-(void)accessGrantedForCalendar
{
self.defaultCalendar = self.eventStore.defaultCalendarForNewEvents;
}
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action
{
[self dismissViewControllerAnimated:YES completion:^
{
if (action != EKEventEditViewActionCanceled)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
There are two ways to create an event with EventKit. Your sample code currently has a mix of both, so you should pick just one!
A: Create an event with certain fields pre-set (in your case, the title), and allow the user to review and save it (or choose to cancel and discard it) with EKEventEditViewController. In this case, your code doesn't need to commit the event - just watch for the delegate response to confirm that it happened.
- (void)createEventWithTitle:(NSString *)title
{
EKEvent *newEvent = [EKEvent eventWithEventStore:self.eventStore];
newEvent.title = title;
EKEventEditViewController *controller = [[EKEventEditViewController alloc] init];
controller.eventStore = self.eventStore;
controller.event = newEvent;
controller.editViewDelegate = self;
[self presentViewController:controller animated:YES completion:nil];
}
// EKEventEditViewController delegate method
- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action
{
if (action == EKEventEditViewActionSaved) {
// event has been committed
}
// alternatives are EKEventEditViewActionCanceled, EKEventEditViewActionDeleted
[self dismissViewControllerAnimated:YES completion:Nil];
}
B. You can create an event and commit it entirely in your code, if you don't need user involvement. In this case you can use EKEventStore saveEvent: span: error: instead of relying on EKEventEditViewController.
Have you tried something like
self.event.title = self.textView1.text;
?

App crashed after enable or disable calendar from settings

I have implemented EKEventStore, EKCalendar in my app to make the EKEvent within the app. It is working fine until or unless I didn't change permissions from the settings. But when I changed the requested access (on/off or off/on) from the settings, the app get crashed. I am unable to find the error. If someone has idea then please help me out. Here is the code I have implemented :
self.eventStore = [[EKEventStore alloc] init];
[self checkEventStoreAccessForCalendar];
-(void)checkEventStoreAccessForCalendar
{
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status)
{
case EKAuthorizationStatusAuthorized: [self accessGrantedForCalendar];
break;
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Privacy Warning" message:#"Permission was not granted for Calendar"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
} }
-(void)requestCalendarAccess
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,
NSError *error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
-(void)accessGrantedForCalendar
{
self.defaultCalendar = self.eventStore.defaultCalendarForNewEvents;
EKEvent *addEvent = [EKEvent eventWithEventStore:self.eventStore];
addEvent.title = [NSString stringWithFormat:#"%#", textcontainer.text];
}
#pragma mark EKEventEditViewDelegate
-(void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action{
[self dismissViewControllerAnimated:YES completion:^
{
if (action != EKEventEditViewActionCanceled)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
}];
}
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller
{
return self.defaultCalendar;
}
When your app goes to the background it should save all its states and should be prepared to get killed. When someone switches off access to calendar, the easiest way for the system to deals with that is to kill your app, and that is why its happening. If you switch back to your app by clicking 'Back to Your-App' on top, you can notice that your app will be launching from the beginning, not from where you left. Try not using the breakpoint and you will notice the change.
So its not a crash actually.

Can't create event in default iOS 7 calendar

#import <EventKit/EventKit.h>
I can't create event in default iOS calendar.
EKEventStore *eventStore = [[EKEventStore alloc] init];
for (EKSource *source in eventStore.sources)
{
if (source.sourceType == EKSourceTypeCalDAV || source.sourceType == EKSourceTypeLocal)
{
NSLog(#"I found it");
break;
}
}
Beginning from here it couldn't return any sources. When I build and run app there are no any requests to give its access to default calendar.
All in all I get an empty array:
[eventStore.sources count]
Even when I trying to add event without creating new calendar (using
[eventStore defaultCalendarForNewEvents]
I guess there is problem in accessing EKEventStore, to check permission try following,
EKEventStore *eventStore = [[EKEventStore alloc] init];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]){
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
NSLog(#"GRANTED: %c", granted);
for (EKSource *source in eventStore.sources)
{
if (source.sourceType == EKSourceTypeCalDAV || source.sourceType == EKSourceTypeLocal)
{
NSLog(#"I found it");
break;
}
}
}];
}
Hope it Helps you..
I have found problem:
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
// TODO
}];
I must request permission manually, thought permission set without it, I think it had fixed in iOS 7.0.2 build.

Resources