Есть ли способ добавить событие iCal в календарь iPhone из пользовательского приложения?
Программно добавить пользовательское событие в iPhone Календарь
Ответ 1
Основываясь на документации Apple, это немного изменилось с iOS 6.0.
1) Вам необходимо запросить доступ к пользовательскому календарю через "requestAccessToEntityType: завершение:" и выполнить обработку событий внутри блока.
2) Вам нужно зафиксировать ваше событие сейчас или передать параметр "commit" в ваш вызов сохранения/удаления
Все остальное остается прежним...
 Добавьте каркас EventKit и #import <EventKit/EventKit.h> в свой код.
В моем примере у меня есть свойство экземпляра NSString * saveEventId.
Чтобы добавить событие:
    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
    }];
Удалить событие:
    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];
        }
    }];
Это добавляет события в ваш календарь по умолчанию, если у вас есть несколько календарей, то вы узнаете, какой из них является
Swift версия
Вам необходимо импортировать фреймворк EventKit
import EventKit
Добавить событие
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
    }
}
Удалить событие
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
Вы можете сделать это, используя фреймворк Event Kit в ОС 4.0.
Щелкните правой кнопкой мыши на группе FrameWorks в Навигаторе групп и файлов в левой части окна. Выберите "Добавить", затем "Существующий FrameWorks", затем "EventKit.Framework".
Затем вы сможете добавлять события с таким кодом:
#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
Да, для этого нет API (2.1). Но, похоже, на WWDC многие люди уже интересовались функциональностью (включая меня), и рекомендация заключалась в том, чтобы перейти на сайт ниже и создать запрос функции для этого. Если будет достаточно интереса, они могут в конечном итоге переместить ICal.framework в общедоступный SDK.
Ответ 4
Добавлен доступ к календарю в iPhone OS 4.0:
Доступ к календарю
Теперь приложения могут создавать и редактировать события непосредственно в Приложение "Календарь" с комплектом событий.
Создавать повторяющиеся события, настраивать начало и конец раза и назначить их на любой календарь на устройстве.
Ответ 5
Вы можете добавить событие, используя описанный API событий, например Tristan, и вы также можете добавить событие Календаря Google, которое отображается в календаре iOS.
используя Google API Objective-C
  - (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
Реализация Swift 4.0:
 использовать импорт в верхней части страницы при import EventKit
затем
@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 !")
            }
        }
    })
}
Ответ 7
Обновление для быстрого 4 для ответа Дашрат
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.
    }
}
также не забудьте добавить разрешение на использование календаря

Ответ 8
Простой.... используйте библиотеку tapku.... вы можете использовать это слово и использовать его... его с открытым исходным кодом... наслаждайтесь..... не нужно прослушивать эти коды....
Ответ 9
Не забудьте установить endDate для созданного события, это обязательно.
В противном случае с этой ошибкой произойдет ошибка (почти бесшумно):
"Error Domain=EKErrorDomain Code=3 "No end date has been set." UserInfo={NSLocalizedDescription=No end date has been set.}"
Полный рабочий код для меня:
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
Рабочий код в 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)
            }
        }
       })
    }
}
Теперь мы получим экран событий, и здесь вы также можете изменить свои настройки:
Теперь добавьте метод делегата для обработки Cancel и добавьте действие кнопки события экрана события:
    extension viewController: EKEventEditViewDelegate {
    func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        controller.dismiss(animated: true, completion: nil)
    }
}
Примечание. Не забудьте добавить ключ NSCalendarsUsageDescription в информационный список.
Ответ 11
Идея Google хорошая, но есть проблемы.
Я могу успешно открыть экран событий календаря Google, но только на главной версии рабочего стола, и он не отображается правильно на iPhone Safari. Календарь Google для мобильных устройств, который корректно отображает Safari, похоже, не работает с API для добавления событий.
На данный момент я не вижу хорошего выхода из этого.

