Mempelajari Lebih Jauh Tentang CloudKit di iOS Part II – FoodPin Apps

Jika dipostingan sebelumnya kita membahas tentang apa itu framework CloudKit, menggunakan CloudKit, dan tutorial mengimplementasikan CloudKit pada aplikasi, nah di postingan kali ini kita sedikit membahas tentang performa dari implementasi CloudKit.

Implementasi CloudKit di iOS Part II

Pada testing terakhir dari aplikasi, kita mendapatkan bahwa aplikasi berjala sangat lamban untuk me-load data dari iCloud.

Kenapa Lamban ?

cat_slow_moKenapa sih load data nya lamban? Apakah masalah koneksi jaringan? Atau gara-gara ukuran gambar?

Mari kita bahas ini secara mendetail. Jika kita sama-sama melihat kembali code yang ada di method getRecordFromCloud kita membuat pesan seperti ini  “Complete the download of Restaurant Data” yang di tampilkan ke console ketika query berhasil di eksekusi. Coba jalankan kembali aplikasi, dan lihat console.

Pesan Console setelah query complete
Pesan Console setelah query complete

Selama proses hanya memakan waktu berapa detik untuk menampilkan pesan tersebut ke console. Tapi memakan waktu sekitar 10-20 detik untuk menampilkan record ke halaman.

Nah dari kondisi itu kita bisa ambil kesimpulan bahwa akar masalah dari lambanya load record bukanlah karena jaringan atau speed download. Melainkan karena cara menampilkannya pada tabel cell. Mari kita lihat kembali method performQuery :

Walaupun kita memanggil method reloadData untuk memanggil ulang table view setelah didownload, ternyata proses reload tidak berjalan dengan semestinya.

Seperti yang telah dibahas disebelumnya bahawa semua query berjalan secara asynchrounous. CloudKit secara otomatis mengeksekusi query di background, dengan kata lain complete handler di ekskusi menggunakan background thread.

Jika Anda masih baru di dunia programming, mungkin Anda tidak familiar dengan yang namanya dengan thread. Tetapi tentu Anda akan familiar dengan situasi berikut:

  • kita harus mengerjakan tugas rumah
  • tetapi juga ingin menonton TV
  • dan mengecek facebook, twitter, dsb.

Kita melakukan banyak kegiatan di waktunya sama. Kita membagi waktu kita sedikit untuk tugas rumah, sedikit untuk TV, dan juga facebook-an.

Dalam dunia komputasi, situasi diatas terjadi diwaktu yang bersamaan. Dan Aplikasi selalu bekerja untuk meng-handle banyak tugas secara paralel. Misalnya untuk meng-update user interface, ketika user meninput dan mendownload file dari internet. Untuk setiap tugas, aplikasi menggunakan thread untuk menanganinya.

iOS mengalokasikan sedikit waktu untuk setiap thread dan dilakukan secara bergantian. Waktu yang dialokasikan disetiap thread bervariasi, tergantung dari pada prioritasnya. Biasanya yang dialokasikan pertama kali adalah prioritas yang lebih tinggi dan dengan waktu yang lebih lama.

Nah diasumsikan kita telah memahami sedikit tentang teori dasar dari thread, mari kembali lagi ke code. CloudKit membuat backround thread untuk query search dan mengeksekusi reload table di background thread ini.

Nah di iOS, untuk mengupdate UI seperti table reload ini harus di eksekusi di main thread. Main thread diprioritaskan utama agar UI tetap responsive. Jika kita mengupdate UI di background thread, maka UI tersebut tidak akan dieksekusi segera. Inilah sebabnya kenapa memakan waktu yang lama hingga akhirnya data tampil di table view.

Nah bagaimana kita memperbaikinya untuk meningkatkan perfroma aplikasi?

Sebenarnya sangat mudah, kita hanya harus memindahkannya ke main thread. Kita gunakan fungsi dispatch_async dan main thread yang spesifik (seperti memanggil dispatch_get_main_queue()) untuk menjalankan tugasnya. Jadi update codenya menjadi seperi ini:

dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})

Setelah menggantinya, coba jalankan aplikasi kembali. Aplikasi akan menampilkan record restaurant setelah download berhasil.


Mengambil Data dari Public Database menggunakan API Operational

API Convenience bagus digunakan untuk query yang simple, dikarenakan tidak memiliki batasan. Method performQuery hanya digunakan mengambil data dalam jumlah kecil. Jadi jika kita mempunyai beberapa ratus data atau lebih, maka method ini tidak akan cocok. Selain itu kita tidak bisa melakukan “tweaking” menggunakan API Convenience. Ketika kita memanggil method performQuery, method tersebut akan memanggil semua record yang berisikan attribut seperti nama, tipe, lokasi, dan gambar. Jadi jika kita hanya ingin memanggil attribut nama saja, kita tidak bisa menggunakan API Convenience, untuk itu kita harus menggunakan API Operational.

Penggunaan API Operational sebenarnya hampir sama dengan API Convenience, cuma sedikit lebih fleksibel. Mari kita contohkan kedalam code, timpa method getRecordsFromCloud dengan code dibawah ini:

Baris pertama dari code sebenarnya sama persis dengan sebelumnya, dimana kita mengambil default container dan public database-nya, lalu diikuti dengan pembuatan query untuk mengambil record Restaurant.

Selama kita memanggil method performQuery secara langsung, kita juga telah membuat operation object untuk query (yang dinamakan dengan API Operational). Query operation object bertanggung jawab untuk beberapa pengaturan, salah satunya property desiredKeys yang memperbolehkan kita untuk menentukan field apa saja yang diambil. Code diatas memberitahu query operation object bahwa yang kita butuhkan hanyalah field nama dan image dari records. Biasanya, kita menggunakan desiredKeys untuk membatasi jumlah data yang diambil untuk setiap record selama melakukan operasi pencarian.

