Combine: apa itu, konsep kunci dan Publisher dengan Subscriber

Penulis: IT Sectr Diterbitkan: 2026-03-17 Waktu membaca: 8 mnt

Combine adalah framework pemrograman reaktif dari Apple, diperkenalkan di iOS 13. Menurut Apple Documentation, 2025, Combine menyediakan API deklaratif terpadu untuk memproses peristiwa asinkron. Publisher menentukan sumber data, dan Subscriber berlangganan untuk menerimanya.

Utama

  • Combine — framework Apple bawaan untuk pemrograman reaktif, tersedia sejak iOS 13
  • Publisher — protokol yang menentukan sumber nilai Output dengan kemungkinan kesalahan Failure
  • Subscriber — protokol yang menerima nilai dari Publisher dengan demand yang dikelola
  • Subject — Publisher yang memungkinkan penyisipan peristiwa secara manual (PassthroughSubject, CurrentValueSubject)
  • Operators — map, filter, combineLatest, flatMap untuk transformasi dan penggabungan aliran

Apa itu Combine?

Combine adalah framework Swift deklaratif untuk memproses peristiwa asinkron dari waktu ke waktu. Tidak seperti pendekatan berbasis callback, Combine memungkinkan deskripsi pipeline pemrosesan data melalui rantai operator. Framework ini terintegrasi dengan Foundation (URLSession, Timer, NotificationCenter) dan SwiftUI (ObservableObject, @Published).

Protokol Publisher

Setiap tipe yang mengimplementasikan protokol Publisher harus menentukan Output (tipe nilai) dan Failure (tipe kesalahan). Publisher tidak aktif hingga berlangganan — mulai memancarkan peristiwa hanya setelah subscribe dipanggil. Ini adalah semantik dingin, karakteristik aliran reaktif, yang meningkatkan efisiensi.

Protokol Subscriber

Subscriber menerima peristiwa melalui tiga metode: receive(subscription:) — konfirmasi langganan dengan manajemen demand; receive(_:) — menerima nilai baru; receive(completion:) — penyelesaian aliran dengan sukses atau kesalahan. Demand menentukan jumlah nilai yang siap diterima Subscriber — ini adalah mekanisme backpressure.

Publisher Bawaan

Apple menyediakan banyak Publisher bawaan: Just memancarkan satu nilai dan selesai, Future — hasil asinkron dengan closure, Deferred — pembuatan Publisher yang ditangguhkan hingga saat berlangganan. URLSession.dataTaskPublisher mengubah permintaan jaringan menjadi aliran reaktif. Timer.publish membuat timer periodik. NotificationCenter.default.publisher mengubah notifikasi menjadi Publisher. Integrasi ini memungkinkan berlangganan peristiwa tanpa jembatan manual.

Publisher dan Subscriber di Combine

Di Combine, Publisher dan Subscriber terhubung melalui protokol Subscription. Subscription adalah objek penghubung yang mengontrol aliran data. Pengembang tidak perlu membuat tipe Publisher sendiri — Apple menyediakan Publisher bawaan: Just, Future, Deferred, Fail, Empty, serta Publisher untuk URLSession dan Timer.

Subject di Combine

Subject adalah Publisher yang dapat menerima nilai secara manual. PassthroughSubject tidak menyimpan status: pelanggan hanya menerima peristiwa yang terjadi setelah berlangganan. CurrentValueSubject, mirip dengan BehaviorRelay di RxSwift, menyimpan nilai saat ini dan segera meneruskannya ke pelanggan baru.

Backpressure

Mekanisme backpressure di Combine mengatur kecepatan transmisi data. Subscriber memberi tahu Publisher melalui subscription.request(.unlimited) atau subscription.request(.max(N)) berapa banyak nilai yang siap diproses. Ini mencegah luapan buffer pada kecepatan yang tidak merata antara produsen dan konsumen.

Operator Combine

Combine mencakup lebih dari 100 operator yang dibagi ke dalam kategori: transformasi (map, tryMap, flatMap), penyaringan (filter, compactMap, removeDuplicates), penggabungan (combineLatest, merge, zip), manajemen waktu (debounce, throttle, delay) dan penanganan kesalahan (catch, replaceError, retry).

Operator combineLatest menggabungkan nilai terakhir dari dua Publisher — setiap kali salah satu dari mereka memancarkan nilai baru, closure dipanggil dengan kedua nilai yang diperbarui. Operator ini sangat diperlukan dalam validasi formulir di mana status beberapa bidang input perlu dilacak secara bersamaan.

Operator debounce menunda publikasi nilai hingga interval yang ditentukan berlalu tanpa peristiwa baru. Ini sangat penting untuk bidang pencarian: permintaan ke server dikirim hanya setelah pengguna berhenti mengetik selama 300-500 md, mengurangi beban 5-10 kali lipat.

