Combine: ano ito, mga pangunahing konsepto at Publisher kasama ang Subscriber

May-akda: IT Sectr Nai-publish: 2026-03-17 Oras ng pagbabasa: 8 min

Ang Combine ay isang reactive programming framework mula sa Apple, na ipinakilala sa iOS 13. Ayon sa Apple Documentation, 2025, nagbibigay ang Combine ng nagkakaisang declarative API para sa pagproseso ng mga asynchronous na kaganapan. Ang Publisher ay tumutukoy sa pinagmulan ng data, at ang Subscriber ay nag-subscribe upang matanggap ang mga ito.

Mga Pangunahing

  • Combine — built-in na framework ng Apple para sa reactive programming, available mula iOS 13
  • Publisher — protocol na tumutukoy sa pinagmulan ng mga halaga ng Output na may posibilidad ng error na Failure
  • Subscriber — protocol na tumatanggap ng mga halaga mula sa Publisher na may pinamamahalaang demand
  • Subject — Publisher na nagpapahintulot ng manu-manong pagpasok ng mga kaganapan (PassthroughSubject, CurrentValueSubject)
  • Operators — map, filter, combineLatest, flatMap para sa transpormasyon at pagsasama ng mga stream

Ano ang Combine?

Combine ay isang declarative Swift framework para sa pagproseso ng mga asynchronous na kaganapan sa paglipas ng panahon. Hindi tulad ng mga approach na batay sa callback, pinapayagan ng Combine ang paglalarawan ng mga pipeline ng pagproseso ng data sa pamamagitan ng isang chain ng mga operator. Ang framework ay isinama sa Foundation (URLSession, Timer, NotificationCenter) at SwiftUI (ObservableObject, @Published).

Protocol Publisher

Ang bawat uri na nagpapatupad ng protocol na Publisher ay dapat tukuyin ang Output (uri ng mga halaga) at Failure (uri ng error). Ang Publisher ay hindi aktibo hanggang sa subscription — nagsisimula itong mag-emit ng mga kaganapan pagkatapos lamang tawagan ang subscribe. Ito ay malamig na semantika, katangian ng mga reactive stream, na nagpapataas ng kahusayan.

Protocol Subscriber

Subscriber ay tumatanggap ng mga kaganapan sa pamamagitan ng tatlong pamamaraan: receive(subscription:) — kumpirmasyon ng subscription na may pamamahala ng demand; receive(_:) — pagtanggap ng bagong halaga; receive(completion:) — pagkumpleto ng stream na may tagumpay o error. Tinutukoy ng demand ang bilang ng mga halaga na handang tanggapin ng Subscriber — ito ang mekanismo ng backpressure.

Mga Built-in na Publisher

Ang Apple ay nagbibigay ng maraming built-in na Publisher: Just ay naglalabas ng isang halaga at nagtatapos, Future — asynchronous na resulta na may closure, Deferred — naantalang paglikha ng Publisher hanggang sa sandali ng subscription. Ang URLSession.dataTaskPublisher ay nagpapalit ng network request sa isang reactive stream. Ang Timer.publish ay lumilikha ng periodic timer. Ang NotificationCenter.default.publisher ay nagpapalit ng mga notification sa Publisher. Ang mga integrasyong ito ay nagpapahintulot ng subscription sa mga kaganapan nang walang manu-manong tulay.

Publisher at Subscriber sa Combine

Sa Combine, ang Publisher at Subscriber ay konektado sa pamamagitan ng protocol na Subscription. Ang Subscription ay isang nag-uugnay na bagay na kumokontrol sa daloy ng data. Ang developer ay hindi kailangang lumikha ng kanyang sariling mga uri ng Publisher — nagbibigay ang Apple ng built-in na: Just, Future, Deferred, Fail, Empty, pati na rin ang Publisher para sa URLSession at Timer.

Subject sa Combine

Subject ay isang Publisher kung saan maaaring manu-manong magpadala ng mga halaga. Ang PassthroughSubject ay hindi nag-iimbak ng estado: ang subscriber ay tumatanggap lamang ng mga kaganapan na naganap pagkatapos ng subscription. Ang CurrentValueSubject, katulad ng BehaviorRelay sa RxSwift, ay nag-iimbak ng kasalukuyang halaga at agad itong ipinapasa sa bagong subscriber.

