Advertisement
  1. Code
  2. Core Data

Inti Data dan Swift: mengambil asinkron

by
Read Time:11 minsLanguages:
This post is part of a series called Core Data and Swift.
Core Data and Swift: Batch Deletes

Indonesian (Bahasa Indonesia) translation by graywest (you can also view the original English article)

Dalam angsuran sebelumnya, kita diskusikan batch update dan menghapus batch. Dalam tutorial ini, kita akan mengambil melihat lebih dekat bagaimana menerapkan mengambil asynchronous dan dalam situasi apa aplikasi Anda dapat memperoleh manfaat dari API baru ini.

1. masalah

Seperti batch update, mengambil asinkron telah di daftar keinginan banyak pengembang untuk beberapa waktu. Mengambil permintaan dapat menjadi kompleks, mengambil non-sepele jumlah waktu untuk menyelesaikan. Selama waktu itu mengambil permintaan blok kain itu berjalan pada dan, sebagai akibatnya, blok akses ke konteks dikelola objek yang mengeksekusi permintaan fetch. Masalahnya mudah dimengerti, tapi apa solusi Apple terlihat seperti.

2. solusi.

Apple jawaban untuk masalah ini asinkron mengambil. Permintaan asynchronous fetch yang berjalan di latar belakang. Ini berarti bahwa itu tidak menghalangi tugas-tugas lain sementara sedang dijalankan, seperti memperbarui antarmuka pengguna pada benang.

Asinkron mengambil juga olahraga dua fitur nyaman, kemajuan pelaporan dan pembatalan. Permintaan asynchronous fetch dapat dibatalkan Kapan saja, misalnya, ketika pengguna memutuskan permintaan mengambil waktu terlalu lama untuk menyelesaikan. Laporan kemajuan adalah tambahan yang berguna untuk menunjukkan pengguna keadaan saat ini mengambil permintaan.

Mengambil asinkron adalah API yang fleksibel. Tidak hanya mungkin untuk membatalkan permintaan asynchronous fetch, juga dimungkinkan untuk membuat perubahan konteks dikelola objek sementara permintaan asynchronous fetch sedang dijalankan. Dengan kata lain, pengguna dapat terus menggunakan aplikasi sementara aplikasi mengeksekusi permintaan asynchronous menjemput di latar belakang.

3. Bagaimana cara kerjanya?

Seperti batch update, asynchronous fetch permintaan yang diberikan kepada konteks dikelola objek sebagai objek NSPersistentStoreRequest, instance kelas NSAsynchronousFetchRequest harus tepat.

NSAsynchronousFetchRequest instance diinisialisasi dengan objek NSFetchRequest dan blok penyelesaian. Blok selesai dijalankan ketika permintaan asynchronous fetch telah selesai mengambil permintaan.

Mari kita meninjau kembali aplikasi agenda kita buat sebelumnya dalam seri ini dan mengganti implementasi saat ini kelas NSFetchedResultsController dengan permintaan asynchronous fetch.

Langkah 1: Setup proyek

Download atau klon proyek dari GitHub dan membukanya di Xcode 7. Sebelum kita dapat mulai bekerja dengan kelas NSAsynchronousFetchRequest, kita perlu membuat beberapa perubahan. Kami tidak akan dapat menggunakan NSFetchedResultsController kelas untuk mengelola tampilan tabel data sejak kelas NSFetchedResultsController dirancang untuk dijalankan pada benang.

Langkah 2: Menggantikan Controller terlalu hasil

Mulai dengan memperbarui kelas ViewController seperti yang ditunjukkan di bawah ini. Kami menghapus properti fetchedResultsController dan membuat sebuah properti baru, item, jenis [Item] untuk menyimpan item agenda. Ini juga berarti bahwa kelas ViewController tidak lagi perlu mematuhi protokol NSFetchedResultsControllerDelegate.

Sebelum kita refactor metode viewDidLoad(), saya ingin memperbarui implementasi protokol UITableViewDataSource. Lihatlah perubahan-perubahan yang saya buat.

Kita juga perlu mengubah satu baris kode dalam metode prepareForSegue(_:sender:) seperti yang ditunjukkan di bawah ini.

Terakhir tetapi tidak paling, Hapus implementasi protokol NSFetchedResultsControllerDelegate karena kita tidak lagi membutuhkannya.

Langkah 3: Membuat permintaan Asynchronous Fetch

Seperti yang Anda lihat di bawah ini, kami menciptakan permintaan asynchronous mengambil dalam tampilan controller viewDidLoad() metode. Mari kita luangkan waktu sejenak untuk melihat apa yang terjadi.

Kita mulai dengan membuat dan mengkonfigurasi instance NSFetchRequest untuk menginisialisasi asynchronous fetch permintaan. Ini adalah permintaan ini mengambil permintaan asynchronous fetch akan mengeksekusi di latar belakang.

Untuk menginisialisasi NSAsynchronousFetchRequest instance, kita memanggil init(request:completionBlock:), melewati dalam fetchRequest dan blok penyelesaian.

