EventKit v Xamarin.iOS

iOS má dvě integrované aplikace související s kalendářem: aplikaci Kalendář a aplikaci Připomenutí. Je to dost jednoduché, abyste pochopili, jak aplikace Kalendář spravuje data kalendáře, ale aplikace Připomenutí je méně jasná. Připomenutí můžou mít ve skutečnosti přidružená kalendářní data, pokud jde o termín splnění, kdy jsou splněné atd. IOS proto ukládá všechna data kalendáře, ať už se jedná o události kalendáře nebo připomenutí, do jednoho umístění označovaného jako databáze kalendáře.

Architektura EventKit poskytuje způsob, jak získat přístup k datům kalendáře, událostí kalendáře a připomenutí uložených v databázi kalendáře. Od verze iOS 4 je k dispozici přístup k kalendářům a událostem kalendáře, ale přístup k připomenutím je v iOSu 6 nový.

V této příručce se budeme zabývat:

  • EventKit Basics – Seznámíte se se základními částmi EventKitu prostřednictvím hlavních tříd a seznámíte se s jejich používáním. Tato část je povinná k přečtení před vyřešením další části dokumentu.
  • Běžné úkoly – Část Běžné úkoly je určená jako rychlá reference k tomu, jak provádět běžné věci, jako jsou například výčet kalendářů, vytváření, ukládání a načítání událostí kalendáře a připomenutí, a také použití integrovaných kontrolerů k vytváření a úpravám událostí kalendáře. Tato část nemusí být čtená front-to-back, protože je určena jako reference pro konkrétní úkoly.

Všechny úkoly v této příručce jsou k dispozici v doprovodné ukázkové aplikaci:

The companion sample application screens

Požadavky

EventKit byl představen v iOS 4.0, ale přístup k datům Připomenutí byl představen v iOS 6.0. K obecnému vývoji EventKitu budete muset cílit alespoň na verzi 4.0 a 6.0 pro připomenutí.

Aplikace Reminders navíc není v simulátoru dostupná, což znamená, že data připomenutí nebudou k dispozici, pokud je nejprve nepřidáte. Kromě toho se žádosti o přístup zobrazují jenom uživateli na skutečném zařízení. Proto je vývoj pro EventKit nejlépe testován na zařízení.

Základy sady událostí

Při práci s EventKitem je důležité pochopit běžné třídy a jejich použití. Všechny tyto třídy lze nalézt v EventKit a EventKitUI (pro EKEventEditController).

EventStore

Třída EventStore je nejdůležitější třídou v EventKitu, protože je nutná k provádění jakýchkoli operací v EventKitu. Může se považovat za trvalé úložiště nebo databázový stroj pro všechna data EventKitu. Máte EventStore přístup k kalendářům i událostem kalendáře v aplikaci Kalendář a také k připomenutím v aplikaci Připomenutí.

Vzhledem k tomu EventStore , že se jedná o databázový stroj, měl by být dlouhodobý, což znamená, že by se měl vytvořit a zničit co nejméně během životnosti instance aplikace. Ve skutečnosti se doporučuje, abyste po vytvoření jedné instance EventStore v aplikaci tento odkaz zachovali po celou dobu životnosti aplikace, pokud si nejste jistí, že ji nebudete znovu potřebovat. kromě toho by všechna volání měla přejít do jedné EventStore instance. Z tohoto důvodu se pro zachování jediné instance doporučuje model Singleton.

Vytvoření úložiště událostí

Následující kód znázorňuje efektivní způsob, jak vytvořit jednu instanci EventStore třídy a zpřístupnit ji staticky z aplikace:

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 ( );
    }
}

Výše uvedený kód používá model Singleton k vytvoření instance EventStore při načítání aplikace. K EventStore aplikaci se pak dá přistupovat globálně následujícím způsobem:

App.Current.EventStore;

Všimněte si, že všechny zde uvedené příklady používají tento vzor, takže odkazují prostřednictvím EventStoreApp.Current.EventStore.

Žádost o přístup k datům kalendáře a připomenutí

Před povolením přístupu k datům přes EventStore musí aplikace nejprve požádat o přístup k datům událostí kalendáře nebo dat připomenutí v závislosti na tom, který z nich potřebujete. Aby to bylo možné usnadnit, EventStore zveřejní metodu, RequestAccess která (při zavolání) uživateli zobrazí zobrazení upozornění s oznámením, že aplikace požaduje přístup k datům kalendáře nebo datům připomenutí v závislosti na tom, která EKEntityType data se jí předávají. Vzhledem k tomu, že vyvolá zobrazení výstrahy, volání je asynchronní a zavolá obslužnou rutinu dokončení předanou jako NSAction (nebo lambda), která obdrží dva parametry; logickou hodnotu, zda byl udělen nebo nebyl udělen přístup, a , NSErrorkterý, pokud není null, bude obsahovat jakékoli informace o chybě v požadavku. Například následující kódovaný požadavek požádá o přístup k datům událostí kalendáře a zobrazí zobrazení výstrahy, pokud žádost nebyla udělena.

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 ();
            } );

Po udělení žádosti se zapamatuje, dokud je aplikace nainstalovaná na zařízení a uživateli se nezobrazí upozornění. Přístup je však udělen pouze typu prostředku, a to buď událostem kalendáře, nebo připomenutím uděleným. Pokud aplikace potřebuje přístup k oběma aplikacím, měla by požádat o obojí.

Vzhledem k tomu, že je oprávnění zapamatováno, je poměrně levné vytvořit žádost pokaždé, takže je vhodné vždy požádat o přístup před provedením operace.

Kromě toho, protože obslužná rutina dokončení je volána v samostatném vlákně (bez uživatelského rozhraní), všechny aktualizace uživatelského rozhraní v obslužné rutině dokončení by se měly volat prostřednictvím InvokeOnMainThread, jinak se vyvolá výjimka, a pokud není zachycena, aplikace dojde k chybě.

EKEntityType

EKEntityType je výčet, který popisuje typ EventKit položky nebo dat. Má dvě hodnoty: Event a Připomenutí. Používá se v řadě metod, včetně EventStore.RequestAccess toho EventKit , jakého typu dat chcete získat přístup nebo načíst.

EKCalendar

EKCalendar představuje kalendář, který obsahuje skupinu událostí kalendáře. Kalendáře se dají ukládat na mnoha různých místech, například místně, v iCloudu, v umístění poskytovatele třetí strany, jako je Exchange Server nebo Google atd. EKCalendar Často se používá k určení EventKit , kde hledat události nebo kam je uložit.

EKEventEditController

EKEventEditController lze najít v EventKitUI oboru názvů a je integrovaný kontroler, který lze použít k úpravě nebo vytváření událostí kalendáře. Podobně jako vestavěné ovladače EKEventEditController fotoaparátu, dělá těžké zdvihání za vás při zobrazení uživatelského rozhraní a zpracování ukládání.

EKEvent

EKEvent představuje událost kalendáře. Obě EKEvent a EKReminder dědí z EKCalendarItem a mají pole, jako Titleje , Notesa tak dále.

EKReminder

EKReminder představuje položku připomenutí.

EKSpan

EKSpan je výčet, který popisuje rozsah událostí při úpravě událostí, které se můžou opakovat, a má dvě hodnoty: ThisEvent a FutureEvents. ThisEvent znamená, že ke všem změnám dojde pouze u konkrétní události v řadě, na kterou se odkazuje, zatímco FutureEvents tato událost bude mít vliv na všechny budoucí opakování.

Úlohy

Kvůli snadnému použití se využití EventKitu rozdělilo na běžné úlohy popsané v následujících částech.

Zobrazení výčtu kalendářů

Pokud chcete zobrazit výčet kalendářů, které uživatel na zařízení nakonfiguroval, zavolejte GetCalendars a EventStore předejte typ kalendářů (připomenutí nebo události), které chcete obdržet:

EKCalendar[] calendars = 
App.Current.EventStore.GetCalendars ( EKEntityType.Event );

Přidání nebo úprava události pomocí integrovaného kontroleru

Pokud chcete vytvořit nebo upravit událost se stejným uživatelským rozhraním, které se uživateli zobrazí při používání aplikace Kalendář, provede ekEventEditViewController spoustu náročných úloh:

The UI that is presented to the user when using the Calendar Application

Pokud ho chcete použít, budete ji chtít deklarovat jako proměnnou na úrovni třídy, aby nezískla uvolňování paměti, pokud je deklarována v rámci metody:

public class HomeController : DialogViewController
{
        protected CreateEventEditViewDelegate eventControllerDelegate;
        ...
}

Pak jej spusťte: vytvořte instanci, dát mu odkaz na EventStore, wire up EKEventEditViewDelegate delegát do něj a pak jej zobrazit pomocí PresentViewController:

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

Pokud chcete událost předem naplnit, můžete buď vytvořit úplně novou událost (jak je znázorněno níže), nebo můžete načíst uloženou událost:

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.”;

Pokud chcete uživatelské rozhraní předem naplnit, nezapomeňte nastavit vlastnost Event na kontroleru:

eventController.Event = newEvent;

Pokud chcete použít existující událost, přečtěte si část Načtení události podle ID později.

Delegát by měl přepsat metodu Completed , která je volána kontrolerem, když uživatel dokončí dialogové okno:

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