Backpressure

Ang mekanismong backpressure sa Combine ay nag-aayos ng bilis ng paglipat ng data. Ipinapaalam ng Subscriber sa Publisher sa pamamagitan ng subscription.request(.unlimited) o subscription.request(.max(N)) kung gaano karaming halaga ang handa nitong iproseso. Pinipigilan nito ang pag-apaw ng buffer sa hindi pantay na bilis ng producer at consumer.

Mga Operator ng Combine

Ang Combine ay may kasamang higit sa 100 operator na hinati sa mga kategorya: transpormasyon (map, tryMap, flatMap), pagsala (filter, compactMap, removeDuplicates), pagsasama (combineLatest, merge, zip), pamamahala ng oras (debounce, throttle, delay) at paghawak ng error (catch, replaceError, retry).

Ang operator na combineLatest ay nagsasama ng huling mga halaga ng dalawang Publisher — sa bawat oras na ang alinman sa kanila ay naglalabas ng bagong halaga, ang closure ay tinatawag na may parehong na-update na mga halaga. Ang operator na ito ay kailangang-kailangan sa pagpapatunay ng form kung saan kailangang subaybayan ang estado ng maraming input field nang sabay-sabay.

Ang operator na debounce ay naantala ang pag-publish ng mga halaga hanggang sa lumipas ang isang tinukoy na agwat nang walang mga bagong kaganapan. Ito ay kritikal para sa mga field ng paghahanap: ang kahilingan sa server ay ipinapadala lamang pagkatapos huminto ang user sa pag-type ng 300-500 ms, na binabawasan ang load ng 5-10 beses.

Paghawak ng Error

Nag-aalok ang Combine ng ilang mga diskarte sa paghawak ng error sa antas ng operator. catch ay humaharang sa Failure at pinapalitan ang Publisher ng backup — nagpapatuloy ang stream nang walang crash. replaceError(with:) ay naglalagay ng default na halaga sa halip ng error. retry(_:) ay inuulit ang subscription nang isang tinukoy na bilang ng beses sa pagkabigo. Mahalaga: ang uri ng error na Never sa lagda ng Publisher ay ginagarantiyahan na ang stream ay hindi magtatapos sa error — pinapayagan nito ang paggamit ng Publisher sa SwiftUI nang walang paghawak ng Failure.

Mga Halimbawa ng Code ng Combine

Ang unang halimbawa ay nagpapakita ng pangunahing gawain sa Just — Publisher na naglalabas ng isang halaga at nagtatapos:

swift
let publisher = Just("Hello Combine")

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

Ang ikalawang halimbawa ay nagpapakita ng integrasyon ng Combine sa URLSession para sa network request na may pagproseso ng resulta sa pangunahing thread:

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("Error: \(error)")
        }
    }, receiveValue: { data in
        print("Data na natanggap: \(data.count)")
    })

Ang ikatlong halimbawa — paggamit ng CurrentValueSubject para sa pamamahala ng estado:

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

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

counter.send(1) // Magpapakita: Tagabilang: 1
counter.send(2) // Magpapakita: Tagabilang: 2
print(counter.value) // Magpapakita: 2

Combine vs RxSwift

Combine at RxSwift ay lumulutas ng parehong gawain — reactive programming, ngunit may iba't ibang mga approach. Ang Combine ay isang native na Apple framework na naka-embed sa system: hindi nangangailangan ng pag-install ng mga dependency, isinama sa SwiftUI at Foundation. Ang RxSwift ay isang third-party na library na may suporta para sa iOS 9+ at mas malawak na hanay ng mga operator.

Ang pagganap ng Combine ay mas mataas sa mga tipikal na sitwasyon dahil sa native na implementasyon sa C. Ang RxSwift ay nagbibigay ng mas maraming tool para sa debugging (RxSwift.Resources.total, Debug), ngunit ang object-oriented na arkitektura nito ay maaaring hindi gaanong mahusay sa malalaking stream ng data. Ang pagpili sa pagitan ng mga ito ay isang kompromiso sa pagitan ng mga kakayahan at integrasyon.

Isang mahalagang pagkakaiba — ang modelo ng backpressure. Sa Combine, pinamamahalaan ng Subscriber ang demand sa pamamagitan ng Subscription, na nagbibigay ng tahasang kontrol sa bilis ng stream. Sa RxSwift, ang backpressure ay hindi kinokontrol bilang default — ang Observable ay naglalabas ng lahat ng halaga at pinoproseso ito ng Subscriber pagdating. Para sa malalaking stream ng data, ang Combine ay mas predictable at mas ligtas sa memorya.

Ang Combine ay malalim na isinama sa SwiftUI sa antas ng wika. @Published ay lumilikha ng Publisher, ang ObservableObject ay nagbibigay ng objectWillChange Publisher. Ang SwiftUI View ay awtomatikong nag-subscribe sa mga Publisher na ito at nag-re-render sa mga pagbabago. Para sa UIKit, may mga panlabas na wrapper tulad ng CombineCocoa, ngunit ang Combine ay orihinal na idinisenyo para sa SwiftUI, kaya ang integrasyon nito sa UIKit ay nangangailangan ng karagdagang code. Ang RxSwift, sa kabaligtaran, ay may mayamang ecosystem para sa UIKit: ang RxCocoa ay nagbibigay ng reactive wrappers para sa lahat ng UI elemento.

Sinusuportahan ng Combine ang integrasyon sa Core Data sa pamamagitan ng NSFetchedResultsController Publisher. Ang Publisher ay naglalabas ng bagong data sa bawat pagbabago ng Core Data stack: pagdagdag, pagtanggal, pag-update ng mga record. Ito ay nagpapahintulot sa pagbuo ng mga reactive list nang walang manu-manong pagtawag ng reloadData. Sa pamamagitan ng pagsasama ng Combine sa NotificationCenter Publisher para sa UIApplication.willResignActiveNotification, lumilikha ang developer ng reactive layer para sa buong lifecycle ng application nang walang delegado at callback. Para sa mga klase ng ObservableObject, awtomatikong ina-update ng SwiftUI ang View kapag nagbago ang @Published na mga property — ang Combine ay nagbibigay ng buong koneksyon nang walang isang linya ng manu-manong code. Ang modular na pagsubok ng Combine code ay ginagawa sa pamamagitan ng XCTestExpectation at Publisher.sink sa mga test case na may Scheduler isolation sa pamamagitan ng ImmediateScheduler.

Kapag nagtatrabaho sa Combine sa mga proyekto ng UIKit, ang mga developer ay madalas na gumagamit ng subscription sa pamamagitan ng sink at nag-iimbak ng AnyCancellable sa Set. Ang tipikal na pattern: ang ViewController ay lumilikha ng view, nag-iimbak ng cancellables, nag-subscribe sa Publisher mula sa ViewModel. Sa deinit, ang lahat ng subscription ay awtomatikong kinakansela sa pamamagitan ng Cancellables collection. Para sa tamang paggawa sa UIControl sa Combine, maaaring gamitin ang UIControl.Event Publisher sa pamamagitan ng publisher(for:) extension.

Ang debugging ng Combine ay ginagawa sa pamamagitan ng operator na print() o handleEvents(). Ang print(String) ay nagla-log ng lahat ng kaganapan: receive subscription, request demand, receive value, receive completion. Ang handleEvents ay nagbibigay ng mas pinong kontrol: maaaring tukuyin ang mga closure para sa bawat yugto ng lifecycle ng Publisher. Para sa pagsubok ng Combine, mayroong CombineExpectations — isang library na nagpapahintulot ng pagsuri kung ang Publisher ay naglalabas ng inaasahang mga halaga sa mga pagsubok na may virtual na oras at kontrol ng demand.

Combine sa Praktika

