EventKit dans Xamarin.iOS
iOS a deux applications liées au calendrier intégrées : l’application calendrier et l’application Rappels. Il est assez simple de comprendre comment l’application calendrier gère les données de calendrier, mais l’application Rappels est moins évidente. Les rappels peuvent réellement avoir des dates associées en termes de date d’échéance, lorsqu’elles sont terminées, etc. Par conséquent, iOS stocke toutes les données de calendrier, qu’il s’agisse d’événements de calendrier ou de rappels, dans un emplacement, appelé base de données de calendrier.
L’infrastructure EventKit permet d’accéder aux données Calendriers, Événements de calendrier et Rappels que la base de données calendrier stocke. L’accès aux calendriers et aux événements de calendrier a été disponible depuis iOS 4, mais l’accès aux rappels est nouveau dans iOS 6.
Dans ce guide, nous allons couvrir les points suivants :
- Concepts de base d’EventKit : cela introduit les éléments fondamentaux d’EventKit via les classes principales et fournit une compréhension de leur utilisation. Cette section est nécessaire avant d’aborder la partie suivante du document.
- Tâches courantes : la section Tâches courantes est destinée à être une référence rapide sur la façon d’effectuer des tâches courantes telles que l’énumération des calendriers, la création, l’enregistrement et la récupération d’événements et de rappels de calendrier, ainsi que l’utilisation des contrôleurs intégrés pour la création et la modification d’événements de calendrier. Cette section n’a pas besoin d’être en lecture frontale, car elle est destinée à être une référence pour des tâches particulières.
Toutes les tâches de ce guide sont disponibles dans l’exemple d’application complémentaire :
Spécifications
EventKit a été introduit dans iOS 4.0, mais l’accès aux données de rappels a été introduit dans iOS 6.0. Par conséquent, pour effectuer un développement EventKit général, vous devez cibler au moins la version 4.0 et la version 6.0 pour les rappels.
En outre, l’application Rappels n’est pas disponible sur le simulateur, ce qui signifie que les données de rappel ne seront pas également disponibles, sauf si vous les ajoutez d’abord. En outre, les demandes d’accès sont affichées uniquement à l’utilisateur sur l’appareil réel. Par conséquent, le développement EventKit est le mieux testé sur l’appareil.
Concepts de base du Kit d’événements
Lorsque vous utilisez EventKit, il est important d’avoir une compréhension des classes communes et de leur utilisation. Toutes ces classes sont disponibles dans le EventKit
et EventKitUI
(pour le EKEventEditController
).
EventStore
La classe EventStore est la classe la plus importante dans EventKit, car elle est nécessaire pour effectuer des opérations dans EventKit. Il peut être considéré comme le stockage persistant ou le moteur de base de données pour toutes les données EventKit. À partir de EventStore
vous avez accès aux calendriers et aux événements de calendrier dans l’application calendrier, ainsi qu’aux rappels dans l’application Rappels.
Comme EventStore
un moteur de base de données, il doit être de longue durée, ce qui signifie qu’il doit être créé et détruit le moins possible pendant la durée de vie d’une instance d’application. En fait, il est recommandé qu’une fois que vous créez une instance d’une EventStore
application, vous conservez cette référence pendant toute la durée de vie de l’application, sauf si vous êtes sûr que vous n’en aurez plus besoin. en outre, tous les appels doivent accéder à une seule EventStore
instance. Pour cette raison, le modèle Singleton est recommandé pour conserver une seule instance disponible.
Création d’un magasin d’événements
Le code suivant illustre un moyen efficace de créer une instance unique de la EventStore
classe et de la rendre disponible statiquement à partir d’une application :
public class App
{
public static App Current {
get { return current; }
}
private static App current;
public EKEventStore EventStore {
get { return eventStore; }
}
protected EKEventStore eventStore;
static App ()
{
current = new App();
}
protected App ()
{
eventStore = new EKEventStore ( );
}
}
Le code ci-dessus utilise le modèle Singleton pour instancier une instance du EventStore
moment où l’application se charge. Vous EventStore
pouvez ensuite accéder globalement à partir de l’application comme suit :
App.Current.EventStore;
Notez que tous les exemples ici utilisent ce modèle, de sorte qu’ils référencent le EventStore
via App.Current.EventStore
.
Demande d’accès aux données de calendrier et de rappel
Avant d’être autorisée à accéder à toutes les données via EventStore, une application doit d’abord demander l’accès aux données d’événements de calendrier ou aux données de rappel, selon celle dont vous avez besoin. Pour faciliter cette opération, l’exposition EventStore
d’une méthode appelée RequestAccess
qui, lorsqu’elle est appelée, affiche une vue d’alerte à l’utilisateur lui indiquant que l’application demande l’accès aux données de calendrier ou aux données de rappel, en fonction de EKEntityType
son passage. Étant donné qu’il déclenche une vue d’alerte, l’appel est asynchrone et appelle un gestionnaire de saisie semi-automatique transmis en tant que NSAction
(ou Lambda) à celui-ci qui recevra deux paramètres ; un booléen indiquant si l’accès a été accordé ou non, et un NSError
, qui, s’il n’est pas null, contiendra des informations d’erreur dans la demande. Par exemple, le code suivant demande l’accès aux données d’événement de calendrier et affiche une vue d’alerte si la demande n’a pas été accordée.
App.Current.EventStore.RequestAccess (EKEntityType.Event,
(bool granted, NSError e) => {
if (granted)
//do something here
else
new UIAlertView ( "Access Denied",
"User Denied Access to Calendar Data", null,
"ok", null).Show ();
} );
Une fois la demande accordée, elle est mémorisée tant que l’application est installée sur l’appareil et n’affiche pas d’alerte à l’utilisateur. Toutefois, l’accès n’est accordé qu’au type de ressource, soit aux événements de calendrier, soit aux rappels accordés. Si une application a besoin d’accéder aux deux, elle doit demander les deux.
Étant donné que l’autorisation est mémorisé, il est relativement bon de faire la demande à chaque fois, il est donc judicieux de toujours demander l’accès avant d’effectuer une opération.
En outre, étant donné que le gestionnaire d’achèvement est appelé sur un thread distinct (non-UI), toutes les mises à jour de l’interface utilisateur dans le gestionnaire d’achèvement doivent être appelées via InvokeOnMainThread
, sinon une exception sera levée et, si elle n’est pas interceptée, l’application se bloque.
EKEntityType
EKEntityType
est une énumération qui décrit le type d’élément ou de EventKit
données. Il a deux valeurs : Event
et Reminder. Il est utilisé dans un certain nombre de méthodes, notamment EventStore.RequestAccess
pour indiquer EventKit
quel type de données obtenir l’accès à ou à récupérer.
EKCalendar
EKCalendar représente un calendrier qui contient un groupe d’événements de calendrier. Les calendriers peuvent être stockés dans de nombreux endroits différents, tels que localement, dans iCloud, dans un emplacement fournisseur tiers tel qu’un serveur Exchange Ou Google, etc. De nombreuses fois EKCalendar
sont utilisées pour indiquer EventKit
où rechercher des événements ou où les enregistrer.
EKEventEditController
EKEventEditController se trouve dans l’espace EventKitUI
de noms et est un contrôleur intégré qui peut être utilisé pour modifier ou créer des événements de calendrier. Tout comme les contrôleurs de caméra intégrés, EKEventEditController
effectuez le gros travail pour vous dans l’affichage de l’interface utilisateur et la gestion de l’enregistrement.
EKEvent
EKEvent représente un événement de calendrier. Les deux EKEvent
et EKReminder
héritent des EKCalendarItem
champs tels que Title
, Notes
et ainsi de suite.
EKReminder
EKReminder représente un élément de rappel.
EKSpan
EKSpan est une énumération qui décrit l’étendue des événements lors de la modification d’événements pouvant se reproduire et qui a deux valeurs : ThisEvent et FutureEvents. ThisEvent
signifie que toutes les modifications n’auront lieu qu’à l’événement particulier de la série référencée, tandis que FutureEvents
cela affectera cet événement et toutes les périodicités futures.
Tâches
Pour faciliter l’utilisation, l’utilisation d’EventKit a été divisée en tâches courantes, décrites dans les sections suivantes.
Énumérer les calendriers
Pour énumérer les calendriers que l’utilisateur a configurés sur l’appareil, appelez GetCalendars
le EventStore
type de calendriers (rappels ou événements) que vous souhaitez recevoir :
EKCalendar[] calendars =
App.Current.EventStore.GetCalendars ( EKEntityType.Event );
Ajouter ou modifier un événement à l’aide du contrôleur intégré
EKEventEditViewController effectue un grand nombre de tâches importantes pour vous si vous souhaitez créer ou modifier un événement avec la même interface utilisateur que celle présentée à l’utilisateur lors de l’utilisation de l’application calendrier :
Pour l’utiliser, vous souhaiterez la déclarer en tant que variable de niveau classe afin qu’elle ne soit pas collectée par le garbage-collected si elle est déclarée dans une méthode :
public class HomeController : DialogViewController
{
protected CreateEventEditViewDelegate eventControllerDelegate;
...
}
Ensuite, pour le lancer : instanciez-le, donnez-lui une référence au EventStore
, connectez un délégué EKEventEditViewDelegate à celui-ci, puis affichez-le à l’aide PresentViewController
de :
EventKitUI.EKEventEditViewController eventController =
new EventKitUI.EKEventEditViewController ();
// set the controller's event store - it needs to know where/how to save the event
eventController.EventStore = App.Current.EventStore;
// wire up a delegate to handle events from the controller
eventControllerDelegate = new CreateEventEditViewDelegate ( eventController );
eventController.EditViewDelegate = eventControllerDelegate;
// show the event controller
PresentViewController ( eventController, true, null );
Si vous souhaitez préremplir l’événement, vous pouvez créer un nouvel événement (comme indiqué ci-dessous) ou récupérer un événement enregistré :
EKEvent newEvent = EKEvent.FromStore ( App.Current.EventStore );
// set the alarm for 10 minutes from now
newEvent.AddAlarm ( EKAlarm.FromDate ( DateTime.Now.AddMinutes ( 10 ) ) );
// make the event start 20 minutes from now and last 30 minutes
newEvent.StartDate = DateTime.Now.AddMinutes ( 20 );
newEvent.EndDate = DateTime.Now.AddMinutes ( 50 );
newEvent.Title = "Get outside and exercise!";
newEvent.Notes = "This is your reminder to go and exercise for 30 minutes.”;
Si vous souhaitez préremplir l’interface utilisateur, veillez à définir la propriété Event sur le contrôleur :
eventController.Event = newEvent;
Pour utiliser un événement existant, consultez la section Récupérer un événement par ID plus loin.
Le délégué doit remplacer la Completed
méthode, appelée par le contrôleur lorsque l’utilisateur est terminé avec la boîte de dialogue :
protected class CreateEventEditViewDelegate : EventKitUI.EKEventEditViewDelegate
{
// we need to keep a reference to the controller so we can dismiss it
protected EventKitUI.EKEventEditViewController eventController;
public CreateEventEditViewDelegate (EventKitUI.EKEventEditViewController eventController)
{
// save our controller reference
this.eventController = eventController;
}
// completed is called when a user eith
public override void Completed (EventKitUI.EKEventEditViewController controller, EKEventEditViewAction action)
{
eventController.DismissViewController (true, null);
}
}
}
Si vous le souhaitez, dans le délégué, vous pouvez case activée l’action dans la Completed
méthode pour modifier l’événement et réinscrire, ou effectuer d’autres opérations, si elle est annulée, etc. :
public override void Completed (EventKitUI.EKEventEditViewController controller, EKEventEditViewAction action)
{
eventController.DismissViewController (true, null);
switch ( action ) {
case EKEventEditViewAction.Canceled:
break;
case EKEventEditViewAction.Deleted:
break;
case EKEventEditViewAction.Saved:
// if you wanted to modify the event you could do so here,
// and then save:
//App.Current.EventStore.SaveEvent ( controller.Event, )
break;
}
}
Création d’un événement par programmation
Pour créer un événement dans le code, utilisez la méthode de fabrique FromStore sur la EKEvent
classe et définissez les données sur celle-ci :
EKEvent newEvent = EKEvent.FromStore ( App.Current.EventStore );
// set the alarm for 10 minutes from now
newEvent.AddAlarm ( EKAlarm.FromDate ( DateTime.Now.AddMinutes ( 10 ) ) );
// make the event start 20 minutes from now and last 30 minutes
newEvent.StartDate = DateTime.Now.AddMinutes ( 20 );
newEvent.EndDate = DateTime.Now.AddMinutes ( 50 );
newEvent.Title = "Get outside and do some exercise!";
newEvent.Notes = "This is your motivational event to go and do 30 minutes of exercise. Super important. Do this.";
Vous devez définir le calendrier dans lequel vous souhaitez enregistrer l’événement, mais si vous n’avez aucune préférence, vous pouvez utiliser la valeur par défaut :
newEvent.Calendar = App.Current.EventStore.DefaultCalendarForNewEvents;
Pour enregistrer l’événement, appelez la méthode SaveEvent sur les EventStore
points suivants :
NSError e;
App.Current.EventStore.SaveEvent ( newEvent, EKSpan.ThisEvent, out e );
Une fois enregistrée, la propriété EventIdentifier est mise à jour avec un identificateur unique qui peut être utilisé ultérieurement pour récupérer l’événement :
Console.WriteLine ("Event Saved, ID: " + newEvent.CalendarItemIdentifier);
EventIdentifier
est un GUID mis en forme de chaîne.
Créer un rappel par programmation
La création d’un rappel dans le code est beaucoup la même que la création d’un événement de calendrier :
EKReminder reminder = EKReminder.Create ( App.Current.EventStore );
reminder.Title = "Do something awesome!";
reminder.Calendar = App.Current.EventStore.DefaultCalendarForNewReminders;
Pour enregistrer, appelez la méthode SaveReminder sur les EventStore
points suivants :
NSError e;
App.Current.EventStore.SaveReminder ( reminder, true, out e );
Récupération d’un événement par ID
Pour récupérer un événement par son ID, utilisez la méthode EventFromIdentifier sur l’événement EventStore
et transmettez-le à EventIdentifier
partir de l’événement :
EKEvent mySavedEvent = App.Current.EventStore.EventFromIdentifier ( newEvent.EventIdentifier );
Pour les événements, il existe deux autres propriétés d’identificateur, mais EventIdentifier
il s’agit du seul qui fonctionne pour cela.
Récupération d’un rappel par ID
Pour récupérer un rappel, utilisez la méthode GetCalendarItem sur celle-ci EventStore
et transmettez-la à CalendarItemIdentifier :
EKCalendarItem myReminder = App.Current.EventStore.GetCalendarItem ( reminder.CalendarItemIdentifier );
Étant donné que GetCalendarItem
retourne un EKCalendarItem
élément , il doit être casté EKReminder
si vous devez accéder aux données de rappel ou utiliser l’instance comme une EKReminder
version ultérieure.
N’utilisez GetCalendarItem
pas les événements de calendrier, comme au moment de l’écriture, cela ne fonctionne pas.
Suppression d’un événement
Pour supprimer un événement de calendrier, appelez RemoveEvent sur votre EventStore
application et transmettez une référence à l’événement, ainsi que les éléments appropriés EKSpan
:
NSError e;
App.Current.EventStore.RemoveEvent ( mySavedEvent, EKSpan.ThisEvent, true, out e);
Notez toutefois qu’une fois qu’un événement a été supprimé, la référence de l’événement sera null
.
Suppression d’un rappel
Pour supprimer un rappel, appelez RemoveReminder sur le EventStore
site et transmettez une référence au rappel :
NSError e;
App.Current.EventStore.RemoveReminder ( myReminder as EKReminder, true, out e);
Notez que, dans le code ci-dessus, il existe un cast sur EKReminder
, car GetCalendarItem
il a été utilisé pour le récupérer
Recherche d’événements
Pour rechercher des événements de calendrier, vous devez créer un objet NSPredicate via la méthode PredicateForEvents sur le EventStore
. Il NSPredicate
s’agit d’un objet de données de requête que iOS utilise pour localiser les correspondances :
DateTime startDate = DateTime.Now.AddDays ( -7 );
DateTime endDate = DateTime.Now;
// the third parameter is calendars we want to look in, to use all calendars, we pass null
NSPredicate query = App.Current.EventStore.PredicateForEvents ( startDate, endDate, null );
Une fois que vous avez créé le NSPredicate
, utilisez la méthode EventsMatching sur les EventStore
points suivants :
// execute the query
EKCalendarItem[] events = App.Current.EventStore.EventsMatching ( query );
Notez que les requêtes sont synchrones (bloquantes) et peuvent prendre beaucoup de temps, selon la requête, de sorte que vous souhaiterez peut-être faire tourner un nouveau thread ou une tâche pour le faire.
Recherche de rappels
La recherche de rappels est similaire aux événements ; il nécessite un prédicat, mais l’appel est déjà asynchrone. Vous n’avez donc pas besoin de vous soucier du blocage du thread :
// create our NSPredicate which we'll use for the query
NSPredicate query = App.Current.EventStore.PredicateForReminders ( null );
// execute the query
App.Current.EventStore.FetchReminders (
query, ( EKReminder[] items ) => {
// do someting with the items
} );
Résumé
Ce document a donné une vue d’ensemble des éléments importants de l’infrastructure EventKit et un certain nombre des tâches les plus courantes. Toutefois, l’infrastructure EventKit est très volumineuse et puissante, et inclut des fonctionnalités qui n’ont pas été introduites ici, telles que les mises à jour par lots, la configuration des alarmes, la configuration de la périodicité sur les événements, l’inscription et l’écoute des modifications sur la base de données de calendrier, la définition de GeoFences et bien plus encore. Pour plus d’informations, consultez le Guide de programmation calendrier et rappels d’Apple.