Programmatically add custom event in the iPhone Ca

2019-01-01 01:23发布

问题:

Is there any way to add iCal event to the iPhone Calendar from the custom App?

回答1:

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
        }
    }
}


回答2:

You can do this using the Event Kit framework in OS 4.0.

Right click on the FrameWorks group in the Groups and Files Navigator on the left of the window. Select \'Add\' then \'Existing FrameWorks\' then \'EventKit.Framework\'.

Then you should be able to add events with code like this:

#import \"EventTestViewController.h\"
#import <EventKit/EventKit.h>

@implementation EventTestViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    EKEventStore *eventStore = [[EKEventStore alloc] init];

    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];       
}

@end


回答3:

Yes there still is no API for this (2.1). But it seemed like at WWDC a lot of people were already interested in the functionality (including myself) and the recommendation was to go to the below site and create a feature request for this. If there is enough of an interest, they might end up moving the ICal.framework to the public SDK.

https://developer.apple.com/bugreporter/



回答4:

Calendar access is being added in iPhone OS 4.0:

Calendar Access
Apps can now create and edit events directly in the Calendar app with Event Kit.
Create recurring events, set up start and end times and assign them to any calendar on the device.



回答5:

You can add the event using the Event API like Tristan outlined and you can also add a Google Calendar event which shows up in the iOS calendar.

using Google\'s API Objective-C Client

  - (void)addAnEvent {
  // Make a new event, and show it to the user to edit
  GTLCalendarEvent *newEvent = [GTLCalendarEvent object];
  newEvent.summary = @\"Sample Added Event\";
  newEvent.descriptionProperty = @\"Description of sample added event\";

  // We\'ll set the start time to now, and the end time to an hour from now,
  // with a reminder 10 minutes before
  NSDate *anHourFromNow = [NSDate dateWithTimeIntervalSinceNow:60*60];
  GTLDateTime *startDateTime = [GTLDateTime dateTimeWithDate:[NSDate date]
                                                    timeZone:[NSTimeZone systemTimeZone]];
  GTLDateTime *endDateTime = [GTLDateTime dateTimeWithDate:anHourFromNow
                                                  timeZone:[NSTimeZone systemTimeZone]];

  newEvent.start = [GTLCalendarEventDateTime object];
  newEvent.start.dateTime = startDateTime;

  newEvent.end = [GTLCalendarEventDateTime object];
  newEvent.end.dateTime = endDateTime;

  GTLCalendarEventReminder *reminder = [GTLCalendarEventReminder object];
  reminder.minutes = [NSNumber numberWithInteger:10];
  reminder.method = @\"email\";

  newEvent.reminders = [GTLCalendarEventReminders object];
  newEvent.reminders.overrides = [NSArray arrayWithObject:reminder];
  newEvent.reminders.useDefault = [NSNumber numberWithBool:NO];

  // Display the event edit dialog
  EditEventWindowController *controller = [[[EditEventWindowController alloc] init] autorelease];
  [controller runModalForWindow:[self window]
                          event:newEvent
              completionHandler:^(NSInteger returnCode, GTLCalendarEvent *event) {
                // Callback
                if (returnCode == NSOKButton) {
                  [self addEvent:event];
                }
              }];
}


回答6:

Update for swift 4 for Dashrath answer

import UIKit
import EventKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let eventStore = EKEventStore()

        eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in

            if (granted) && (error == nil) {


                let event = EKEvent(eventStore: eventStore)

                event.title = \"My Event\"
                event.startDate = Date(timeIntervalSinceNow: TimeInterval())
                event.endDate = Date(timeIntervalSinceNow: TimeInterval())
                event.notes = \"Yeah!!!\"
                event.calendar = eventStore.defaultCalendarForNewEvents

                var event_id = \"\"
                do{
                    try eventStore.save(event, span: .thisEvent)
                    event_id = event.eventIdentifier
                }
                catch let error as NSError {
                    print(\"json error: \\(error.localizedDescription)\")
                }

                if(event_id != \"\"){
                    print(\"event added !\")
                }
            }
        })
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

also don\'t forget to add permission for calendar usage \"image



回答7:

Swift 4.0 implementation :

use import in top of page by import EventKit

then

@IBAction func addtoCalendarClicked(sender: AnyObject) {

    let eventStore = EKEventStore()

    eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in

        if (granted) && (error == nil) {
            print(\"granted \\(granted)\")
            print(\"error \\(error)\")

            let event = EKEvent(eventStore: eventStore)

            event.title = \"Event Title\"
            event.startDate = Date()
            event.endDate = Date()
            event.notes = \"Event Details Here\"
            event.calendar = eventStore.defaultCalendarForNewEvents

            var event_id = \"\"
            do {
                try eventStore.save(event, span: .thisEvent)
                event_id = event.eventIdentifier
            }
            catch let error as NSError {
                print(\"json error: \\(error.localizedDescription)\")
            }

            if(event_id != \"\"){
                print(\"event added !\")
            }
        }
    })
}


回答8:

Simple.... use tapku library.... you can google that word and use it... its open source... enjoy..... no need of bugging with those codes....



回答9:

Remember to set the endDate to the created event, it is mandatory.

Otherwise it will fail (almost silently) with this error:

\"Error Domain=EKErrorDomain Code=3 \"No end date has been set.\" UserInfo={NSLocalizedDescription=No end date has been set.}\"

The complete working code for me is:

EKEventStore *store = [EKEventStore new];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
    if (!granted) { return; }
    EKEvent *calendarEvent = [EKEvent eventWithEventStore:store];
    calendarEvent.title = [NSString stringWithFormat:@\"CEmprendedor: %@\", _event.name];
    calendarEvent.startDate = _event.date;
    // 5 hours of duration, we must add the duration of the event to the API
    NSDate *endDate = [_event.date dateByAddingTimeInterval:60*60*5];
    calendarEvent.endDate = endDate;
    calendarEvent.calendar = [store defaultCalendarForNewEvents];
    NSError *err = nil;
    [store saveEvent:calendarEvent span:EKSpanThisEvent commit:YES error:&err];
    self.savedEventId = calendarEvent.eventIdentifier;  //saving the calendar event id to possibly deleted them
}];


回答10:

The Google idea is a nice one, but has problems.

I can successfully open a Google calendar event screen - but only on the main desktop version, and it doesn\'t display properly on iPhone Safari. The Google mobile calendar, which does display properly on Safari, doesn\'t seem to work with the API to add events.

For the moment, I can\'t see a good way out of this one.



回答11:

Working code in Swift-4.2

import UIKit
import EventKit
import EventKitUI

class yourViewController: UIViewController{

    let eventStore = EKEventStore()

    func addEventToCalendar() {

    eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in
        DispatchQueue.main.async {
            if (granted) && (error == nil) {
                let event = EKEvent(eventStore: self.eventStore)
                event.title = self.headerDescription
                event.startDate = self.parse(self.requestDetails.value(forKey: \"session_time\") as? String ?? \"\")
                event.endDate = self.parse(self.requestDetails.value(forKey: \"session_end_time\") as? String ?? \"\")
                let eventController = EKEventEditViewController()
                eventController.event = event
                eventController.eventStore = self.eventStore
                eventController.editViewDelegate = self
                self.present(eventController, animated: true, completion: nil)

            }
        }


       })
    }

}

Now we will get the event screen and here you can also modify your settings:

\"enter

Now add delegate method to handle Cancel and add the event button action of event screen:

    extension viewController: EKEventEditViewDelegate {

    func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        controller.dismiss(animated: true, completion: nil)

    }
}

Note: Don\'t forget to add NSCalendarsUsageDescription key into info plist.