Sdílet prostřednictvím


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:

Obrazovky doprovodné ukázkové aplikace

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:

Uživatelské rozhraní, které se uživateli zobrazí při použití aplikace Kalendář

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.