Advertisement
  1. Code
  2. Mobile Development

Data Inti dari Scratch: Hubungan dan Lebih Banyak Pengambilan

by
Read Time:13 minsLanguages:
This post is part of a series called Core Data from Scratch.
Core Data from Scratch: Managed Objects and Fetch Requests
Core Data from Scratch: NSFetchedResultsController

Indonesian (Bahasa Indonesia) translation by Dwi Bagus Nurrohman (you can also view the original English article)

Dalam artikel sebelumnya, kita belajar tentang NSManagedObject dan betapa mudahnya membuat, membaca, memperbarui, dan menghapus rekaman menggunakan Data Inti. Namun, saya tidak menyebutkan hubungan dalam diskusi tersebut. Selain beberapa peringatan yang perlu Anda sadari, hubungan sama mudahnya untuk memanipulasi sebagai atribut. Dalam artikel ini, kami akan fokus pada hubungan dan kami juga akan melanjutkan eksplorasi NSFetchRequest kami.

1. Hubungan

Kami sudah bekerja dengan hubungan dalam editor model Data Inti dan yang akan saya ceritakan kepada Anda akan terdengar akrab. Hubungan, seperti atribut, diakses menggunakan kode nilai kunci. Ingat bahwa model data yang kami buat sebelumnya dalam seri ini mendefinisikan entitas Person dan entitas Address. Seseorang terhubung dengan satu atau lebih alamat dan alamat terkait dengan satu atau lebih orang. Ini adalah hubungan banyak-ke-banyak.

Untuk mengambil alamat seseorang, kita cukup memanggil valueForKey: pada orang itu, instance NSManagedObject, dan masukkan addresses sebagai kuncinya. Perhatikan bahwa addresses adalah kunci yang kami tetapkan dalam model data. Jenis objek apa yang Anda harapkan? Kebanyakan orang yang baru menggunakan Core Data mengharapkan NSArray yang diurutkan, tetapi Core Data mengembalikan NSSet, yang tidak disortir. Bekerja dengan NSSet memiliki kelebihan seperti yang akan Anda pelajari nanti.

Menciptakan Catatan

Cukup dengan teori, buka proyek dari artikel sebelumnya atau klon dari GitHub. Mari kita mulai dengan membuat seseorang lalu menautkannya ke alamat. Untuk membuat seseorang, perbarui application: didFinishLaunchingWithOptions: metode seperti yang ditunjukkan di bawah ini.

Ini seharusnya terlihat familier jika Anda telah membaca artikel sebelumnya. Membuat alamat terlihat mirip seperti yang Anda lihat di bawah ini.

Karena setiap atribut dari entitas Address ditandai sebagai opsional, kita tidak perlu menetapkan nilai untuk setiap atribut. Dalam contoh di atas, kami hanya mengatur atribut catatan street dan city.

Menciptakan Hubungan

Untuk menautkan newAddress ke newPerson, kami memanggil setValue:forKey:, meneruskan addresses sebagai kuncinya. Nilai yang kami berikan adalah NSSet yang berisi newAddress. Lihatlah blok kode berikut untuk klarifikasi.

Kami menyebutnya save: pada konteks objek yang dikelola objek newPerson untuk menyebarkan perubahan ke penyimpanan persisten. Ingat bahwa panggilan save: pada konteks objek yang dikelola menyimpan keadaan konteks objek yang dikelola. Ini berarti bahwa newAddress juga ditulis ke backing store serta hubungan yang baru saja kita definisikan.

Anda mungkin bertanya-tanya mengapa kami tidak mengaitkan newPerson dengan newAddress, karena kami mendefinisikan hubungan terbalik dalam model data kami. Data Inti menciptakan hubungan ini untuk kami. Jika suatu hubungan memiliki hubungan terbalik, maka Core Data akan mengurus ini secara otomatis. Anda dapat memverifikasi ini dengan menanyakan objek newAddress untuk persons.

Mengambil dan Memutakhirkan Hubungan