Penanganan Kesalahan

Combine menawarkan beberapa strategi penanganan kesalahan di tingkat operator. catch menangkap Failure dan mengganti Publisher dengan cadangan — aliran berlanjut tanpa crash. replaceError(with:) menempatkan nilai default sebagai pengganti kesalahan. retry(_:) mengulangi langganan sejumlah kali tertentu saat gagal. Penting: tipe kesalahan Never di tanda tangan Publisher menjamin bahwa aliran tidak akan pernah berakhir dengan kesalahan — ini memungkinkan penggunaan Publisher di SwiftUI tanpa penanganan Failure.

Contoh Kode Combine

Contoh pertama menunjukkan kerja dasar dengan Just — Publisher yang memancarkan satu nilai dan selesai:

swift
let publisher = Just("Hello Combine")

publisher
    .sink(receiveCompletion: { completion in
        print("Selesai: \(completion)")
    }, receiveValue: { value in
        print("Diterima: \(value)")
    })

Contoh kedua mendemonstrasikan integrasi Combine dengan URLSession untuk permintaan jaringan dengan pemrosesan hasil di thread utama:

swift
let url = URL(string: "https://api.example.com")!

URLSession.shared
    .dataTaskPublisher(for: url)
    .map { $0.data }
    .receive(on: DispatchQueue.main)
    .sink(receiveCompletion: { completion in
        if case .failure(let error) = completion {
            print("Kesalahan: \(error)")
        }
    }, receiveValue: { data in
        print("Data diterima: \(data.count)")
    })

Contoh ketiga — penggunaan CurrentValueSubject untuk manajemen status:

swift
let counter = CurrentValueSubject<Int, Never>(0)

counter
    .sink { value in
        print("Penghitung: \(value)")
    }

counter.send(1) // Menampilkan: Penghitung: 1
counter.send(2) // Menampilkan: Penghitung: 2
print(counter.value) // Menampilkan: 2

Combine vs RxSwift

Combine dan RxSwift memecahkan tugas yang sama — pemrograman reaktif, tetapi dengan pendekatan yang berbeda. Combine adalah framework native Apple yang terpasang di sistem: tidak memerlukan instalasi dependensi, terintegrasi dengan SwiftUI dan Foundation. RxSwift adalah pustaka pihak ketiga dengan dukungan iOS 9+ dan kumpulan operator yang lebih luas.

Kinerja Combine lebih tinggi dalam skenario tipikal berkat implementasi native di C. RxSwift menyediakan lebih banyak alat debugging (RxSwift.Resources.total, Debug), tetapi arsitektur berorientasi objeknya mungkin kurang efisien pada aliran data besar. Pilihan di antara keduanya adalah kompromi antara kemampuan dan integrasi.

Perbedaan penting — model backpressure. Di Combine, Subscriber mengelola demand melalui Subscription, yang memberikan kontrol eksplisit atas kecepatan aliran. Di RxSwift, backpressure tidak dikontrol secara default — Observable memancarkan semua nilai dan Subscriber memprosesnya saat tiba. Untuk aliran data besar, Combine terbukti lebih dapat diprediksi dan lebih aman dari segi memori.

Combine terintegrasi secara mendalam dengan SwiftUI di tingkat bahasa. @Published menghasilkan Publisher, ObservableObject menyediakan objectWillChange Publisher. SwiftUI View secara otomatis berlangganan Publisher ini dan menggambar ulang saat perubahan. Untuk UIKit ada pembungkus pihak ketiga seperti CombineCocoa, tetapi Combine pada awalnya dirancang untuk SwiftUI, sehingga integrasinya di UIKit memerlukan kode tambahan. RxSwift, sebaliknya, memiliki ekosistem yang kaya untuk UIKit: RxCocoa menyediakan pembungkus reaktif untuk semua elemen UI.

Combine mendukung integrasi dengan Core Data melalui NSFetchedResultsController Publisher. Publisher memancarkan data baru pada setiap perubahan tumpukan Core Data: penambahan, penghapusan, pembaruan catatan. Ini memungkinkan pembangunan daftar reaktif tanpa memanggil reloadData secara manual. Dengan menggabungkan Combine dengan NotificationCenter Publisher untuk UIApplication.willResignActiveNotification, pengembang menciptakan lapisan reaktif untuk seluruh siklus hidup aplikasi tanpa delegasi dan callback. Untuk kelas ObservableObject, SwiftUI secara otomatis memperbarui View saat properti @Published berubah — Combine menyediakan seluruh koneksi tanpa satu baris kode manual. Pengujian modular kode Combine dilakukan melalui XCTestExpectation dan Publisher.sink dalam kasus uji dengan isolasi Scheduler melalui ImmediateScheduler.

Saat bekerja dengan Combine di proyek UIKit, pengembang sering menggunakan langganan melalui sink dan menyimpan AnyCancellable di Set. Pola tipikal: ViewController membuat tampilan, menyimpan cancellables, berlangganan ke Publisher dari ViewModel. Saat deinit, semua langganan secara otomatis dibatalkan melalui koleksi Cancellables. Untuk bekerja dengan benar dengan UIControl di Combine, UIControl.Event Publisher dapat digunakan melalui ekstensi publisher(for:).

Debugging Combine dilakukan melalui operator print() atau handleEvents(). print(String) mencatat semua peristiwa: receive subscription, request demand, receive value, receive completion. handleEvents memberikan kontrol yang lebih halus: closure dapat ditentukan untuk setiap tahap siklus hidup Publisher. Untuk pengujian Combine ada CombineExpectations — pustaka yang memungkinkan pemeriksaan bahwa Publisher memancarkan nilai yang diharapkan dalam pengujian dengan waktu virtual dan kontrol demand.

Combine dalam Praktik

Combine secara aktif digunakan di SwiftUI untuk manajemen formulir: setiap properti @Published menghasilkan Publisher, SwiftUI berlangganan melaluinya View.body. Dengan menggabungkan beberapa Publisher melalui combineLatest, validasi formulir menjadi deklaratif: setiap Publisher melacak satu bidang, combineLatest mengumpulkan semua nilai, map memeriksanya dan mengembalikan status tombol Submit. Publishers.Merge menggabungkan beberapa Publisher dari tipe yang sama menjadi satu — berguna untuk mengumpulkan peristiwa dari berbagai kontrol ke dalam satu aliran.

Untuk integrasi Combine dengan UIKit gunakan UIControl Publisher melalui ekstensi: button.publisher(for: .touchUpInside) mengembalikan Publisher yang memancarkan peristiwa saat ditekan. CombineCocoa — pustaka komunitas yang menyediakan Publisher untuk semua peristiwa UIControl, UITextView.text, UIScrollView.contentOffset. Saat pembatalan langganan, cancellables Store dibersihkan di deinit, menjamin bahwa tidak ada langganan yang bertahan lebih lama dari pemiliknya. Untuk UIControl dengan banyak status, gunakan Publishers.MergeMany untuk menggabungkan Publisher dalam array.

Pertanyaan yang Sering Diajukan

Sejak versi iOS berapa Combine tersedia?

Combine tersedia sejak iOS 13, macOS 10.15, tvOS 13 dan watchOS 6. Ini membatasi penggunaannya dalam proyek yang memerlukan dukungan untuk versi yang lebih lama. Untuk iOS 12 dan sebelumnya, RxSwift atau pustaka pihak ketiga digunakan.

Apa perbedaan PassthroughSubject dan CurrentValueSubject?

PassthroughSubject tidak menyimpan status dan tidak mengulangi nilai terakhir kepada pelanggan baru — mereka hanya menerima peristiwa di masa depan. CurrentValueSubject menyimpan nilai saat ini dan segera meneruskannya ke pelanggan baru. CurrentValueSubject.value memungkinkan membaca dan menulis nilai saat ini secara sinkron.

Bagaimana Combine terintegrasi dengan SwiftUI?

Combine menjadi dasar SwiftUI: @Published menghasilkan Publisher, ObservableObject menggunakan objectWillChange Publisher. SwiftUI View secara otomatis berlangganan ke @ObservedObject dan @StateObject melalui pipeline Combine, menggambar ulang View saat properti berubah.

Apa itu backpressure di Combine?

Backpressure — mekanisme manajemen kecepatan transmisi data. Subscriber memberi tahu Subscription berapa banyak nilai yang siap diproses (demand). Publisher tidak dapat memancarkan lebih dari yang diminta. Ini sangat penting saat bekerja dengan aliran data besar dari soket jaringan.

Bagaimana cara menangani kesalahan di Combine?

Operator catch menangkap kesalahan dan mengganti Publisher dengan fallback. replaceError mengganti kesalahan dengan nilai default. retry mengulangi langganan sejumlah kali tertentu saat terjadi kesalahan. Semua operator harus ditempatkan sebelum subscribe untuk menghindari crash saat Failure.

Kesimpulan

  • Combine — framework Apple bawaan untuk pemrograman reaktif sejak iOS 13
  • Publisher — protokol dengan Output dan Failure, mulai bekerja setelah berlangganan
  • Subscriber — menerima nilai melalui receive dengan dukungan demand
  • Subject (PassthroughSubject, CurrentValueSubject) — Publisher dengan penyisipan peristiwa manual
  • Operator map, filter, combineLatest, debounce, catch — dasar pipeline
  • Backpressure melalui demand mencegah luapan buffer Subscriber
  • Pilih Combine untuk proyek baru dari iOS 13, RxSwift — untuk dukungan versi lama

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga