Menyimpan logika penyaringan di Swift Combine. Bagian 2

Menggabungkan Data Berorientasi





Terjemahan artikel disiapkan khusus untuk siswa dari kursus lanjutan "Pengembang iOS" .





Dalam episode sebelumnya, kami berhasil memodelkan aliran nilai, di mana satu operator sederhana ( delay) dilampirkan ke setiap nilai .

Pada bagian ini, kita akan melihat beberapa operator lagi, membuat mereka, Codeabledan akhirnya mengubahnya menjadi Combine publisher saat runtime.



Jenis Operator


Sebelum kita mulai memodelkannya, kita perlu memahami jenis operator apa yang ada.

Situs ReactiveX memecahnya menjadi sekitar 10 kategori: pembuatan, transformasi, pemfilteran, penggabungan, penanganan kesalahan, bantu, kondisional, matematis / agregat, tekanan balik, operator konversi yang dapat diamati dan diamati (Ke). Jika Anda tertarik, ReactiveX memiliki penjelasan yang baik untuk setiap jenis dan operator.
Catatan: Jika Anda tidak akrab dengan RxSwift, diamati di RxSwift setara dengan Publisher di Combine.
Pada bagian sebelumnya, kami menyebutkan operator delay, yang mengacu pada tipe bantu ( utility). Hari ini kami akan fokus pada pengawetan dua filteringoperator filtering ( ).



Operator filter


Jenis operator ini mencegah semua atau sebagian (atau tidak ada) elemen aliran bergerak lebih jauh ke hulu berdasarkan kondisi ini.

dropFirst


dropFirstmenghentikan transmisi nelemen pertama . Kami hanya dapat menambahkannya ke enum kami Operator, mengingat kesederhanaannya.

enum Operator {
 case delay(seconds: Double)
 case dropFirst(count: Int)
}

Kami juga dapat dengan mudah mengonversi case listing ini ke Publisher.

extension Operator {func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> { 
switch self {
   case .dropFirst(let count):
       return publisher.dropFirst(count).eraseToAnyPublisher()
 //   
 }}}

Sekarang operator dropFirstdapat disimpan dan ditampilkan dalam daftar operator.



Penghematan dropFirstmirip dengan operator delay. Mungkin penyaringan tidak jauh berbeda dengan operator bantu. Baiklah, mari kita coba pernyataan lain sebelum kita membuat kesimpulan seperti itu.

Saring


Sebaliknya dropFirst, yang memiliki kriteria penyaringan yang sangat sederhana, operator filtermenggunakan penutup daripada tipe primitif. Ini adalah kasus yang lebih rumit. Bagaimana cara kita menyimpan dan menyebarkan penutupan?

filter(_:)

Terbitkan ulang semua elemen yang cocok dengan penutupan yang diberikan.

developer.apple.com


Mari kita lihat filterlebih dekat metode ini .

func filter(_ isIncluded: @escaping (Self.Output) -> Bool) -> Publishers.Filter<Self>

Penutupannya isIncludedmenggunakan tipe universal dan mengembalikan nilai boolean.

Apakah ada sesuatu di Yayasan yang mewakili kondisi logis dan mengembalikan nilai logis? Mengingatkan saya pada sesuatu?

Saring dengan NSPredicate


Jawabannya adalah NSPredicate. Jika kami dapat menyimpan kondisi pemfilteran sebagai ekspresi dalam format string, kami cukup meneruskan nilai stream dan menggunakannya NSPredicateuntuk mengevaluasi hasilnya.

Mari kita lanjutkan dan tambahkan filterke daftar.

enum Operator {
 case delay(seconds: Double)
 case dropFirst(count: Int)
 case filter(expression: String)
}

Yang perlu kita lakukan hanyalah memfilter ekspresi seperti %d !=3atau %@ != ā€œDā€; oleh karena itu, ekspresi adalah tipe yang tepat. Demikian pula, kami harus dapat memindahkan cantuman filter ke Penerbit.

extension Operator {
func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> { 
 switch self {
   case .filter(let expression):
   return publisher.filter { value in
               NSPredicate(format: expression,
                           argumentArray: [value])
                .evaluate(with: nil) }.eraseToAnyPublisher()
      
     //   
 }}}

Sesuai rencana, kami mengirim ekspresi NSPredicatebeserta nilai yang dikirim dari Publisher.

Perhatikan bahwa NSPredicatemenerima berbagai argumen. Oleh karena itu, ia harus bekerja dengan beberapa modifikasi, bahkan ketika nilai mengasumsikan format tuple, yang sangat umum dalam skenario reaktif. Kami akan kembali ke ini di masa mendatang ketika kami berbicara tentang operator gabungan.



Seperti yang Anda lihat, Filter Stream ditambahkan ke array pernyataan yang disimpan ini dan dikonversi ke Publisher untuk memfilter angka 3 dari nilai yang lebih tinggi.



Dalam episode berikutnya: Menyimpan Operator Transformasi, Peta dan Pindai


Dalam demo GIF, Anda mungkin menemukan bahwa daftar operator cukup kosong. Dalam beberapa minggu ke depan, kita akan mengisinya dengan berbagai jenis operator: operator transformasi, mapdan scan.
Anda dapat menemukan kode sumber di repositori kombinasi-sihir-swifui di folder taman bermain-gabungan.

Kami menantikan komentar Anda dan mengundang Anda untuk membuka hari di kursus .

All Articles