Bagikan melalui


EventKit di Xamarin.iOS

iOS memiliki dua aplikasi terkait kalender bawaan: Aplikasi Kalender, dan Aplikasi Pengingat. Cukup mudah untuk memahami bagaimana Aplikasi Kalender mengelola data kalender, tetapi Aplikasi Pengingat kurang jelas. Pengingat sebenarnya dapat memiliki tanggal yang terkait dengan mereka dalam hal kapan mereka jatuh tempo, ketika mereka selesai, dll. Dengan demikian, iOS menyimpan semua data kalender, baik acara kalender maupun pengingat, di satu lokasi, yang disebut Database Kalender.

Kerangka kerja EventKit menyediakan cara untuk mengakses data Kalender, Acara Kalender, dan Pengingat yang disimpan Database Kalender. Akses ke kalender dan acara kalender telah tersedia sejak iOS 4, tetapi akses ke pengingat baru di iOS 6.

Dalam panduan ini kita akan membahas:

  • Dasar-Dasar EventKit - Ini akan memperkenalkan potongan-potongan dasar EventKit melalui kelas utama dan memberikan pemahaman tentang penggunaannya. Bagian ini diperlukan untuk membaca sebelum menangani bagian berikutnya dari dokumen.
  • Tugas Umum – Bagian tugas umum dimaksudkan untuk menjadi referensi cepat tentang cara melakukan hal-hal umum seperti; menghitung kalender, membuat, menyimpan, dan mengambil acara dan pengingat kalender, serta menggunakan pengontrol bawaan untuk membuat dan memodifikasi acara kalender. Bagian ini tidak perlu dibaca front-to-back, karena dimaksudkan untuk menjadi referensi untuk tugas tertentu.

Semua tugas dalam panduan ini tersedia dalam aplikasi sampel pendamping:

Layar aplikasi sampel pendamping

Persyaratan

EventKit diperkenalkan di iOS 4.0, tetapi akses ke data Pengingat diperkenalkan di iOS 6.0. Dengan demikian, untuk melakukan pengembangan EventKit umum, Anda harus menargetkan setidaknya versi 4.0, dan 6.0 untuk pengingat.

Selain itu, aplikasi Pengingat tidak tersedia di simulator, yang berarti bahwa data pengingat juga tidak akan tersedia, kecuali Anda menambahkannya terlebih dahulu. Selain itu, permintaan akses hanya ditampilkan kepada pengguna di perangkat aktual. Dengan demikian, pengembangan EventKit paling baik diuji pada Perangkat.

Dasar-Dasar Event Kit

Saat bekerja dengan EventKit, penting untuk memahami kelas umum dan penggunaannya. Semua kelas ini dapat ditemukan di EventKit dan EventKitUI (untuk EKEventEditController).

EventStore

Kelas EventStore adalah kelas terpenting di EventKit karena diperlukan untuk melakukan operasi apa pun di EventKit. Ini dapat dianggap sebagai penyimpanan persisten, atau mesin database, untuk semua data EventKit. Dari EventStore Anda memiliki akses ke kalender dan acara kalender di Aplikasi Kalender, serta pengingat di Aplikasi Pengingat.

Karena EventStore seperti mesin database, itu harus berumur panjang, yang berarti bahwa itu harus dibuat dan dihancurkan sesedikitan mungkin selama masa pakai instans aplikasi. Bahkan, disarankan bahwa setelah Anda membuat satu instans EventStore dalam aplikasi, Anda menyimpan referensi tersebut selama seluruh masa pakai aplikasi, kecuali Anda yakin tidak akan membutuhkannya lagi. selain itu, semua panggilan harus masuk ke satu EventStore instans. Untuk alasan ini, pola Singleton direkomendasikan untuk menjaga satu instans tetap tersedia.

Membuat Penyimpanan Peristiwa

Kode berikut mengilustrasikan cara yang efisien untuk membuat satu instans EventStore kelas dan membuatnya tersedia secara statis dari dalam aplikasi:

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

Kode di atas menggunakan pola Singleton untuk membuat instans EventStore saat aplikasi dimuat. EventStore kemudian dapat diakses secara global dari dalam aplikasi sebagai berikut:

App.Current.EventStore;

Perhatikan bahwa semua contoh di sini menggunakan pola ini, sehingga mereferensikan EventStore melalui App.Current.EventStore.

Meminta Akses ke Kalender dan Data Pengingat

