Combine: nedir, temel kavramlar ve Publisher ile Subscriber

Yazar: IT Sectr Yayınlanma: 2026-03-17 Okuma süresi: 8 dk

Combine, Apple’ın iOS 13 ile tanıttığı reaktif programlama framework’üdür. Apple Documentation, 2025’e göre Combine, asenkron olayları işlemek için birleşik bildirimsel bir API sağlar. Publisher veri kaynağını tanımlar ve Subscriber bunları almak için abone olur.

Anahtar Noktalar

  • Combine — iOS 13’ten itibaren kullanılabilen Apple’ın yerleşik reaktif programlama framework’ü
  • Publisher — Failure hatası olasılığı ile Output değerlerinin kaynağını tanımlayan protokol
  • Subscriber — talep yönetimi ile Publisher’dan değer alan protokol
  • Subject — manuel olay enjeksiyonuna izin veren Publisher (PassthroughSubject, CurrentValueSubject)
  • Operators — akışları dönüştürmek ve birleştirmek için map, filter, combineLatest, flatMap

Combine Nedir?

Combine, zaman içinde asenkron olayları işlemek için bildirimsel bir Swift framework’üdür. Geri çağrım tabanlı yaklaşımların aksine, Combine bir dizi operatör aracılığıyla veri işleme boru hatlarını tanımlamaya olanak tanır. Framework, Foundation (URLSession, Timer, NotificationCenter) ve SwiftUI (ObservableObject, @Published) ile entegredir.

Publisher Protokolü

Publisher protokolünü uygulayan her tür, Output (değer türü) ve Failure (hata türü) tanımlamalıdır. Publisher, abone olunana kadar etkin değildir — olayları yalnızca subscribe çağrısından sonra yaymaya başlar. Bu, reaktif akışların karakteristik özelliği olan soğuk anlambilimdir ve verimliliği artırır.

Subscriber Protokolü

Subscriber olayları üç yöntemle alır: receive(subscription:) — talep yönetimi ile abonelik onayı; receive(_:) — yeni bir değer alma; receive(completion:) — başarı veya hata ile akışın tamamlanması. Demand, Subscriber’ın kabul etmeye hazır olduğu değer sayısını belirtir — bu, geri basınç (backpressure) mekanizmasıdır.

Yerleşik Publisher’lar

Apple birçok yerleşik Publisher sağlar: Just tek bir değer yayar ve tamamlanır, Future — bir closure ile asenkron sonuç, Deferred — aboneye kadar Publisher oluşturmayı geciktirir. URLSession.dataTaskPublisher ağ isteğini reaktif bir akışa dönüştürür. Timer.publish periyodik bir zamanlayıcı oluşturur. NotificationCenter.default.publisher bildirimleri Publisher’a dönüştürür. Bu entegrasyonlar, manuel köprü olmadan olaylara abone olmayı sağlar.

Combine’da Publisher ve Subscriber

Combine’da, Publisher ve Subscriber, Subscription protokolü aracılığıyla bağlanır. Subscription, veri akışını kontrol eden bir bağlantı nesnesidir. Geliştiricilerin kendi Publisher türlerini oluşturması gerekmez — Apple yerleşik türler sağlar: Just, Future, Deferred, Fail, Empty ve URLSession ile Timer için Publisher’lar.

Combine’da Subject

Subject, içine manuel olarak değer gönderilebilen bir Publisher’dır. PassthroughSubject durum depolamaz: bir abone yalnızca abonelikten sonra gerçekleşen olayları alır. CurrentValueSubject, RxSwift’teki BehaviorRelay’e benzer şekilde geçerli değeri depolar ve yeni abonelere hemen iletir.

Geri Basınç (Backpressure)

Combine’daki geri basınç mekanizması, veri aktarım hızını düzenler. Subscriber, subscription.request(.unlimited) veya subscription.request(.max(N)) aracılığıyla Publisher’a kaç değeri işlemeye hazır olduğunu bildirir. Bu, üretici ve tüketici hızları eşitsiz olduğunda arabellek taşmasını önler.

Combine Operatörleri

Combine, kategorilere ayrılmış 100’den fazla operatör içerir: dönüşüm (map, tryMap, flatMap), filtreleme (filter, compactMap, removeDuplicates), birleştirme (combineLatest, merge, zip), zaman yönetimi (debounce, throttle, delay) ve hata işleme (catch, replaceError, retry).

combineLatest operatörü iki Publisher’ın en son değerlerini birleştirir — ikisinden biri yeni bir değer yaydığında, closure her iki güncellenmiş değerle çağrılır. Bu operatör, aynı anda birden çok giriş alanının durumunu izlemeniz gereken form doğrulaması için vazgeçilmezdir.

