Fügen Sie programmgesteuert ein benutzerdefiniertes Ereignis in den iPhone-Kalender ein

181

Gibt es eine Möglichkeit, iCal-Ereignisse über die benutzerdefinierte App zum iPhone-Kalender hinzuzufügen?

Vadim
quelle

Antworten:

166

Basierend auf der Apple-Dokumentation hat sich dies ab iOS 6.0 etwas geändert.

1) Sie sollten über "requestAccessToEntityType: finish:" den Zugriff auf den Kalender des Benutzers anfordern und die Ereignisbehandlung innerhalb eines Blocks ausführen.

2) Sie müssen Ihr Ereignis jetzt festschreiben oder den Parameter "Festschreiben" an Ihren Aufruf zum Speichern / Entfernen übergeben

Alles andere bleibt gleich ...

Fügen Sie das EventKit-Framework und #import <EventKit/EventKit.h>Ihren Code hinzu.

In meinem Beispiel habe ich eine NSString * savedEventId-Instanzeigenschaft.

So fügen Sie ein Ereignis hinzu:

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

Entfernen Sie das Ereignis:

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

Dadurch werden Ihrem Standardkalender Ereignisse hinzugefügt. Wenn Sie mehrere Kalender haben, müssen Sie herausfinden, um welchen es sich handelt

Schnelle Version

Sie müssen das EventKit-Framework importieren

import EventKit

Ereignis hinzufügen

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

Ereignis entfernen

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
        }
    }
}
William T.
quelle
6
funktioniert nicht für mich, alles geht ohne Fehler, aber kein Ereignis im Kalender
Boris Gafurov
Alles wird im ekevent-Objekt gespeichert, aber nicht im Kalender. Hlp me
1
@William T: Kann ich den Bildschirm "Ereignis hinzufügen" der Kalender-App (unter Verwendung des URL-Schemas) anzeigen und die Ereignisinformationen übergeben, sodass beim Anzeigen des Bildschirms "Ereignis hinzufügen" vorab ausgefüllte Daten angezeigt werden. Der Benutzer muss nur die Schaltfläche Ereignis hinzufügen hinzufügen. In Ihrem Beispielereignis ohne Angabe an den Benutzer hinzugefügt.
Ans
1
Wenn alles zu funktionieren scheint und noch kein Kalender angezeigt wird, überprüfen Sie, ob Cloud VS Local-Kalender das Problem sind. Wenn Sie eine Mischung aus Cloud- und lokalen Kalendern haben, können Cloud-Kalender dazu führen, dass die lokalen Kalender ausgeblendet werden.
Zonabi
2
@ReddyBasha Wenn Sie das Ereignis hinzufügen, müssen Sie den eventIdentifier speichern und für die zukünftige Verwendung speichern. Sie sollten diese Ereignis-ID verwenden, wenn Sie sie entfernen möchten.
William T.
154

Sie können dies mit dem Event Kit-Framework in OS 4.0 tun.

Klicken Sie im Gruppen- und Dateinavigator links im Fenster mit der rechten Maustaste auf die FrameWorks-Gruppe. Wählen Sie "Hinzufügen", dann "Vorhandene FrameWorks" und dann "EventKit.Framework".

Dann sollten Sie in der Lage sein, Ereignisse mit folgendem Code hinzuzufügen:

#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
WoodenKitty
quelle
18
Vielen Dank für die Veröffentlichung. Nur eine Erinnerung an alle, die dies lesen: Achten Sie auf Speicherlecks. In diesem Codebeispiel gibt es ein paar. Außerdem empfehlen Best Practices, dass Sie den Wert von 'err' nach saveEvent: span: error überprüfen und die Dinge entsprechend behandeln.
David Carney
Wissen Sie, wie Sie ein Wiederholungsereignis hinzufügen können? wie eine Veranstaltung für jeden Montag?
Jay Vachhani
5
Fügen Sie ein Wiederholungsereignis programmgesteuert hinzu: Überprüfen Sie dies unter developer.apple.com/library/ios/#documentation/EventKit/… . Eine weitere Option ist die Verwendung der vom Framework bereitgestellten Standard-Ansichtscontroller zum Hinzufügen / Bearbeiten von Ereignissen (wie die App bit.ly/cJq4Bh auf einen Blick ). Für diese Option siehe developer.apple.com/library/ios/#documentation/EventKitUI/…
DenTheMan
1
4.0? Ich werde nicht in 6 fliegen, siehe Antwort oben
Boris Gafurov
13

