Програмно додайте користувальницьку подію в Календар 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.