Selain dari property desiredKey, kita juga akan menggunakan property queuePriority untuk menentukan prioritas dari operasi, sedangkan property resultsLimit untuk menentukan jumlah maksimum suatu record dari satu waktu.


Mengoptimasi Performa Aplikasi

Performa aplikasi merupakan salah satu alasan terpenting kenapa user bisa betah dengan aplikasi kita nantinya. Maka dari itu kita punya alasan yang kuat untuk mengerahkan fokus kita pada optimasi aplikasi. Tapi bagaimana caranya?

Mengoptimasi performa server? mmm, sepertinya terlalu jauh. Sejauh ini kita hanya bekerja ada aplikasi, jadi mari kita fokus saja pada aplikasi.

Mengurangi ukuran dari gambar? mmm, bisa jadi. Tapi tidak akan terlalu berpengaruh pada performa, malahan membuat kualitas gambar pada aplikasi terlihat jelek.

Terkadang kita terlalu fokus untuk mengoptimasi performa sebuah aplikasi tanpa berpikir cara lain yang membuatnya jadi lebih simple. Yaitu mengoptimasi performa yang dirasakan oleh user. Ok mari kita perjelas, misalnya kita telah mengoptimasi pada bagian tab feed untuk mengurangi ukuran dan kuliatas gambar, yang sebelumnya memakan waktu load sebesar 10 detik menjadi 6 detik setelah di optimasi. Ini merupakan optimasi yang cukup signifikan karena melakukan optimasi sebesar 40%.

Tapi taukah Anda, itu masih terasa lamban, karena user membutuhkan aplikasi yang fast respon, yang menampilkan apa yang diinginkan di saat itu juga. Tentu statistik teknik dari optimasi tadi tidak begitu penting lagi. Jadi disini kita harus tau cara bagaimana membuat user menganggap bahwa aplikasi kita sudah  “fast respone”, yaitu dengan cara:

 

Activity Indicator

pull-down-refresh-iphone-app-interface-ux-design-ramotionSalah satu cara untuk meningkatkan kinerja aplikasi adalah dengan membuatnya responsive. Contohnya gini, ketika kita memilih halaman Feed, maka akan tampil layar putih terlebih dahulu karena sistem sedang melakukan downloading data dari iCloud. Padahal user berahap ketika user sudah berada di halaman tersebut, sudah ada konten yang di tampilkan. Untuk mengatasinya kita harus membuat Activity Indikator berupa animasi. Bahkan banyak penelitian yang menunjukkan bahwa indikator loading ini dapat mempertahankan fokus/perhatian User.

Incicator Activity dari iOS
Incicator Activity dari iOS

Framework UIKit bertanggung jawab pada class yang dinamakan dengan UIActivityIndicatorView untuk menampilkan indikator loading (spinner) yang menunjukkan task sedang di proses.

Class ini bertanggung jawab untuk 3 style indicator: Gray, White (default), dan WhiteLarge. Pada code diatas, kita menggunakan Gray style. Biasanya posisi spinner ini ada di pada bagian atas sebelah kiri, untuk itu kita harus menggantinya menjadi center. Property control hidesWhenStopped digunakan untuk mengindikasikan bahwa spinner harus tersembunyi ketika animasi berhenti.

 

Lazy Loading Images

homepage_placeholder_iphoneNah spinner diatas sudah cukup membuat aplikasi terlihat responsive. Tapi masih ada cara lagi untuk mengoptimasi aplikasi loh, yaitu dengan lazy loading. Mari kita coba buka halaman Feed, nah konten akan muncul ketika semua data dan gambar telah berhasil didownload. Bayangkan semakin banyak data dan gambar yang ada pada database iCloud maka akan semakin lama data didownload untuk akhirnya bisa ditampilkan di aplikasi.

Dengan teknik ini, kita mempermudah pekerjaan karena pertama kali kita menampilkan gambar  default untuk setiap gambar restaurant sampai gambar restaurant yang aslinya berhasil didownload, hingga akhirnya menampilkan gambar aslinya. Ketika gambar sudah siap, aplikasi akan meng-update image cell. Berikut ilustrasi dari lazy loading nya:

Ilustrasi Lazy Loading
Ilustrasi Lazy Loading

Untuk mengimplementasikannya, ganti property desireKeys dari query operation yang ada di method getRecordsFromCloud seperti dibawah ini:

Sebelumnya:

queryOperation.desiredKeys = ["name", "image"]

Sesudahnya:

queryOperation.desiredKeys = ["name"]

Setelah mengganti diatas, kita hanya akan menampung nama restaurant, lalu pada method tableView(_:cellForRowAtIndexPath:) modifikasi code tersebut menjadi code dibawah ini untuk mengimplementasikan lazy loading:

Pertama kali kita memasangnya menjadi default (camera.png) untuk tiap cell nya. Lalu kita menggunakan background thread untuk mendownload gambar aslinya. Ketika gambar aslinya sudah di terima, maka gambar default akan ditimpa dengan gambar asli restaurant.

Setelah modifikasi ini, kita sudah bisa melakukan testing aplikasi. Dan seharunya aplikasi sudah menjadi lebih lebih responsive lagi. Dan akan terlihat seperti gambar dibawah ini.

Contoh implementasi Lazy Loading
Contoh implementasi Lazy Loading

Well kita lanjutkan Mempelajari Lebih Jauh Tentang CloudKit di iOS Part III ya Guys ..

Iklan

Good People write good comments ..

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s