Ja, dafür gibt es noch keine API (2.1). Aber es schien, als ob bei WWDC viele Leute bereits an der Funktionalität interessiert waren (einschließlich meiner selbst) und die Empfehlung war, auf die unten stehende Site zu gehen und eine Feature-Anfrage dafür zu erstellen. Wenn genügend Interesse besteht, wird das ICal.framework möglicherweise in das öffentliche SDK verschoben.

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

keremk
quelle
5
Antwort ist veraltet, überlegen Sie, dies zu entfernen
Jasper
12

Der Kalenderzugriff wird in iPhone OS 4.0 hinzugefügt :

Kalenderzugriffs-
Apps können jetzt Ereignisse direkt in der Kalender-App mit Event Kit erstellen und bearbeiten.
Erstellen Sie wiederkehrende Ereignisse, richten Sie Start- und Endzeiten ein und weisen Sie sie einem beliebigen Kalender auf dem Gerät zu.

Chris S.
quelle
1
Ihr Link ist jetzt defekt.
Adil Soomro
5

Sie können das Ereignis mithilfe der Ereignis-API wie in Tristan beschrieben hinzufügen und ein Google Kalender-Ereignis hinzufügen, das im iOS-Kalender angezeigt wird.

Verwenden des API Objective-C-Clients von 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];
                }
              }];
}
Iggy
quelle
5

Schnelle 4.0-Implementierung:

Verwenden Sie den Import oben auf der Seite von import EventKit

dann

@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 !")
            }
        }
    })
}
Dashrath
quelle
Könntest du mir mit Google Kalender bezüglich der gleichen Antwort helfen? @Dashrath
Dilip Tiwari
4

Update für Swift 4 für Dashrath Antwort

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


}

Vergessen Sie auch nicht, die Berechtigung zur Verwendung des Kalenders hinzuzufügen Bild für private Einstellung

luhuiya
quelle
2

Arbeitscode 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)

            }
        }


       })
    }

}

Jetzt erhalten wir den Ereignisbildschirm und hier können Sie auch Ihre Einstellungen ändern:

Geben Sie hier die Bildbeschreibung ein

Fügen Sie nun die Delegatenmethode hinzu, um Abbrechen zu behandeln, und fügen Sie die Ereignisschaltflächenaktion des Ereignisbildschirms hinzu:

    extension viewController: EKEventEditViewDelegate {

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

    }
}

Hinweis: Vergessen Sie nicht, den NSCalendarsUsageDescription- Schlüssel zur Info- Liste hinzuzufügen .

Alok
quelle
1

Denken Sie daran, das endDate auf das erstellte Ereignis festzulegen. Dies ist obligatorisch.

Andernfalls schlägt es (fast lautlos) mit diesem Fehler fehl:

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

Der vollständige Arbeitscode für mich lautet:

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
}];
Halbano
quelle
1
Denken Sie auch daran, dass das Enddatum gleich oder größer als das Startdatum sein muss. Andernfalls wird ein weiterer Fehler angezeigt.
launisch
0

Die Google-Idee ist nett, hat aber Probleme.

Ich kann einen Google Kalender-Ereignisbildschirm erfolgreich öffnen - jedoch nur auf der Haupt-Desktop-Version, und er wird auf dem iPhone Safari nicht richtig angezeigt. Der mobile Google-Kalender, der in Safari ordnungsgemäß angezeigt wird, scheint nicht mit der API zum Hinzufügen von Ereignissen zu funktionieren.

Im Moment sehe ich keinen guten Ausweg aus diesem.

xgretsch
quelle
0

Einfach ... benutze die Tapku-Bibliothek ... du kannst dieses Wort googeln und es benutzen ... seine Open Source ... genieße ... keine Notwendigkeit, mit diesen Codes zu nerven ...

Rajesh_Bangalore
quelle
Kann Tapku Bibliothek Kalender mit Kalender App Ereignisse synchronisieren
coder1010
Ich weiß nur, dass die Tapku-Bibliothek ein Kalenderkomponenten-Steuerelement ist, das eine Option namens Datenquelle hat. Es liegt also an Ihrer Logik, zu schreiben, woher diese Quelle stammt ... Happy Coding :)
Rajesh_Bangalore