Blok penyelesaian yang dipanggil ketika mengambil asynchronous permintaan telah selesai mengeksekusi permintaan fetch. Blok selesai mengambil satu argumen jenis NSAsynchronousFetchResult, yang berisi hasil query serta referensi ke asli asynchronous fetch permintaan.

Di blok selesai, kita memanggil processAsynchronousFetchResult(_:), melewati dalam objek NSAsynchronousFetchResult. Kita akan mengambil melihat ini metode penolong dalam beberapa saat.

Mengeksekusi permintaan asynchronous fetch hampir identik dengan bagaimana kami menjalankan NSBatchUpdateRequest. Kita memanggil executeRequest(_:) pada konteks dikelola objek, melewati dalam permintaan asynchronous fetch.

Meskipun permintaan asynchronous fetch dijalankan di latar belakang, dicatat bahwa metode executeRequest(_:) kembali segera, menyerahkan kami NSAsynchronousFetchResult objek. Setelah permintaan asynchronous fetch selesai, NSAsynchronousFetchResult obyek yang sama diisi dengan hasil dari permintaan fetch.

Ingat dari tutorial sebelumnya bahwa executeRequest(_:) adalah metode melempar. Kami menangkap kesalahan dalam klausa menangkap pernyataan do-menangkap dan mencetak mereka ke konsol untuk debugging.

Langkah 4: Pengolahan hasil asinkron Fetch

Metode processAsynchronousFetchResult(_:) adalah tidak lebih dari metode penolong yang kami memproses hasil dari permintaan asynchronous fetch. Kami mengatur tampilan controller item properti dengan isi dari hasil finalResult properti dan reload tampilan tabel.

Langkah 5: Membangun & menjalankan

Membangun proyek dan menjalankan aplikasi di iOS Simulator. Jika aplikasi Anda crash ketika mencoba untuk mengeksekusi permintaan asynchronous fetch, maka Anda dapat menggunakan API yang deprecated pada iOS 9 (dan OS X El Capitan).

Data inti dan Swift: Concurrency, saya menjelaskan jenis berbeda concurrency konteks dikelola objek yang dapat memiliki. Pada iOS 9 (dan OS X El Capitan), ConfinementConcurrencyType deprecated. Hal yang sama berlaku untuk init() metode kelas NSManagedObjectContext, karena ia menciptakan instance dengan concurrency jenis ConfinementConcurrencyType.

Jika aplikasi Anda crash, Anda kemungkinan besar menggunakan konteks dikelola objek dengan jenis concurrency ConfinementConcurrencyType, yang tidak mendukung mengambil asinkron. Untungnya, Solusinya sederhana. Membuat konteks dikelola objek yang menggunakan initializer Ruangan Khusus, init(concurrencyType:), melewati dalam MainQueueConcurrencyType atau PrivateQueueConcurrencyType sebagai jenis concurrency.

4. menampilkan kemajuan

Kelas NSAsynchronousFetchRequest yang menambahkan dukungan untuk memonitor perkembangan permintaan fetch dan itu bahkan dimungkinkan untuk membatalkan permintaan asynchronous fetch, misalnya, jika pengguna memutuskan bahwa itu berlangsung terlalu lama untuk menyelesaikan.

Kelas NSAsynchronousFetchRequest memanfaatkan kelas NSProgress untuk kemajuan pelaporan serta membatalkan permintaan asynchronous fetch. Kelas NSProgress, tersedia sejak iOS 7 dan OS X Mavericks, adalah cara cerdas untuk memantau kemajuan dari tugas tanpa perlu erat beberapa tugas untuk antarmuka pengguna.

Kelas NSProgress juga mendukung pembatalan, yang adalah bagaimana permintaan asynchronous fetch dapat dibatalkan. Mari kita Cari tahu apa yang kita perlu lakukan untuk melaksanakan kemajuan pelaporan untuk menjemput asynchronous permintaan.

Langkah 1: Menambahkan SVProgressHUD

Kami akan menunjukkan pengguna kemajuan permintaan asynchronous fetch menggunakan Sam Vermette SVProgressHUD Perpustakaan. Cara termudah untuk melakukannya adalah melalui CocoaPods. Ini adalah apa yang tampak seperti proyek Podfile.

Menjalankan pod menginstal bentuk baris perintah dan jangan lupa untuk membuka ruang kerja CocoaPods telah menciptakan bagi Anda daripada Xcode proyek.

Langkah 2: Menyiapkan NSProgress

Dalam artikel ini, kita tidak akan mengeksplorasi kelas NSProgress banyak detail, tetapi merasa bebas untuk membaca lebih lanjut tentang hal itu dalam dokumentasi Apple. Kami membuat NSProgress instance dalam tampilan controller viewDidLoad() metode, sebelum kita mengeksekusi permintaan asynchronous fetch.

