Programmatically add custom event in the iPhone Calendar
Based on Apple Documentation, this has changed a bit as of iOS 6.0.
1) You should request access to the user's calendar via "requestAccessToEntityType:completion:" and execute the event handling inside of a block.
2) You need to commit your event now or pass the "commit" param to your save/remove call
Everything else stays the same...
Add the EventKit framework and #import <EventKit/EventKit.h>
to your code.
In my example, I have a NSString *savedEventId instance property.
To add an event:
EKEventStore *store = [EKEventStore new];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = @"Event Title";
event.startDate = [NSDate date]; //today
event.endDate = [event.startDate dateByAddingTimeInterval:60*60]; //set 1 hour meeting
event.calendar = [store defaultCalendarForNewEvents];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
self.savedEventId = event.eventIdentifier; //save the event id if you want to access this later
}];
Remove the event:
EKEventStore* store = [EKEventStore new];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent* eventToRemove = [store eventWithIdentifier:self.savedEventId];
if (eventToRemove) {
NSError* error = nil;
[store removeEvent:eventToRemove span:EKSpanThisEvent commit:YES error:&error];
}
}];
This adds events to your default calendar, if you have multiple calendars then you'll have find out which one that is
Swift version
You need to import the EventKit framework
import EventKit
Add event
let store = EKEventStore()
store.requestAccessToEntityType(.Event) {(granted, error) in
if !granted { return }
var event = EKEvent(eventStore: store)
event.title = "Event Title"
event.startDate = NSDate() //today
event.endDate = event.startDate.dateByAddingTimeInterval(60*60) //1 hour long meeting
event.calendar = store.defaultCalendarForNewEvents
do {
try store.saveEvent(event, span: .ThisEvent, commit: true)
self.savedEventId = event.eventIdentifier //save event id to access this particular event later
} catch {
// Display error to user
}
}
Remove event
let store = EKEventStore()
store.requestAccessToEntityType(EKEntityTypeEvent) {(granted, error) in
if !granted { return }
let eventToRemove = store.eventWithIdentifier(self.savedEventId)
if eventToRemove != nil {
do {
try store.removeEvent(eventToRemove, span: .ThisEvent, commit: true)
} catch {
// Display error to user
}
}
}
iPhone Event Kit : programmatically SUBSCRIBE to a new calendar
Why not use this: How to programmatically add calendar subscriptions on iOS?
Summarizing the accepted answer:
NSString *url = @"http://server/filename.ics";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
Edit: Used this in my own app and verified that it works...
Edit by MitchR:
For those generating their own ics feeds on the server, the url must
end in .ics to receive the subscription prompt. The MIME type of the
response must also be text/calendar. My server is a .NET/MVC server so
I added a custom route so I could have the .ics on the end of the
controller action.
How to add an event in the device calendar using swift?
Note: If your app is crashing with This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCalendarsUsageDescription key with a string value explaining to the user how the app uses this data.
, you'll need to add NSCalendarsUsageDescription
to your info.plist. Can follow the example here.
Swift 5.0 Version
import Foundation
import EventKit
let eventStore : EKEventStore = EKEventStore()
// 'EKEntityTypeReminder' or 'EKEntityTypeEvent'
eventStore.requestAccess(to: .event) { (granted, error) in
if (granted) && (error == nil) {
print("granted \(granted)")
print("error \(error)")
let event:EKEvent = EKEvent(eventStore: eventStore)
event.title = "Test Title"
event.startDate = Date()
event.endDate = Date()
event.notes = "This is a note"
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
} catch let error as NSError {
print("failed to save event with error : \(error)")
}
print("Saved Event")
}
else{
print("failed to save event with error : \(error) or access not granted")
}
}
Reference : https://gist.github.com/mchirico/d072c4e38bda61040f91
How to add event in native IOS Calendar
See the Calendar and Reminders Programming Guide. But the basic process is:
Add the
EventKit.Framework
andEventKitUI.Framework
to your project. (See Linking to a Library or Framework.)Import the header:
#import <EventKitUI/EventKitUI.h>
If creating an event, you use :
- (IBAction)didPressCreateEventButton:(id)sender
{
EKEventStore *store = [[EKEventStore alloc] init];
if([store respondsToSelector:@selector(requestAccessToEntityType:completion:)])
{
// iOS 6
[store requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self createEventAndPresentViewController:store];
});
}
}];
} else
{
// iOS 5
[self createEventAndPresentViewController:store];
}
}
- (void)createEventAndPresentViewController:(EKEventStore *)store
{
EKEvent *event = [self findOrCreateEvent:store];
EKEventEditViewController *controller = [[EKEventEditViewController alloc] init];
controller.event = event;
controller.eventStore = store;
controller.editViewDelegate = self;
[self presentViewController:controller animated:YES completion:nil];
}Your view controller should conform to the
EKEventEditViewDelegate
protocol:@interface ViewController () <EKEventEditViewDelegate>
and implement the
didCompleteWithAction
method:- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action
{
[self dismissViewControllerAnimated:YES completion:nil];
}You can obviously create your event any way you want. For example, this is looks for an event in the next week with the appropriate title, and if it doesn't find it, create a new event (hour long event that starts in four hours):
- (EKEvent *)findOrCreateEvent:(EKEventStore *)store
{
NSString *title = @"My event title";
// try to find an event
EKEvent *event = [self findEventWithTitle:title inEventStore:store];
// if found, use it
if (event)
return event;
// if not, let's create new event
event = [EKEvent eventWithEventStore:store];
event.title = title;
event.notes = @"My event notes";
event.location = @"My event location";
event.calendar = [store defaultCalendarForNewEvents];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.hour = 4;
event.startDate = [calendar dateByAddingComponents:components
toDate:[NSDate date]
options:0];
components.hour = 1;
event.endDate = [calendar dateByAddingComponents:components
toDate:event.startDate
options:0];
return event;
}
- (EKEvent *)findEventWithTitle:(NSString *)title inEventStore:(EKEventStore *)store
{
// Get the appropriate calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// Create the start range date components
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
// Create the end range date components
NSDateComponents *oneWeekFromNowComponents = [[NSDateComponents alloc] init];
oneWeekFromNowComponents.day = 7;
NSDate *oneWeekFromNow = [calendar dateByAddingComponents:oneWeekFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo
endDate:oneWeekFromNow
calendars:nil];
// Fetch all events that match the predicate
NSArray *events = [store eventsMatchingPredicate:predicate];
for (EKEvent *event in events)
{
if ([title isEqualToString:event.title])
{
return event;
}
}
return nil;
}
Create event based on dates in a text field
To add an event programmatically, read Apple's Event Kit Programming Guide. Maybe you want to make it easier on yourself by using an EKEventViewController
, but you can do everything in code as well.
To transform an NSString
from the text
property of your text field into an NSDate
you will have to use an NSDateFormatter
. There are good examples in the class documentation.
iOS - Add custom URI of our app to the event stored in calendar programmatically
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.
Related Topics
Presenting Modal in iOS 13 Fullscreen
How to Force Nslocalizedstring to Use a Specific Language
Determine Device (Iphone, Ipod Touch) With Ios
How to Debug 'Unrecognized Selector Sent to Instance' Error
How to Make Http Request in Swift
How to Debug Memory Leaks When Leaks Instrument Does Not Show Them
How to Set Cornerradius For Only Top-Left and Top-Right Corner of a Uiview
Nsurlsession/Nsurlconnection Http Load Failed on iOS 9
Attempt to Present Uiviewcontroller on Uiviewcontroller Whose View Is Not in the Window Hierarchy
Detecting Which Uibutton Was Pressed in a Uitableview
Dateformatter Doesn't Return Date For "Hh:Mm:Ss"
How to Use Nsurlconnection to Connect With Ssl For an Untrusted Cert
Convert Between Uiimage and Base64 String
How to Get a Background Location Update Every N Minutes in My iOS Application
Firebase - Deleting and Reinstalling App Does Not Un-Authenticate a User