debounce operatörü, yeni olay olmadan belirtilen aralık geçene kadar değer yayınlanmasını geciktirir. Bu, arama alanları için kritiktir: sunucu isteği yalnızca kullanıcı 300–500 ms boyunca yazmayı bıraktıktan sonra gönderilir ve yükü 5–10 kat azaltır.

Hata İşleme

Combine, operatör düzeyinde birkaç hata işleme stratejisi sunar. catch Failure’ı yakalar ve Publisher’ı bir yedekle değiştirir — akış çökmeden devam eder. replaceError(with:) hata yerine varsayılan bir değer sağlar. retry(_:) başarısızlıkta belirtilen sayıda aboneliği yeniden dener. Önemli: Publisher imzasındaki Never hata türü, akışın asla hata ile sonlanmayacağını garanti eder — bu, SwiftUI’da Failure işlemesi olmadan Publisher kullanımına olanak tanır.

Combine Kod Örnekleri

İlk örnek, Just’in temel kullanımını gösterir — tek bir değer yayan ve tamamlanan Publisher:

swift
let publisher = Just("Hello Combine")

publisher
    .sink(receiveCompletion: { completion in
        print("Tamamlandı: \(completion)")
    }, receiveValue: { value in
        print("Alındı: \(value)")
    })

İkinci örnek, ana iplikte sonuç işleme ile ağ isteği için Combine’ın URLSession ile entegrasyonunu gösterir:

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("Hata: \(error)")
        }
    }, receiveValue: { data in
        print("Alınan veri: \(data.count)")
    })

Üçüncü örnek, durum yönetimi için CurrentValueSubject kullanımını gösterir:

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

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

counter.send(1) // Yazdırır: Sayaç: 1
counter.send(2) // Yazdırır: Sayaç: 2
print(counter.value) // Yazdırır: 2

Combine vs RxSwift

Combine ve RxSwift aynı sorunu — reaktif programlama — çözer, ancak farklı yaklaşımlarla. Combine, sisteme entegre edilmiş yerel bir Apple framework’üdür: bağımlılık kurulumu gerektirmez, SwiftUI ve Foundation ile entegredir. RxSwift, iOS 9+ desteği ve daha geniş bir operatör kümesi ile üçüncü taraf bir kütüphanedir.

Yerel C uygulaması sayesinde tipik senaryolarda Combine’ın performansı daha yüksektir. RxSwift daha fazla hata ayıklama aracı (RxSwift.Resources.total, Debug) sağlar, ancak nesne yönelimli mimarisi büyük veri akışlarında daha az verimli olabilir. Aralarındaki seçim, yetenekler ve entegrasyon arasında bir dengedir.

Önemli bir fark, geri basınç modelidir. Combine’da Subscriber, Subscription aracılığıyla talebi yönetir ve akış hızı üzerinde açık kontrol sağlar. RxSwift’te geri basınç varsayılan olarak kontrol edilmez — Observable tüm değerleri yayar ve Subscriber bunları geldikçe işler. Büyük veri akışları için Combine daha öngörülebilir ve bellek açısından daha güvenlidir.

Combine, dil düzeyinde SwiftUI ile derinlemesine entegredir. @Published bir Publisher üretir, ObservableObject objectWillChange Publisher sağlar. SwiftUI View otomatik olarak bu Publisher’lara abone olur ve değişikliklerde yeniden çizer. UIKit için CombineCocoa gibi üçüncü taraf sarmalayıcılar vardır, ancak Combine başlangıçta SwiftUI için tasarlanmıştır, bu nedenle UIKit’te entegrasyonu ek kod gerektirir. Öte yandan RxSwift, UIKit için zengin bir ekosisteme sahiptir: RxCocoa, tüm UI öğeleri için reaktif sarmalayıcılar sağlar.

Combine, NSFetchedResultsController Publisher aracılığıyla Core Data ile entegrasyonu destekler. Publisher, Core Data yığınındaki her değişiklikte (kayıt ekleme, silme, güncelleme) yeni veriler yayar. Bu, manuel olarak reloadData çağırmadan reaktif listeler oluşturmayı sağlar. Combine’ı UIApplication.willResignActiveNotification için NotificationCenter Publisher ile birleştirerek geliştiriciler, temsilciler ve geri çağırımlar olmadan tüm uygulama yaşam döngüsü için reaktif bir katman oluşturur. ObservableObject sınıfları için, @Published özellikleri değiştiğinde SwiftUI otomatik olarak View’i günceller — Combine, tek bir satır manuel kod olmadan tüm zinciri yönetir. Combine kodunun birim testi, ImmediateScheduler aracılığıyla Scheduler izolasyonu ile test durumlarında XCTestExpectation ve Publisher.sink aracılığıyla yapılır.