Sebelum diizinkan mengakses data apa pun melalui EventStore, aplikasi harus terlebih dahulu meminta akses ke data acara kalender atau data pengingat, tergantung pada data yang Anda butuhkan. Untuk memfasilitasi hal ini, EventStore mengekspos metode yang disebut RequestAccess yang — ketika dipanggil - akan menampilkan tampilan pemberitahuan kepada pengguna yang memberi tahu mereka bahwa aplikasi meminta akses ke data kalender, atau data pengingat, tergantung pada yang EKEntityType diteruskan ke sana. Karena meningkatkan tampilan pemberitahuan, panggilan tidak sinkron, dan akan memanggil handler penyelesaian yang diteruskan sebagai NSAction (atau Lambda) ke dalamnya yang akan menerima dua parameter; boolean tentang apakah akses diberikan atau tidak, dan NSError, yang, jika tidak-null akan berisi informasi kesalahan dalam permintaan. Misalnya, kode berikut akan meminta akses ke data acara kalender dan menampilkan tampilan pemberitahuan jika permintaan tidak diberikan.

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

Setelah permintaan diberikan, permintaan akan diingat selama aplikasi diinstal pada perangkat dan tidak akan memunculkan pemberitahuan kepada pengguna. Namun, akses hanya diberikan ke jenis sumber daya, baik acara kalender atau pengingat yang diberikan. Jika aplikasi membutuhkan akses ke keduanya, aplikasi harus meminta keduanya.

Karena izin diingat, relatif murah untuk membuat permintaan setiap kali, jadi ada baiknya untuk selalu meminta akses sebelum melakukan operasi.

Selain itu, karena handler penyelesaian dipanggil pada utas terpisah (non-UI), pembaruan apa pun pada UI dalam handler penyelesaian harus dipanggil melalui InvokeOnMainThread, jika tidak, pengecualian akan dilemparkan, dan jika tidak tertangkap, aplikasi akan crash.

EKEntityType

EKEntityType adalah enumerasi yang menjelaskan jenis EventKit item atau data. Ini memiliki dua nilai: Event dan Pengingat. Ini digunakan dalam sejumlah metode, termasuk EventStore.RequestAccess untuk memberi tahu EventKit jenis data apa yang akan diakses atau diambil.

EKCalendar

EKCalendar mewakili kalender, yang berisi sekelompok acara kalender. Kalender dapat disimpan di banyak tempat berbeda, seperti secara lokal, di iCloud, di lokasi penyedia pihak ke-3 seperti Server Exchange atau Google, dll. Sering kali EKCalendar digunakan untuk memberi tahu EventKit di mana mencari peristiwa, atau di mana menyimpannya.

EKEventEditController

EKEventEditController dapat ditemukan di EventKitUI namespace dan merupakan pengontrol bawaan yang dapat digunakan untuk mengedit atau membuat acara kalender. Sama seperti pengontrol kamera bawaan, EKEventEditController melakukan pengangkatan berat untuk Anda dalam menampilkan UI dan menangani penghematan.

EKEvent

EKEvent mewakili acara kalender. Baik EKEvent dan EKReminder mewarisi dari EKCalendarItem dan memiliki bidang seperti Title, , Notesdan sebagainya.

EKReminder

EKReminder mewakili item pengingat.

EKSpan

EKSpan adalah enumerasi yang menjelaskan rentang peristiwa saat memodifikasi peristiwa yang dapat berulang, dan memiliki dua nilai: ThisEvent dan FutureEvents. ThisEvent berarti bahwa setiap perubahan hanya akan terjadi pada peristiwa tertentu dalam seri yang sedang dirujuk, sedangkan FutureEvents akan memengaruhi peristiwa tersebut dan semua pengulangan di masa mendatang.

Tugas

Untuk kemudahan penggunaan, penggunaan EventKit telah dipecah menjadi tugas umum, yang dijelaskan di bagian berikut.

Menghitung Kalender

Untuk menghitung kalender yang telah dikonfigurasi pengguna di perangkat, panggil GetCalendars dan EventStore teruskan jenis kalender (baik pengingat atau acara) yang ingin Anda terima:

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

Menambahkan atau Mengubah Peristiwa Menggunakan Pengontrol Bawaan

EKEventEditViewController melakukan banyak pengangkatan berat untuk Anda jika Anda ingin membuat atau mengedit acara dengan UI yang sama yang disajikan kepada pengguna saat menggunakan Aplikasi Kalender:

UI yang disajikan kepada pengguna saat menggunakan Aplikasi Kalender

Untuk menggunakannya, Anda harus mendeklarasikannya sebagai variabel tingkat kelas sehingga tidak dikumpulkan sampah jika dinyatakan dalam metode:

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

Kemudian, untuk meluncurkannya: buat instans, beri referensi ke EventStore, kawat delegasi EKEventEditViewDelegate ke sana, lalu tampilkan menggunakan 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 );