Anda mungkin akan terkejut bahwa kita tetapkan jumlah total unit 1. Alasannya sederhana. Ketika Data inti mengeksekusi permintaan asynchronous fetch, ia tidak tahu berapa banyak catatan itu akan menemukan di toko terus-menerus. Ini juga berarti bahwa kita tidak akan mampu menunjukkan kemajuan relatif kepada pengguna — persentase. Sebaliknya, kita akan menunjukkan pengguna kemajuan mutlak-jumlah record yang telah menemukan.

Anda bisa memperbaiki masalah ini dengan melakukan mengambil permintaan untuk mengambil jumlah record sebelum Anda mengeksekusi permintaan asynchronous fetch. Saya lebih suka tidak melakukan hal ini meskipun, karena ini juga berarti bahwa mengambil catatan dari toko terus-menerus mengambil lebih lama untuk menyelesaikan karena permintaan mengambil tambahan pada awal.

Step 3: Menambahkan pengamat

Ketika kita menjalankan permintaan asynchronous menjemput, kita segera diberikan sebuah objek NSAsynchronousFetchResult. Objek ini memiliki properti kemajuan, yang merupakan jenis NSProgress. Ini adalah properti kemajuan yang kita butuhkan untuk mengamati jika kita ingin menerima update kemajuan.

Perhatikan bahwa kita sebut resignCurrent pada objek kemajuan untuk menyeimbangkan becomeCurrentWithPendingUnitCount sebelumnya: panggilan. Perlu diingat bahwa kedua metode ini perlu dipanggil pada kain yang sama.

Langkah 4: Menghapus pengamat

Di blok penyelesaian asynchronous fetch permintaan, kami menghapus pengamat dan mengabaikan kemajuan HUD.

Sebelum kita menerapkan observeValueForKeyPath(_:ofObject:change:context:), kita perlu menunjukkan kemajuan HUD sebelum membuat permintaan asynchronous fetch.

Langkah 5: Kemajuan pelaporan

Semua yang tersisa untuk kita lakukan, adalah menerapkan metode observeValueForKeyPath(_:ofObject:change:context:). Kami memeriksa jika konteks sama dengan ProgressContext, membuat objek status penggalian jumlah record selesai dari kamus perubahan, dan memperbarui kemajuan HUD. Perhatikan bahwa kami memperbarui antarmuka pengguna pada benang.

5. dummy Data

Jika kita ingin benar menguji aplikasi kita, kita perlu lebih banyak data. Sementara saya tidak merekomendasikan menggunakan pendekatan berikut dalam aplikasi produksi, ini adalah cara cepat dan mudah untuk mengisi database dengan data.

Buka AppDelegate.swift dan memperbarui metode application(_:didFinishLaunchingWithOptions:) seperti yang ditunjukkan di bawah ini. Metode populateDatabase() adalah metode sederhana penolong di mana kita menambahkan dummy data ke database.

Implementasi sangatlah mudah. Karena kami hanya ingin untuk insert dummy data sekali, kami memeriksa pengguna default database untuk kunci "didPopulateDatabase". Jika kunci tidak ditetapkan, kami memasukkan dummy data.

Jumlah record penting. Jika Anda berencana untuk menjalankan aplikasi di iOS Simulator, maka itu baik untuk memasukkan 100.000 atau 1.000.000 catatan. Ini tidak akan bekerja sebagai baik pada perangkat fisik dan akan memakan waktu terlalu lama untuk menyelesaikan.

Dalam untuk loop, kita membuat sebuah objek yang dikelola dan menempatkannya dengan data. Catatan bahwa kami tidak menyimpan perubahan konteks dikelola objek selama setiap pengulangan untuk loop.

Akhirnya, kami memperbarui pengguna default database untuk memastikan bahwa database tidak dihuni saat berikutnya aplikasi diluncurkan.

Hebat. Jalankan aplikasi di iOS Simulator untuk melihat hasil. Anda akan melihat bahwa diperlukan beberapa saat untuk mengambil asynchronous permintaan untuk mulai mengambil catatan dan update kemajuan HUD.

Showing The Progress of The Asynchronous Fetch RequestShowing The Progress of The Asynchronous Fetch RequestShowing The Progress of The Asynchronous Fetch Request

6. melanggar perubahan

Dengan mengganti kelas controller terlalu hasil dengan permintaan asynchronous menjemput, kita telah rusak beberapa bagian dari aplikasi. Misalnya, menekan centang pada item agenda tampaknya tidak bekerja lagi. Sedangkan database sedang diperbarui, antarmuka pengguna tidak mencerminkan perubahan. Solusinya cukup mudah untuk memperbaiki dan aku akan meninggalkan itu terserah Anda untuk menerapkan solusi. Sekarang Anda harus memiliki pengetahuan yang cukup untuk memahami masalah dan menemukan solusi yang cocok.

Kesimpulan

Saya yakin Anda akan setuju bahwa mengambil asinkron sangat mudah digunakan. Angkat berat dilakukan oleh inti Data, yang berarti bahwa ada tidak perlu secara manual menggabungkan hasil permintaan asynchronous fetch dengan konteks dikelola objek. Pekerjaan Anda hanya akan memperbarui antarmuka pengguna ketika permintaan asynchronous mengambil tangan Anda hasil.

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.