Memperbarui sebuah hubungan tidak sulit juga. Satu-satunya peringatan adalah bahwa kita perlu menambahkan atau menghapus elemen dari NSSet yang tidak dapat diubah, misalnya, tangan Data Core kepada kami. Untuk membuat tugas ini lebih mudah, bagaimanapun, NSManagedObject mendeklarasikan metode kemudahan bisa mutableSetValueForKey:, yang mengembalikan objek NSMutableSet. Kami kemudian hanya dapat menambahkan atau menghapus item dari koleksi untuk memperbarui hubungan.

Lihatlah blok kode berikut di mana kami membuat alamat lain dan mengaitkannya dengan newPerson. Kami melakukan ini dengan menerapkan mutableSetValueForKey: pada newPerson dan tambahkan otherAddress ke set yang bisa berubah. Tidak perlu memberitahu Core Data bahwa kami telah memperbarui hubungan. Data Inti melacak kumpulan yang bisa berubah yang diberikannya dan memperbarui hubungan yang sesuai.

Menghapus Hubungan

Menghapus sebuah relasi sesederhana seperti memohon setValue:forKey:, melewati  nil sebagai nilai dan nama hubungan sebagai kuncinya. Ini membatalkan tautan setiap alamat dari newPerson.

2. Hubungan Satu-ke-Satu dan Satu-ke-Banyak

Hubungan Satu-ke-Satu

Meskipun model data kami tidak mendefinisikan hubungan satu-ke-satu, Anda telah mempelajari semua yang perlu Anda ketahui untuk bekerja dengan jenis hubungan ini. Bekerja dengan hubungan satu-ke-satu identik dengan bekerja dengan atribut. Satu-satunya perbedaan adalah bahwa nilai yang Anda dapatkan kembali dari valueForKey: dan nilai yang Anda berikan kepada setValue:forKey: adalah instance NSManagedObject.

Mari perbarui model data kami untuk mengilustrasikan ini. Buka Core_Data.xcdatamodeld dan pilih entitas Person. Buat hubungan baru dan beri nama spouse. Atur entitas Person sebagai tujuan dan tetapkan hubungan spouse sebagai hubungan terbalik.

Seperti yang Anda lihat, sangat mungkin untuk menciptakan hubungan di mana tujuan hubungan adalah entitas yang sama dengan entitas yang menentukan hubungan. Juga perhatikan bahwa kami selalu mengatur kebalikan dari hubungan itu. Sebagaimana dinyatakan oleh dokumentasi, ada sangat sedikit situasi di mana Anda ingin membuat hubungan yang tidak memiliki hubungan terbalik.

Tahukah Anda apa yang akan terjadi jika Anda membangun dan menjalankan aplikasi? Itu benar, aplikasi akan crash. Karena kami mengubah model data, toko yang ada, database SQLite dalam contoh ini, tidak lagi kompatibel dengan model data. Untuk memperbaiki ini, hapus aplikasi dari perangkat Anda atau iOS Simulator dan jalankan aplikasi. Namun jangan khawatir, kami akan menyelesaikan masalah ini dengan lebih elegan dalam angsuran berikutnya menggunakan migrasi.

Jika Anda dapat menjalankan aplikasi tanpa masalah, maka saatnya untuk langkah selanjutnya. Kembali ke kelas delegasi aplikasi dan tambahkan blok kode berikut.

Untuk menetapkan anotherPerson sebagai pasangan dari newPerson, kami mengaktifkan setValue: forKey: pada newPerson dan meneruskan anotherPerson dan @"spouse" sebagai argumen. Kita dapat mencapai hasil yang sama dengan menerapkan setValue:forKey: pada anotherPerson dan meneruskan newPerson dan @"spouse" sebagai argumen.

Hubungan Satu-ke-Banyak

Mari kita selesaikan dengan melihat hubungan satu ke banyak. Buka Core_Data.xcdatamodeld, pilih entitas Person, dan buat hubungan bernama children. Setel tujuan ke Person, atur jenis ke To Many, dan biarkan hubungan terbalik kosong untuk saat ini.

Buat hubungan lain bernama father, tetapkan tujuan ke Person, dan atur hubungan terbalik dengan children. Ini secara otomatis akan mengisi hubungan terbalik dari hubungan children yang kita kosongkan beberapa saat yang lalu. Kami sekarang telah menciptakan hubungan satu-ke-banyak, yaitu, seorang ayah dapat memiliki banyak anak, tetapi seorang anak hanya dapat memiliki satu ayah.

