Ajouter un événement personnalisé par programme dans le calendrier iPhone

183

Existe-t-il un moyen d'ajouter un événement iCal au calendrier iPhone à partir de l'application personnalisée?

Vadim
la source

Réponses:

167

Basé sur la documentation Apple , cela a un peu changé depuis iOS 6.0.

1) Vous devez demander l'accès au calendrier de l'utilisateur via "requestAccessToEntityType: completion:" et exécuter la gestion des événements à l'intérieur d'un bloc.

2) Vous devez valider votre événement maintenant ou passer le paramètre "commit" à votre appel de sauvegarde / suppression

Tout le reste demeure inchangé...

Ajoutez le framework EventKit et #import <EventKit/EventKit.h>à votre code.

Dans mon exemple, j'ai une propriété d'instance NSString * savedEventId.

Pour ajouter un événement:

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

Supprimer l'événement:

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

Cela ajoute des événements à votre calendrier par défaut, si vous avez plusieurs calendriers, vous devrez savoir lequel est

Version Swift

Vous devez importer le framework EventKit

import EventKit

Ajouter un évènement

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

Supprimer l'événement

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.
la source
6
ne fonctionne pas pour moi, tout se passe sans erreurs mais pas d'événement dans le calendrier
Boris Gafurov
Tout est stocké dans l'objet ekevent mais pas dans le calendrier hlp me
1
@William T: Puis-je présenter l'écran Ajouter un événement de l'application Calendrier (en utilisant le schéma d'URL) et transmettre les informations de l'événement afin que lorsque l'écran Ajouter un événement apparaît, il contienne des données pré-remplies. L'utilisateur doit simplement appuyer sur le bouton d'ajout d'événement. Dans votre exemple d'événement ajouté sans aucune indication à l'utilisateur.
Ans
1
si tout semble fonctionner mais qu'aucun calendrier n'apparaît, vérifiez si les calendriers Cloud VS Local posent problème. Si vous disposez d'un mélange de calendriers cloud et locaux, les calendriers cloud peuvent forcer les calendriers locaux à être masqués.
zonabi
2
@ReddyBasha lorsque vous ajoutez l'événement, vous devez enregistrer le eventIdentifier et le stocker pour une utilisation future. Vous devez utiliser cet identifiant d'événement lorsque vous allez le supprimer.
William T.
153

Vous pouvez le faire en utilisant le framework Event Kit dans OS 4.0.

Cliquez avec le bouton droit sur le groupe FrameWorks dans le navigateur Groupes et fichiers à gauche de la fenêtre. Sélectionnez «Ajouter» puis «FrameWorks existants» puis «EventKit.Framework».

Ensuite, vous devriez pouvoir ajouter des événements avec un code comme celui-ci:

#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
la source
18
Merci d'avoir publié ceci. Juste un rappel à tous ceux qui liront ceci: faites attention aux fuites de mémoire. Il y en a quelques-uns dans cet exemple de code. De plus, les meilleures pratiques imposent de vérifier la valeur de «err» après saveEvent: span: error et de gérer les choses en conséquence.
David Carney
Savez-vous comment ajouter un événement de récurrence? comme un événement pour chaque lundi?
Jay Vachhani
5
Ajouter un événement de récurrence par programme: consultez cette rubrique developer.apple.com/library/ios/#documentation/EventKit/… . Une autre option consiste à utiliser les contrôleurs de vue fournis par le framework par défaut pour ajouter / modifier des événements (comme l'application Calendar At-A-Glance bit.ly/cJq4Bh ). Pour cette option, voir developer.apple.com/library/ios/#documentation/EventKitUI/…
DenTheMan
Pour ajouter des frameworks dans XCode 4 voir cette question SO: stackoverflow.com/questions/3352664/...
Nate
1
4.0? ne va pas voler dans 6 voir la réponse ci-dessus
Boris Gafurov
13

Oui, il n'y a toujours pas d'API pour cela (2.1). Mais il semblait qu'à la WWDC, beaucoup de gens étaient déjà intéressés par la fonctionnalité (y compris moi-même) et la recommandation était d'aller sur le site ci-dessous et de créer une demande de fonctionnalité pour cela. S'il y a suffisamment d'intérêt, ils pourraient finir par déplacer le cadre ICal.fr vers le SDK public.

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

Keremk
la source
5
La réponse est obsolète, pensez à la supprimer
Jasper
12

L'accès au calendrier est ajouté dans iPhone OS 4.0 :

Les
applications d' accès au calendrier peuvent désormais créer et modifier des événements directement dans l'application Calendrier avec Event Kit.
Créez des événements récurrents, configurez les heures de début et de fin et attribuez-les à n'importe quel calendrier sur l'appareil.

Chris S
la source
1
votre lien est rompu maintenant.
Adil Soomro
6

Implémentation Swift 4.0:

utiliser l'importation en haut de page par import EventKit

puis

@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
la source
pourriez-vous m'aider avec le calendrier google concernant la même réponse @Dashrath
Dilip Tiwari
5

Vous pouvez ajouter l'événement à l'aide de l'API d'événement comme Tristan l'a décrit et vous pouvez également ajouter un événement Google Agenda qui apparaît dans le calendrier iOS.

en utilisant le client API Objective-C de 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
la source
4

Mise à jour pour Swift 4 pour Dashrath answer

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


}

n'oubliez pas non plus d'ajouter une autorisation pour l'utilisation du calendrier image pour cadre privé

luhuiya
la source
2

Code de travail dans 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)

            }
        }


       })
    }

}

Nous allons maintenant avoir l'écran des événements et ici vous pouvez également modifier vos paramètres:

entrez la description de l'image ici

Maintenant, ajoutez une méthode de délégué pour gérer Annuler et ajoutez l'action du bouton d'événement de l'écran d'événement:

    extension viewController: EKEventEditViewDelegate {

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

    }
}

Remarque: n'oubliez pas d'ajouter la clé NSCalendarsUsageDescription dans info plist.

Alok
la source
1

N'oubliez pas de définir endDate sur l'événement créé, c'est obligatoire.

Sinon, il échouera (presque silencieusement) avec cette erreur:

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

Le code de travail complet pour moi est:

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
la source
1
Et n'oubliez pas que la date de fin doit être égale ou supérieure à la date de début. Sinon, vous obtiendrez une autre erreur.
maussade du
0

L'idée de Google est intéressante, mais elle pose des problèmes.

Je peux ouvrir avec succès un écran d'événement de calendrier Google - mais uniquement sur la version de bureau principale, et il ne s'affiche pas correctement sur iPhone Safari. Le calendrier mobile de Google, qui s'affiche correctement sur Safari, ne semble pas fonctionner avec l'API pour ajouter des événements.

Pour le moment, je ne vois pas de bon moyen de sortir de celui-ci.

xgretsch
la source
0

Simple .... utilisez la bibliothèque tapku .... vous pouvez rechercher ce mot sur Google et l'utiliser ... son open source ... profitez ..... pas besoin de bugger avec ces codes ....

Rajesh_Bangalore
la source
Le calendrier de la bibliothèque Tapku peut-il se synchroniser avec les événements de l'application de calendrier
Coder1010
Tout ce que je sais, c'est que la bibliothèque Tapku est un contrôle de composant de calendrier doté d'une option appelée Source de données. Donc, il est logique d'écrire où cette source que vous récupérez ... Happy Coding :)
Rajesh_Bangalore