UIKit projelerinde Combine ile çalışırken geliştiriciler genellikle sink aracılığıyla abone olur ve AnyCancellable’ı bir Set’te saklar. Tipik desen: ViewController bir görünüm oluşturur, cancellables’ı saklar, ViewModel’den Publisher’a abone olur. Deinit’te, tüm abonelikler Cancellables koleksiyonu aracılığıyla otomatik olarak iptal edilir. Combine’da UIControl’ün doğru şekilde işlenmesi için publisher(for:) uzantısı aracılığıyla UIControl.Event Publisher kullanılabilir.

Combine hata ayıklaması, print() veya handleEvents() operatörü aracılığıyla yapılır. print(String) tüm olayları günlüğe kaydeder: receive subscription, request demand, receive value, receive completion. handleEvents daha ince kontrol sağlar: Publisher yaşam döngüsünün her aşaması için closure’lar belirtilebilir. Test için CombineExpectations vardır — sanal zaman ve talep kontrolü ile testlerde Publisher’ın beklenen değerleri yayıp yaymadığını kontrol etmeye olanak tanıyan bir kütüphane.

Combine Pratikte

Combine, SwiftUI’da form yönetimi için aktif olarak kullanılır: her @Published özelliği bir Publisher üretir, SwiftUI View.body aracılığıyla abone olur. combineLatest aracılığıyla birden çok Publisher’ı birleştirerek form doğrulaması bildirimsel hale gelir: her Publisher bir alanı izler, combineLatest tüm değerleri toplar, map bunları doğrular ve Submit düğmesi durumunu döndürür. Publishers.Merge, aynı türden birden çok Publisher’ı tek bir Publisher’da birleştirir — farklı kontrollerden gelen olayları tek bir akışta toplamak için yararlıdır.

Combine’ı UIKit ile entegre etmek için bir uzantı aracılığıyla UIControl Publisher kullanın: button.publisher(for: .touchUpInside) dokunmada olay yayan bir Publisher döndürür. CombineCocoa, tüm UIControl olayları, UITextView.text, UIScrollView.contentOffset için Publisher sağlayan bir topluluk kütüphanesidir. Abonelik iptalinde, cancellables deposu deinit’te temizlenir ve hiçbir aboneliğin sahibinden daha uzun yaşamamasını garanti eder. Birden çok duruma sahip UIControl için Publisher’ları bir dizide birleştirmek için Publishers.MergeMany kullanın.

Sıkça Sorulan Sorular

Combine hangi iOS sürümünden itibaren kullanılabilir?

Combine, iOS 13, macOS 10.15, tvOS 13 ve watchOS 6’dan itibaren kullanılabilir. Bu, daha eski sürümleri desteklemesi gereken projelerde kullanımını sınırlar. iOS 12 ve altı için RxSwift veya üçüncü taraf kütüphaneler kullanılır.

PassthroughSubject ve CurrentValueSubject arasındaki fark nedir?

PassthroughSubject durum depolamaz ve son değeri yeni abonelere tekrar göndermez — yalnızca gelecekteki olayları alırlar. CurrentValueSubject geçerli değeri depolar ve yeni abonelere hemen iletir. CurrentValueSubject.value, geçerli değeri senkron olarak okumaya ve yazmaya olanak tanır.

Combine SwiftUI ile nasıl entegre olur?

Combine, SwiftUI’nin temelidir: @Published bir Publisher üretir, ObservableObject objectWillChange Publisher kullanır. SwiftUI View, Combine hattı aracılığıyla @ObservedObject ve @StateObject’e otomatik olarak abone olur ve özellikler değiştiğinde View’i yeniden çizer.

Combine’da geri basınç (backpressure) nedir?

Geri basınç, veri aktarım hızını kontrol eden bir mekanizmadır. Subscriber, Subscription’a kaç değeri işlemeye hazır olduğunu (talep) bildirir. Publisher, talep edilenden fazlasını yayamaz. Bu, ağ soketlerinden gelen büyük veri akışlarıyla çalışırken kritiktir.

Combine’da hatalar nasıl işlenir?

catch operatörü bir hatayı yakalar ve Publisher’ı bir yedekle değiştirir. replaceError hatayı varsayılan bir değerle değiştirir. retry, hata durumunda belirtilen sayıda aboneliği yeniden dener. Failure durumunda çökmeleri önlemek için tüm operatörler subscribe’dan önce yerleştirilmelidir.

Özet

  • Combine — iOS 13’ten itibaren reaktif programlama için Apple’ın yerleşik framework’ü
  • Publisher — Output ve Failure ile protokol, abonelikten sonra çalışmaya başlar
  • Subscriber — talep yönetimi desteği ile receive aracılığıyla değer alır
  • Subject (PassthroughSubject, CurrentValueSubject) — manuel olay enjeksiyonu ile Publisher
  • Operatörler map, filter, combineLatest, debounce, catch — boru hatlarının temeli
  • Geri basınç talep yoluyla Subscriber arabellek taşmasını önler
  • iOS 13+ hedefleyen yeni projeler için Combine’ı seçin, eski sürüm desteği için RxSwift

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun