Програмно додайте користувальницьку подію в Календар iPhone


Відповіді:


166

На основі документації Apple , це дещо змінилося, ніж у iOS 6.0.

1) Вам слід запитати доступ до календаря користувача через "requestAccessToEntityType: завершення:" та виконати обробку подій всередині блоку.

2) Вам потрібно здійснити свою подію зараз або передати параметр "здійснити" на ваш дзвінок збереження / видалення

Все інше залишається таким же ...

Додайте рамку 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];
        }
    }];

Це додає події до вашого календаря за замовчуванням, якщо у вас є кілька календарів, ви дізнаєтеся, який це

Швидка версія

Вам потрібно імпортувати рамку 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
        }
    }
}

6
не працює для мене, все йде без помилок, але в календарі немає події
— Борис Гафуров

Все зберігається в об'єкті ekevent, але не зберігається всередині календаря hlp me

1
@William T: Чи можу я представити екран "Подія" програми "Календар" (за допомогою схеми URL) та передати інформацію про подію, щоб на екрані "Додати подію" з'явилися попередньо заповнені дані. Користувачеві просто потрібно натиснути кнопку Додати подію. У вашому прикладі подія додається без будь-яких вказівок для користувача.
— Відповідь

1
якщо все, здається, не працює, але календаря не з’являється, перевірте, чи не є проблемою локальних календарів Cloud VS. Якщо у вас суміш хмарних та локальних календарів, хмарні календарі можуть змусити локальні календарі сховатися.
— zonabi

2
@ReddyBasha, коли ви додаєте подію, вам потрібно зберегти подію ідентифікатора eventId та зберегти його для подальшого використання. Ви повинні використовувати цей ідентифікатор події, коли ви збираєтесь його видалити.
— Вільям Т.

154

Це можна зробити, використовуючи рамку Event Kit в ОС 4.0.

Клацніть правою кнопкою миші на групу 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

18
Дякуємо, що опублікували це. Лише нагадування для всіх, хто читає це: подбайте про стеження за витоком пам’яті. У цьому зразку коду є пара. Крім того, найкращі практики означають, що ви перевіряєте значення 'err' після saveEvent: span: error та обробляєте речі відповідно.
— Девід Карні

Чи знаєте ви, як додати подію рецидиву? як подія на кожен понеділок?
— Джей Ваххані

5
Додайте подію повторення програмно: перевірте це на developer.apple.com/library/ios/#documentation/EventKit/… . Інший варіант - використовувати контролери подання за замовчуванням, що поставляються за рамками за замовчуванням, для додавання / редагування подій (наприклад, додаток Calendar At-A-Glance bit.ly/cJq4Bh ). Про цей параметр див. Developer.apple.com/library/ios/#documentation/EventKitUI/…
— DenTheMan

Щоб додати рамки в XCode 4, дивіться це запитання ТА
— Nate

1
4,0? не буду летіти в 6 див. вище відповідь
— Борис Гафуров

13

Так, для цього все ще немає API (2.1). Але здавалося, що на WWDC багато людей вже зацікавились функціоналом (в тому числі і я), і рекомендація полягала в тому, щоб зайти на веб-сайт нижче та створити для цього запит на функції. Якщо інтересу достатньо, вони можуть перенести ICal.framework на загальнодоступний SDK.

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


5
відповідь застаріла, подумайте про видалення цього
— Джаспер

12

Доступ до календаря додається в iPhone OS 4.0 :


Додатки до календаря тепер можуть створювати та редагувати події безпосередньо в додатку «Календар» за допомогою комплекту подій.
Створіть періодичні події, встановіть час початку та закінчення та призначте їх будь-якому календару на пристрої.


1
ваше посилання зараз розірвано
— Аділ Соомро

5

Ви можете додати подію за допомогою API подій, як, наприклад, Трістан, а також додати Календар Google, який відображається в календарі iOS.

за допомогою клієнта API 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];
                }
              }];
}

5

Реалізація 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 !")
            }
        }
    })
}

Чи можете ви мені допомогти з календарем google щодо тієї самої відповіді @Dashrath
— Діліп Тіварі

4

Оновлення для швидкого 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.
    }


}

також не забудьте додати дозвіл на використання календаря зображення для приватних налаштувань


2

Робочий код у 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)

            }
        }


       })
    }

}

Тепер ми отримаємо екран події, і тут ви також можете змінити свої налаштування:

введіть тут опис зображення

Тепер додайте метод делегата для обробки Скасувати та додайте дії кнопки події на екрані події:

    extension viewController: EKEventEditViewDelegate {

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

    }
}

Примітка. Не забудьте додати ключ NSCalendarsUsageDescription в інформаційний список.


1

Не забудьте встановити 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
}];

1
А також пам’ятайте, що дата закінчення повинна бути рівною або більшою, ніж дата початку. В іншому випадку ви отримаєте ще одну помилку.
— похмурий

0

Ідея Google приємна, але має проблеми.

Я можу успішно відкрити екран подій календаря Google, але лише у головній версії робочого столу, і він не відображається належним чином на iPhone Safari. Мобільний календар Google, який відображається належним чином на Safari, схоже, не працює з API для додавання подій.

На даний момент я не бачу хорошого виходу з цього.


0

Просте .... використовуйте бібліотеку tapku .... ви можете передати Google це слово і використовувати його ... його відкритий код ... насолоджуйтесь ..... немає потреби в помилках з цими кодами ....



Чи може календар бібліотеки Tapku синхронізуватися з подіями календаря
— coder1010

Все, що я знаю, - це те, що бібліотека Tapku - це елемент керування компонентами календаря, який має опцію "Джерело даних". Тож його логіка до ур, щоб писати, звідки ви отримуєте це джерело ... Happy Coding :)
— Rajesh_Bangalore
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.