Secara opsional, jika Anda ingin mengisi acara sebelumnya, Anda dapat membuat acara baru (seperti yang ditunjukkan di bawah), atau Anda dapat mengambil peristiwa yang disimpan:

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

Jika Anda ingin mengisi UI terlebih dahulu, pastikan untuk mengatur properti Peristiwa pada pengontrol:

eventController.Event = newEvent;

Untuk menggunakan peristiwa yang sudah ada, lihat bagian Ambil Peristiwa menurut ID nanti.

Delegasi harus mengambil Completed alih metode , yang dipanggil oleh pengontrol ketika pengguna selesai dengan dialog:

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

Secara opsional, di delegasi, Anda dapat memeriksa Tindakan dalam Completed metode untuk memodifikasi peristiwa dan menyimpan kembali, atau melakukan hal lain, jika dibatalkan, dlletera:

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

Membuat Acara Secara Terprogram

Untuk membuat peristiwa dalam kode, gunakan metode pabrik FromStore pada EKEvent kelas, dan atur data apa pun di dalamnya:

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

Anda harus mengatur kalender tempat acara disimpan, tetapi jika Anda tidak memiliki preferensi, Anda bisa menggunakan default:

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

Untuk menyimpan peristiwa, panggil metode SaveEvent pada EventStore:

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

Setelah disimpan, properti EventIdentifier akan diperbarui dengan pengidentifikasi unik yang dapat digunakan nanti untuk mengambil peristiwa:

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

EventIdentifier adalah GUID berformat string.

Membuat Pengingat Secara Terprogram

Membuat pengingat dalam kode sama dengan membuat acara kalender:

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

Untuk menyimpan, panggil metode SaveReminder pada EventStore:

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

Mengambil Peristiwa berdasarkan ID

Untuk mengambil peristiwa dengan ID, gunakan metode EventFromIdentifier pada EventStore dan berikan EventIdentifier yang ditarik dari peristiwa:

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

Untuk peristiwa, ada dua properti pengidentifikasi lainnya, tetapi EventIdentifier adalah satu-satunya yang berfungsi untuk ini.

Mengambil Pengingat berdasarkan ID

Untuk mengambil pengingat, gunakan metode GetCalendarItem pada EventStore dan berikan CalendarItemIdentifier:

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

Karena GetCalendarItem mengembalikan EKCalendarItem, itu harus dilemparkan ke EKReminder jika Anda perlu mengakses data pengingat atau menggunakan instans sebagai nanti EKReminder .

Jangan gunakan GetCalendarItem untuk acara kalender, karena pada saat penulisan, itu tidak berfungsi.

Menghapus Peristiwa

Untuk menghapus acara kalender, panggil RemoveEvent di Anda EventStore dan teruskan referensi ke acara, dan yang sesuai EKSpan:

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

Namun, perhatikan, setelah peristiwa dihapus, referensi peristiwa akan menjadi null.

Menghapus Pengingat

Untuk menghapus pengingat, panggil RemoveReminder di EventStore dan teruskan referensi ke pengingat:

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

Perhatikan bahwa dalam kode di atas ada cast ke EKReminder, karena GetCalendarItem digunakan untuk mengambilnya

Mencari Peristiwa

Untuk mencari acara kalender, Anda harus membuat objek NSPredicate melalui metode PredicateForEvents pada EventStore. NSPredicate adalah objek data kueri yang digunakan iOS untuk menemukan kecocokan:

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

Setelah Anda membuat NSPredicate, gunakan metode EventsMatching pada EventStore:

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

Perhatikan bahwa kueri sinkron (memblokir) dan mungkin memakan waktu lama, tergantung pada kueri, sehingga Anda mungkin ingin memutar utas atau tugas baru untuk melakukannya.

Mencari Pengingat

Mencari pengingat mirip dengan peristiwa; itu membutuhkan predikat, tetapi panggilan sudah asinkron, jadi Anda tidak perlu khawatir tentang memblokir utas:

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

Ringkasan

Dokumen ini memberikan gambaran umum tentang bagian penting dari kerangka kerja EventKit, dan sejumlah tugas yang paling umum. Namun, kerangka kerja EventKit sangat besar dan kuat, dan mencakup fitur yang belum diperkenalkan di sini, seperti: pembaruan batch, mengonfigurasi alarm, mengonfigurasi pengulangan pada peristiwa, mendaftar dan mendengarkan perubahan pada database kalender, mengatur GeoFences, dan banyak lagi. Untuk informasi selengkapnya, lihat Panduan Pemrograman Kalender dan Pengingat Apple.