Aggiungi a livello di codice evento personalizzato nel calendario di iPhone


181

Esiste un modo per aggiungere l'evento iCal al calendario iPhone dall'app personalizzata?

Risposte:


166

Basato sulla documentazione Apple , questo è leggermente cambiato rispetto a iOS 6.0.

1) È necessario richiedere l'accesso al calendario dell'utente tramite "requestAccessToEntityType: completamento:" ed eseguire la gestione degli eventi all'interno di un blocco.

2) Devi impegnare il tuo evento ora o passare il parametro "commit" alla tua chiamata di salvataggio / rimozione

Tutto il resto rimane uguale ...

Aggiungi il framework EventKit e #import <EventKit/EventKit.h>al tuo codice.

Nel mio esempio, ho una proprietà dell'istanza NSString * saveEventId.

Per aggiungere un evento:

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

Rimuovi l'evento:

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

Questo aggiunge eventi al tuo calendario predefinito, se hai più calendari, allora scoprirai quale è

Versione rapida

Devi importare il framework EventKit

import EventKit

Aggiungi evento

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

Rimuovi evento

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
non funziona per me, tutto procede senza errori ma nessun evento nel calendario
Boris Gafurov,

Tutto è archiviato nell'oggetto ekevent ma non è archiviato nel calendario hlp me

1
@William T: Posso presentare la schermata Aggiungi evento dell'app Calendario (usando lo schema URL) e passare le informazioni sull'evento in modo che quando appare la schermata Aggiungi evento, avrà dati precompilati. L'utente deve solo premere il pulsante Aggiungi evento. Nel tuo esempio evento aggiunto senza alcuna indicazione all'utente.
Ans

1
se tutto sembra funzionare ma non appare alcun calendario, controlla se il problema riguarda i calendari Cloud VS Local. Se disponi di una combinazione di calendari cloud e locali, i calendari cloud possono forzare i calendari locali a essere nascosti.
zonabi,

2
@ReddyBasha quando aggiungi l'evento, devi salvare eventIdentifier e memorizzarlo per un uso futuro. Dovresti usare quell'ID evento quando vai a rimuoverlo.
William T.,

154

È possibile farlo utilizzando il framework Event Kit in OS 4.0.

Fare clic con il tasto destro del mouse sul gruppo FrameWorks nel Navigatore di gruppi e file a sinistra della finestra. Seleziona "Aggiungi", quindi "FrameWorks esistenti", quindi "EventKit.Framework".

Quindi dovresti essere in grado di aggiungere eventi con codice come questo:

#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
Grazie per aver pubblicato questo Solo un promemoria per tutti coloro che leggono questo: fai attenzione a cercare perdite di memoria. Ci sono un paio in questo esempio di codice. Inoltre, le migliori pratiche imporrebbero di controllare il valore di "err" dopo saveEvent: span: error e gestire le cose di conseguenza.
David Carney,

Sai come aggiungere un evento di ricorrenza? come un evento per ogni lunedì?
Jay Vachhani,

5
Aggiungi l'evento di ricorrenza a livello di codice: controlla questo developer.apple.com/library/ios/#documentation/EventKit/… . Un'altra opzione è quella di utilizzare i controller di visualizzazione forniti dal framework predefinito per aggiungere / modificare eventi (come l'app Calendar At-A-Glance bit.ly/cJq4Bh ). Per questa opzione, consultare developer.apple.com/library/ios/#documentation/EventKitUI/…
DenTheMan il

Per aggiungere framework in XCode 4 vedi questa domanda SO: stackoverflow.com/questions/3352664/…
Nate

1
4.0? non volerà in 6 vedi sopra risposta
Boris Gafurov

13

Sì, non esiste ancora alcuna API per questo (2.1). Ma al WWDC sembrava che molte persone fossero già interessate alla funzionalità (incluso me stesso) e la raccomandazione era di andare sul sito sottostante e creare una richiesta di funzionalità per questo. Se l'interesse è sufficiente, potrebbero finire per spostare ICal.framework nell'SDK pubblico.

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


5
la risposta è obsoleta, considera di rimuoverlo
Jasper,


5

Puoi aggiungere l'evento utilizzando l'API dell'evento come Tristan delineato e puoi anche aggiungere un evento di Google Calendar che viene visualizzato nel calendario iOS.

utilizzando il client API di Objective-C di 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];
                }
              }];
}

5

Implementazione di Swift 4.0:

usa import nella parte superiore della pagina di import EventKit

poi

@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 !")
            }
        }
    })
}

potresti aiutarmi con il calendario di Google per quanto riguarda la stessa risposta @Dashrath
Dilip Tiwari

4

Aggiornamento per swift 4 per la risposta di 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.
    }


}

inoltre, non dimenticare di aggiungere l'autorizzazione per l'utilizzo del calendario immagine per ambiente privato


2

Codice di lavoro 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)

            }
        }


       })
    }

}

Ora avremo la schermata dell'evento e qui puoi anche modificare le tue impostazioni:

inserisci qui la descrizione dell'immagine

Ora aggiungi il metodo delegato per gestire Annulla e aggiungi l'azione del pulsante evento della schermata evento:

    extension viewController: EKEventEditViewDelegate {

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

    }
}

Nota: non dimenticare di aggiungere la chiave NSCalendarsUsageDescription nella finestra informazioni.


1

Ricorda di impostare endDate sull'evento creato, è obbligatorio.

Altrimenti fallirà (quasi in silenzio) con questo errore:

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

Il codice di lavoro completo per me è:

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
E ricorda anche che la data di fine deve essere uguale o maggiore della data di inizio. Altrimenti, otterrai un altro errore.
lunatico

0

L'idea di Google è bella, ma ha dei problemi.

Posso aprire correttamente una schermata degli eventi del calendario di Google, ma solo sulla versione desktop principale e non viene visualizzata correttamente su iPhone Safari. Il calendario mobile di Google, che viene visualizzato correttamente su Safari, non sembra funzionare con l'API per aggiungere eventi.

Per il momento, non riesco a vedere una buona via d'uscita da questo.


0

Semplice .... usa la libreria tapku .... puoi cercare su Google quella parola e usarla ... è open source ... divertiti ..... non c'è bisogno di alterare con quei codici ....



Il calendario della Biblioteca Tapku può sincronizzarsi con gli eventi dell'app calendario
coder1010,

Tutto quello che so è che la libreria Tapku è un controllo dei componenti del calendario che ha un'opzione chiamata Origine dati. Quindi è buona logica scrivere la fonte da cui stai recuperando ... Happy Coding :)
Rajesh_Bangalore,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.