Kembali ke delegasi aplikasi dan tambahkan blok kode berikut. Kami membuat catatan Person yang lain, mengatur atributnya, dan mengaturnya sebagai anak dari newPerson dengan meminta Data Inti untuk set yang dapat berubah untuk kunci children dan menambahkan catatan baru ke set yang bisa berubah.

Blok kode berikut menyelesaikan hasil yang sama dengan menetapkan atribut father dari anotherChildPerson. Hasilnya adalah newPerson menjadi bapak dari otherChildPerson dan anotherChildPerson menjadi anak dari newPerson.

3. Lebih Banyak Mengambil

Model data dari aplikasi contoh kami telah berkembang sedikit dalam hal kompleksitas. Kami telah membuat hubungan satu-ke-satu, satu-ke-banyak, dan banyak-ke-banyak. Kami telah melihat betapa mudahnya membuat rekaman, termasuk hubungan. Namun, jika kami juga ingin dapat menarik data tersebut dari penyimpanan persisten, maka kami perlu tahu lebih banyak tentang pengambilan. Mari kita mulai dengan contoh sederhana di mana kita melihat bagaimana mengurutkan hasil yang dikembalikan oleh permintaan pengambilan.

Urutkan Deskriptor

Untuk mengurutkan catatan yang kami dapatkan dari konteks objek yang dikelola, kami menggunakan kelas NSSortDescriptor. Lihatlah potongan kode berikut.

Kami menginisialisasi permintaan pengambilan dengan meneruskan entitas yang kami minati, Person. Kami kemudian membuat objek NSSortDescriptor dengan menerapkan sortDescriptorWithKey:ascending:, meneruskan atribut dari entitas yang ingin kita urutkan berdasarkan, first, dan boolean yang menunjukkan apakah rekaman perlu diurutkan dalam urutan menaik atau menurun.

Kami mengikat deskriptor semacam permintaan ambil dengan memanggil setSortDescriptors: pada permintaan ambil, lewat dalam array yang mencakup deskripsi semacam. Karena setSortDescriptors: menerima larik, adalah mungkin untuk meneruskan lebih dari satu jenis deskripsi. Kita akan melihat opsi ini di sejenak.

Sisa dari blok kode harus terlihat akrab. Permintaan pengambilan diteruskan ke konteks objek yang dikelola, yang mengeksekusi permintaan ambil saat kita menjalankan executeFetchRequest:error:. Penting untuk selalu meneruskan pointer ke objek NSError untuk mengetahui apa yang salah jika eksekusi permintaan pengambilan gagal.

Jalankan aplikasi dan periksa output di konsol Xcode. Outputnya akan terlihat seperti apa yang ditunjukkan di bawah ini. Seperti yang Anda lihat, catatan diurutkan berdasarkan nama depannya.

Jika Anda melihat duplikat dalam output, maka pastikan untuk mengomentari kode yang kami tulis sebelumnya untuk membuat rekaman. Setiap kali Anda menjalankan aplikasi, catatan yang sama dibuat, menghasilkan rekaman duplikat.

Seperti yang saya sebutkan sebelumnya, mungkin untuk menggabungkan beberapa jenis deskriptor. Mari kita urutkan catatan berdasarkan nama terakhir dan umur mereka. Kami pertama-tama mengatur kunci dari deskriptor tipe pertama ke last. Kami kemudian membuat deskriptor jenis lain dengan kunci age dan menambahkannya ke array deskripsi semacam yang kami berikan kepada setSortDescriptors :.

Output menunjukkan bahwa urutan deskriptor semacam dalam array penting. Catatan-catatan ini pertama kali diurutkan berdasarkan nama belakang mereka dan kemudian berdasarkan usia mereka.

Predikat

Sortor deskripsinya bagus dan mudah digunakan, tetapi predikat adalah apa yang benar-benar membuat mengambil kuat di Core Data. Sementara deskriptor semacam memberi tahu Data Inti bagaimana catatan perlu disortir, predikat menceritakannya catatan apa yang Anda minati. Kelas yang akan kami kerjakan adalah NSPredicate.