Ang Combine ay aktibong ginagamit sa SwiftUI para sa pamamahala ng form: bawat @Published property ay lumilikha ng Publisher, ang SwiftUI ay nag-subscribe dito sa pamamagitan ng View.body. Sa pamamagitan ng pagsasama ng maraming Publisher sa pamamagitan ng combineLatest, ang pagpapatunay ng form ay nagiging declarative: bawat Publisher ay sumusubaybay sa isang field, ang combineLatest ay nangongolekta ng lahat ng halaga, sinusuri sila ng map at ibinabalik ang status ng Submit button. Ang Publishers.Merge ay nagsasama ng maraming Publisher ng parehong uri sa isa — kapaki-pakinabang para sa pagkolekta ng mga kaganapan mula sa iba't ibang mga kontrol sa iisang stream.

Para sa integrasyon ng Combine sa UIKit, gamitin ang UIControl Publisher sa pamamagitan ng extension: ang button.publisher(for: .touchUpInside) ay nagbabalik ng Publisher na naglalabas ng kaganapan kapag pinindot. Ang CombineCocoa — isang community library na nagbibigay ng Publisher para sa lahat ng UIControl na kaganapan, UITextView.text, UIScrollView.contentOffset. Sa pagkansela ng subscription, ang cancellables Store ay nililinis sa deinit, na ginagarantiyahan na walang subscription na mabubuhay nang mas mahaba kaysa sa may-ari nito. Para sa UIControl na may maraming estado, gamitin ang Publishers.MergeMany upang pagsamahin ang mga Publisher sa isang array.

Mga Madalas Itanong

Mula sa anong bersyon ng iOS available ang Combine?

Combine ay available mula iOS 13, macOS 10.15, tvOS 13 at watchOS 6. Ito ay naglilimita sa paggamit nito sa mga proyektong nangangailangan ng suporta para sa mas lumang bersyon. Para sa iOS 12 at mas mababa, ginagamit ang RxSwift o third-party na library.

Ano ang pagkakaiba ng PassthroughSubject at CurrentValueSubject?

PassthroughSubject ay hindi nag-iimbak ng estado at hindi inuulit ang huling halaga sa mga bagong subscriber — nakakatanggap lamang sila ng mga hinaharap na kaganapan. Ang CurrentValueSubject ay nag-iimbak ng kasalukuyang halaga at agad itong ipinapasa sa bagong subscriber. Ang CurrentValueSubject.value ay nagpapahintulot ng pagbasa at pagsulat ng kasalukuyang halaga nang sabay-sabay.

Paano isinasama ang Combine sa SwiftUI?

Combine ay nasa pundasyon ng SwiftUI: @Published ay lumilikha ng Publisher, ang ObservableObject ay gumagamit ng objectWillChange Publisher. Ang SwiftUI View ay awtomatikong nag-subscribe sa @ObservedObject at @StateObject sa pamamagitan ng Combine pipeline, na nagre-render ng View kapag nagbago ang mga property.

Ano ang backpressure sa Combine?

Backpressure — mekanismo ng pamamahala ng bilis ng paglipat ng data. Ipinapaalam ng Subscriber sa Subscription kung gaano karaming halaga ang handa nitong iproseso (demand). Ang Publisher ay hindi maaaring maglabas ng higit sa hiniling. Ito ay kritikal kapag nagtatrabaho sa malalaking stream ng data mula sa network sockets.

Paano hahawakan ang mga error sa Combine?

Ang operator na catch ay humaharang sa error at pinapalitan ang Publisher ng fallback. replaceError ay pinapalitan ang error ng default na halaga. retry ay inuulit ang subscription nang isang tinukoy na bilang ng beses sa error. Lahat ng operator ay dapat ilagay bago ang subscribe upang maiwasan ang crash sa Failure.

Buod

  • Combine — built-in na Apple framework para sa reactive programming mula iOS 13
  • Publisher — protocol na may Output at Failure, nagsisimula pagkatapos ng subscription
  • Subscriber — tumatanggap ng mga halaga sa pamamagitan ng receive na may suporta sa demand
  • Subject (PassthroughSubject, CurrentValueSubject) — Publisher na may manu-manong pagpasok ng kaganapan
  • Mga Operator map, filter, combineLatest, debounce, catch — pundasyon ng pipeline
  • Backpressure sa pamamagitan ng demand ay pumipigil sa pag-apaw ng buffer ng Subscriber
  • Pumili ng Combine para sa mga bagong proyekto mula iOS 13, RxSwift — para sa suporta ng lumang bersyon

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din