Volitelně můžete v delegátovi zkontrolovat akci v Completed metodě a upravit událost a znovu ukládat, nebo dělat další věci, pokud je zrušen, atd.

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

Programové vytvoření události

Pokud chcete vytvořit událost v kódu, použijte metodu FromStore factory ve EKEvent třídě a nastavte na ni všechna data:

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.";

Musíte nastavit kalendář, do kterého chcete událost uložit, ale pokud nemáte žádnou předvolbu, můžete použít výchozí nastavení:

newEvent.Calendar = App.Current.EventStore.DefaultCalendarForNewEvents;

Pokud chcete událost uložit, zavolejte metodu SaveEvent na :EventStore

NSError e;
App.Current.EventStore.SaveEvent ( newEvent, EKSpan.ThisEvent, out e );

Po uložení se vlastnost EventIdentifier aktualizuje jedinečným identifikátorem, který lze později použít k načtení události:

Console.WriteLine ("Event Saved, ID: " + newEvent.CalendarItemIdentifier);

EventIdentifier je identifikátor GUID formátovaný řetězcem.

Vytvoření připomenutí prostřednictvím kódu programu

Vytvoření připomenutí v kódu je velmi stejné jako vytvoření události kalendáře:

EKReminder reminder = EKReminder.Create ( App.Current.EventStore );
reminder.Title = "Do something awesome!";
reminder.Calendar = App.Current.EventStore.DefaultCalendarForNewReminders;

Chcete-li uložit, zavolejte Metodu SaveReminder na :EventStore

NSError e;
App.Current.EventStore.SaveReminder ( reminder, true, out e );

Načtení události podle ID

Pokud chcete načíst událost podle ID, použijte metodu EventFromIdentifier na EventStore a předejte ji EventIdentifier , která byla načtena z události:

EKEvent mySavedEvent = App.Current.EventStore.EventFromIdentifier ( newEvent.EventIdentifier );

U událostí existují dvě další vlastnosti identifikátoru, ale EventIdentifier je to jediný, který pro to funguje.

Načtení připomenutí podle ID

Pokud chcete načíst připomenutí, použijte metodu GetCalendarItem na EventStore a předejte ji CalendarItemIdentifier:

EKCalendarItem myReminder = App.Current.EventStore.GetCalendarItem ( reminder.CalendarItemIdentifier );

Protože GetCalendarItem vrátí hodnotu EKCalendarItem, musí být přetypován, EKReminder pokud potřebujete získat přístup k datům připomenutí nebo použít instanci jako EKReminder později.

Nepoužívejte GetCalendarItem pro události kalendáře, protože v době psaní nefunguje.

Odstranění události

Pokud chcete odstranit událost kalendáře, zavolejte na události EventStore RemoveEvent a předejte odkaz na událost a odpovídajícíEKSpan:

NSError e;
App.Current.EventStore.RemoveEvent ( mySavedEvent, EKSpan.ThisEvent, true, out e);

Všimněte si však, že po odstranění události bude nullodkaz na událost .

Odstranění připomenutí

Pokud chcete připomenutí odstranit, zavolejte na removeReminder a EventStore předejte odkaz na připomenutí:

NSError e;
App.Current.EventStore.RemoveReminder ( myReminder as EKReminder, true, out e);

Všimněte si, že ve výše uvedeném kódu existuje přetypování EKReminder, protože GetCalendarItem byl použit k jeho načtení.

Hledání událostí

Chcete-li vyhledat události kalendáře, musíte vytvořit NSPredicate objekt prostřednictvím PredicateForEvents metoda na EventStore. Jedná se NSPredicate o datový objekt dotazu, který iOS používá k vyhledání shod:

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

Po vytvoření NSPredicatepoužijte metodu EventsMatching v :EventStore

// execute the query
EKCalendarItem[] events = App.Current.EventStore.EventsMatching ( query );

Všimněte si, že dotazy jsou synchronní (blokující) a v závislosti na dotazu můžou trvat dlouho, takže můžete chtít vytvořit nové vlákno nebo úlohu.

Hledání připomenutí

Hledání připomenutí je podobné událostem; vyžaduje predikát, ale volání je již asynchronní, takže se nemusíte starat o blokování vlákna:

// 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
        } );

Shrnutí

Tento dokument poskytl přehled důležitých částí architektury EventKit a řady nejběžnějších úloh. Architektura EventKit je ale velmi velká a výkonná a zahrnuje funkce, které zde nebyly zavedeny, například: dávkové aktualizace, konfigurace alarmů, konfigurace opakování událostí, registrace a naslouchání změnám v databázi kalendáře, nastavení GeoFences a další. Další informace najdete v Průvodci programováním kalendářů a připomenutí společnosti Apple.