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:
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 EventStore
App.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 , NSError
který, 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 Title
je , Notes
a 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:
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 null
odkaz 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í NSPredicate
použ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.