Mari kita mulai dengan mengambil setiap anggota keluarga Doe. Ini sangat mudah dilakukan dan sintaksnya akan mengingatkan Anda tentang SQL.

Kami tidak banyak berubah selain membuat objek NSPredicate dengan menerapkan predicateWithFormat: dan mengikat predikat ke permintaan pengambilan dengan meneruskannya sebagai argumen dari panggilan setPredicate: . Ide di balik predicateWithFormat: mirip dengan stringWithFormat: dalam hal ini menerima sejumlah argumen variabel.

Perhatikan bahwa string format predikat menggunakan %K untuk nama properti dan %@ untuk nilainya. Sebagaimana dinyatakan dalam Panduan Pemrograman Predikat,%K adalah substitusi argumen variabel untuk jalur kunci sementara%@ adalah substitusi argumen variabel untuk nilai objek. Ini berarti bahwa string format predikat dari contoh kami mengevaluasi ke last == "Doe".

Jika Anda menjalankan aplikasi sekali lagi dan memeriksa output di konsol Xcode, Anda akan melihat hasil berikut:

Ada banyak operator yang bisa kita gunakan untuk perbandingan. Selain = dan ==, yang identik sejauh menyangkut Data Inti, ada juga >= dan =>, <= dan =>,!= Dan <>, dan> dan <. Saya mendorong Anda untuk bereksperimen dengan operator ini untuk mempelajari bagaimana mereka memengaruhi hasil permintaan pengambilan.

Predikat berikut menggambarkan bagaimana kita dapat menggunakan >= operator untuk hanya mengambil catatan Orang dengan atribut age lebih dari 30.

Kami juga memiliki operator untuk perbandingan string, CONTAINS, LIKE, MATCHES, BEGINSWITH, dan ENDSWITH. Mari kita ambil setiap catatan Orang yang namanya CONTAINS huruf j.

Jika Anda menjalankan aplikasi sekarang, larik hasil akan kosong karena perbandingan string peka huruf besar secara default. Kita dapat mengubahnya dengan menambahkan pengubah seperti ini:

Anda juga dapat membuat predikat gabungan menggunakan kata kunci AND, OR, dan NOT. Dalam contoh berikut, kami mengambil setiap orang yang nama depannya mengandung huruf j dan lebih muda dari 30.

Predikat juga membuatnya sangat mudah untuk mengambil catatan berdasarkan hubungan mereka. Dalam contoh berikut, kami mengambil setiap orang yang nama ayahnya sama dengan Bart.

Predikat di atas bekerja seperti yang diharapkan, karena%K adalah substitusi argumen variabel untuk jalur kunci, bukan hanya kunci.

Yang perlu Anda ingat adalah predikat itu memungkinkan Anda untuk meminta informasi backing store tanpa Anda mengetahui apa pun tentang toko tersebut. Meskipun sintaks string format predikat mengingatkan pada SQL dalam beberapa hal, tidak masalah jika backing store adalah database SQLite atau penyimpanan di memori. Ini adalah konsep yang sangat kuat yang tidak unik untuk Data Inti. Rekaman Aktif Rails adalah contoh lain dari paradigma ini.

Ada lebih banyak predikat daripada apa yang saya tunjukkan dalam artikel ini. Jika Anda ingin mempelajari lebih lanjut tentang predikat, saya sarankan Anda mencapai puncak di Panduan Pemrograman Predikat Apple. Kami juga akan bekerja lebih banyak dengan predikat di beberapa artikel berikutnya dari seri ini.

Kesimpulan

Kami sekarang memiliki pemahaman yang baik tentang dasar-dasar Core Data dan saatnya untuk mulai bekerja dengan kerangka kerja dengan membuat aplikasi yang memanfaatkan kekuatannya. Pada artikel berikutnya, kami bertemu kelas penting lainnya dari kerangka Core Data, NSFetchedResultsController. Kelas ini akan membantu kami mengelola koleksi rekaman, tetapi Anda akan belajar bahwa itu cukup lebih dari itu.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.