Czy istnieje sposób, aby dodać wydarzenie iCal do kalendarza iPhone'a z poziomu niestandardowej aplikacji?
183
Na podstawie dokumentacji Apple zmieniło się to nieco od wersji iOS 6.0.
1) Należy zażądać dostępu do kalendarza użytkownika poprzez „requestAccessToEntityType: Complete:” i wykonać obsługę zdarzenia wewnątrz bloku.
2) Musisz zatwierdzić wydarzenie teraz lub przekazać parametr „commit” do swojego wywołania save / remove
Wszystko inne pozostaje takie samo ...
Dodaj platformę EventKit i #import <EventKit/EventKit.h>
do swojego kodu.
W moim przykładzie mam właściwość instancji NSString * saveEventId.
Aby dodać wydarzenie:
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
}];
Usuń wydarzenie:
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];
}
}];
Spowoduje to dodanie wydarzeń do domyślnego kalendarza, jeśli masz wiele kalendarzy, dowiesz się, który to jest
Szybka wersja
Musisz zaimportować strukturę EventKit
import EventKit
Dodaj wydarzenie
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
}
}
Usuń wydarzenie
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
}
}
}
Możesz to zrobić za pomocą środowiska Event Kit w systemie OS 4.0.
Kliknij prawym przyciskiem myszy grupę FrameWorks w nawigatorze grup i plików po lewej stronie okna. Wybierz „Dodaj”, a następnie „Istniejące FrameWorks”, a następnie „EventKit.Framework”.
Wtedy powinieneś móc dodawać wydarzenia z takim kodem:
#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
źródło
Tak, nadal nie ma do tego API (2.1). Ale wydawało się, że w WWDC wiele osób było już zainteresowanych funkcjonalnością (w tym ja) i zalecono, aby przejść do poniższej witryny i utworzyć prośbę o funkcję w tym celu. Jeśli zainteresowanie jest wystarczające, mogą w końcu przenieść ICal.framework do publicznego SDK.
https://developer.apple.com/bugreporter/
źródło
Dostęp do kalendarza jest dodawany w iPhone OS 4.0 :
źródło
Wdrożenie Swift 4.0:
użyj importu na górze strony według
import EventKit
następnie
@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 !") } } }) }
źródło
Możesz dodać wydarzenie za pomocą interfejsu Event API, takiego jak opisany przez Tristana, a także możesz dodać wydarzenie z Kalendarza Google, które pojawi się w kalendarzu iOS.
za pomocą klienta API Objective-C firmy Google
- (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]; } }]; }
źródło
Aktualizacja dla Swift 4 dla odpowiedzi Dashrath
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. } }
nie zapomnij również dodać pozwolenia na używanie kalendarza
źródło
Kod roboczy w 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) } } }) } }
Teraz otrzymamy ekran wydarzenia i tutaj możesz również zmodyfikować swoje ustawienia:
Teraz dodaj metodę delegata do obsługi Cancel i dodaj akcję przycisku zdarzenia na ekranie zdarzenia:
extension viewController: EKEventEditViewDelegate { func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) { controller.dismiss(animated: true, completion: nil) } }
Uwaga: nie zapomnij dodać klucza NSCalendarsUsageDescription do pliku info plist.
źródło
Pamiętaj, aby ustawić endDate w utworzonym zdarzeniu, jest to obowiązkowe.
W przeciwnym razie zakończy się niepowodzeniem (prawie bezgłośnie) z tym błędem:
"Error Domain=EKErrorDomain Code=3 "No end date has been set." UserInfo={NSLocalizedDescription=No end date has been set.}"
Kompletny działający kod dla mnie to:
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 }];
źródło
Pomysł na Google jest fajny, ale ma problemy.
Mogę z powodzeniem otworzyć ekran wydarzeń kalendarza Google - ale tylko w głównej wersji komputerowej i nie wyświetla się poprawnie na iPhonie Safari. Mobilny kalendarz Google, który wyświetla się poprawnie w Safari, nie działa z interfejsem API do dodawania wydarzeń.
W tej chwili nie widzę dobrego wyjścia z tego.
źródło
Proste .... użyj biblioteki tapku .... możesz wygooglować to słowo i użyć go ... jego otwarte źródło ... ciesz się ..... nie ma potrzeby bugowania tymi kodami ....
źródło