Combine — iOS 13-də təqdim edilmiş Apple-dan reaktiv proqramlaşdırma framework-udur. Apple Documentation, 2025-a görə, Combine asinxron hadisələrin işlənməsi üçün vahid deklarativ API təmin edir. Publisher məlumat mənbəyini müəyyənləşdirir, Subscriber isə onları qəbul etmək üçün abunə olur.
Başlıca
Combine — zamanla asinxron hadisələrin işlənməsi üçün deklarativ Swift framework-u. Callback yanaşmalarından fərqli olaraq, Combine operatorlar zənciri vasitəsilə məlumat emal boru kəmərlərini təsvir etməyə imkan verir. Framework Foundation (URLSession, Timer, NotificationCenter) və SwiftUI (ObservableObject, @Published) ilə inteqrasiya edilmişdir.
Publisher protokolunu tətbiq edən hər bir tip Output (dəyərlərin növü) və Failure (xətanın növü) müəyyənləşdirməlidir. Publisher abunə olana qədər aktiv deyil — subscribe çağırıldıqdan sonra hadisələri yaymağa başlayır. Bu, reaktiv axınlar üçün xarakterik olan və səmərəliliyi artıran soyuq semantikadır.
Subscriber hadisələri üç metod vasitəsilə qəbul edir: receive(subscription:) — demand idarəsi ilə abunəliyin təsdiqi; receive(_:) — yeni dəyərin qəbulu; receive(completion:) — axının uğur və ya xəta ilə başa çatması. Demand Subscriber-in qəbul etməyə hazır olduğu dəyərlərin sayını müəyyənləşdirir — bu backpressure mexanizmidir.
Apple çoxsaylı daxili Publisher təmin edir: Just bir dəyər yayır və başa çatır, Future — bağlayıcı ilə asinxron nəticə, Deferred — abunə anına qədər təxirə salınmış Publisher yaradılması. URLSession.dataTaskPublisher şəbəkə sorğusunu reaktiv axına çevirir. Timer.publish dövri taymer yaradır. NotificationCenter.default.publisher bildirişləri Publisher-ə çevirir. Bu inteqrasiyalar əl ilə körpü qurmadan hadisələrə abunə olmağa imkan verir.
Combine-də Publisher və Subscriber Subscription protokolu ilə bağlıdır. Subscription məlumat axınını idarə edən birləşdirici obyektdir. Tərtibatçı öz Publisher növlərini yaratmalı deyil — Apple daxili Just, Future, Deferred, Fail, Empty, həmçinin URLSession və Timer üçün Publisher təmin edir.
Subject — içinə əl ilə dəyərlər göndərilə bilən Publisher. PassthroughSubject vəziyyəti saxlamır: abunəçi yalnız abunədən sonra baş verən hadisələri alır. RxSwift-dəki BehaviorRelay-a bənzər CurrentValueSubject cari dəyəri saxlayır və dərhal yeni abunəçiyə ötürür.
Combine-də backpressure mexanizmi məlumat ötürülmə sürətini tənzimləyir. Subscriber subscription.request(.unlimited) vɘ subscription.request(.max(N)) vasitəsilə Publisher-ə neçə dəyər emal etməyə hazır olduğunu bildirir. Bu, istehsalçı və istehlakçının qeyri-bərabər sürətində buferin daşmasının qarşısını alır.
Combine kateqoriyalara bölünmüş 100-dən çox operator ehtiva edir: transformasiya (map, tryMap, flatMap), filtrləmə (filter, compactMap, removeDuplicates), birləşdirmə (combineLatest, merge, zip), zaman idarəsi (debounce, throttle, delay) və xəta emalı (catch, replaceError, retry).
combineLatest operatoru iki Publisher-in son dəyərlərini birləşdirir — hər dəfə onlardan hər hansısi yeni dəyər yaydıqda, bağlayıcı hər iki yenilənmiş dəyərlə çağırılır. Bu operator eyni anda bir neçe giriş sahəsinin vəziyyətini izləmək lazım olan formaların validasiyasında əvəzolunmazdır.
debounce operatoru yeni hadisələr olmadan müəyyən edilmiş interval keçənə qədər dəyərlərin nəşrinə gecikdirir. Bu axtarış sətirləri üçün kritik əhəmiyyət daşıyır: istifadəçi 300-500 ms yazmağı dayandırdıqdan sonra serverə sorğu göndərilir, bu da yükü 5-10 dəfə azaldır.
Combine operatorlar səviyyəsində bir neçe xəta emalı strategiyası təklif edir. catch Failure-i tətikləyir və Publisher-i ehtiyatla əvəz edir — axın çökmədən davam edir. replaceError(with:) xəta əvəzinə standart dəyər qoyur. retry(_:) uğursuzluqda abunəliyi müəyyən edilmiş sayda təkrarlayır. Vacibdir: Publisher-in imzasındakı Never xəta növü axının heç vaxt xəta ilə bitməyəcəyinə zəmanət verir — bu, Publisher-dən SwiftUI-də Failure emalı olmadan istifadə etməyə imkan verir.
Birinci nümunə Just — bir dəyər yayıb başa çatan Publisher ilə əsas işi göstərir:
let publisher = Just("Hello Combine")
publisher
.sink(receiveCompletion: { completion in
print("Tamamlandı: \(completion)")
}, receiveValue: { value in
print("Alındı: \(value)")
})
İkinci nümunə Combine-in URLSession ilə şəbəkə sorğu üçün inteqrasiyasını nümayiş etdirir və nəticənin əsas iplikdə emalını göstərir:
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("Xəta: \(error)")
}
}, receiveValue: { data in
print("Məlumat alındı: \(data.count)")
})
Üçüncü nümunə — vəziyyətin idarə edilməsi üçün CurrentValueSubject istifadəsi:
let counter = CurrentValueSubject<Int, Never>(0)
counter
.sink { value in
print("Sayıcı: \(value)")
}
counter.send(1) // Göstərəcək: Sayıcı: 1
counter.send(2) // Göstərəcək: Sayıcı: 2
print(counter.value) // Göstərəcək: 2
Combine və RxSwift eyni vəzifəni — reaktiv proqramlaşdırmanı həll edir, lakin fərqli yanaşmalarla. Combine sistemə daxil edilmiş yerli Apple framework-udur: asılılıqların quraşdırılmasını tələb etmir, SwiftUI və Foundation ilə inteqrasiya olunub. RxSwift iOS 9+ dəstəyi və daha geniş operator dəsti ilə üçüncü tərəf kitabxanasıdır.
Combine-in performansı C-də yerli tətbiq sayəsində tipik ssenarilərdə daha yüksəkdir. RxSwift daha çox debug vasitəsi təmin edir (RxSwift.Resources.total, Debug), lakin onun obyekt-yönümlü arxitekturası böyük məlumat axınlarında daha az səmərəli ola bilər. Onların arasında seçim imkanlar və inteqrasiya arasında kompromisdir.
Əhəmiyyətli fərq — backpressure modeli. Combine-də Subscriber Subscription vasitəsilə demand-i idarə edir, bu da axın sürəti üzərində açıq nəzarət verir. RxSwift-də backpressure standart olaraq idarə olunmur — Observable bütün dəyərləri yayır, Subscriber isə onları gəldikcə emal edir. Böyük məlumat axınları üçün Combine daha proqnozlaşdırıla bilən və yaddaş baxımından təhlükəsizdir.
Combine dil səviyyəsində SwiftUI ilə dərindən inteqrasiya olunub. @Published Publisher yaradır, ObservableObject objectWillChange Publisher təmin edir. SwiftUI View avtomatik olaraq bu Publisher-lərə abunə olur və dəyişikliklərdə yenidən çəkilir. UIKit üçün CombineCocoa kimi üçüncü tərəf örtüklər var, lakin Combine əslində SwiftUI üçün tərtib edilmişdir, buna görə də onun UIKit ilə inteqrasiyası əlavə kod tələb edir. RxSwift isə UIKit üçün zəngin ekosistemə malikdir: RxCocoa bütün UI elementləri üçün reaktiv örtüklər təmin edir.
Combine Core Data ilə NSFetchedResultsController Publisher vasitəsilə inteqrasiyanı dəstəkləyir. Publisher Core Data yığınındakı hər dəyişiklikdə — əlavə etmə, silmə, yeniləmə — yeni məlumatlar yayır. Bu, əl ilə reloadData çağırmadan reaktiv siyahılar qurmağa imkan verir. Combine-i UIApplication.willResignActiveNotification üçün NotificationCenter Publisher ilə birləşdirərək, tərtibatçı deleqatlar və callback-lər olmadan tətbiqin bütün həyat dövürü üçün reaktiv təbəqə yaradır. ObservableObject sinifləri üçün SwiftUI @Published xüsusiyyətləri dəyişərkən View-i avtomatik yeniləyir — Combine əl ilə yazılmış bir sətir kod olmadan bütün əlaqəni təmin edir. Combine kodunun modul testi XCTestExpectation və Publisher.sink vasitəsilə ImmediateScheduler ilə Scheduler izolyasiyası ilə test hallarında aparılır.
UIKit layihələrində Combine ilə işləyərkən, tərtibatçılar tez-tez sink vasitəsilə abunəlikdən istifadə edir və AnyCancellable-ı Set-də saxlayır. Tipik naxş: ViewController görünüş yaradır, cancellables saxlayır, ViewModel-dən Publisher-ə abunə olur. Deinit zamanı bütün abunəliklər Cancellables kolleksiyası vasitəsilə avtomatik ləğv edilir. Combine-də UIControl ilə düzgün iş üçün publisher(for:) genişləndirməsi vasitəsilə UIControl.Event Publisher istifadə edilə bilər.
Combine-in debug edilməsi print() və ya handleEvents() operatoru vasitəsilə həyata keçirilir. print(String) bütün hadisələri qeyd edir: receive subscription, request demand, receive value, receive completion. handleEvents daha incə nəzarət verir: Publisher-in həyat dövürünün hər mərhələsi üçün bağlayıcılar təyin edilə bilər. Combine testi üçün CombineExpectations mövcuddur — virtual vaxt və demand nəzarəti ilə testlərdə Publisher-in gözlənilən dəyərləri yaydığını yoxlamağa imkan verən kitabxana.
Combine SwiftUI-də formaların idarə edilməsi üçün aktiv istifadə olunur: hər @Published xassəsi Publisher yaradır, SwiftUI View.body vasitəsilə ona abunə olur. Bir neçe Publisher-i combineLatest vasitəsilə birləşdirərək, formanın validasiyası deklarativ olur: hər Publisher bir sahəni izləyir, combineLatest bütün dəyərləri toplayır, map onları yoxlayır və Submit düməsinin statusunu qaytarır. Publishers.Merge eyni tipli bir neçe Publisher-i birinə birləşdirir — müxtəlif idarəetmə elementlərindən hadisələri vahid axında toplamaq üçün faydalıdır.
Combine-i UIKit ilə inteqrasiya etmək üçün genişləndirmə vasitəsilə UIControl Publisher istifadə edin: button.publisher(for: .touchUpInside) basıldıqda hadisə yayan Publisher qaytarır. CombineCocoa — bütün UIControl hadisələri, UITextView.text, UIScrollView.contentOffset üçün Publisher təmin edən icma kitabxanasıdır. Abunəlikdən çıxarkən cancellables Store deinit-də təmizlənir, heç bir abunəliyin sahibindən çox yaşamamasına zəmanət verir. Çox vəziyyətli UIControl üçün Publishers.MergeMany-dən istifadə edərək Publisher-ləri massivdə birləşdirin.
Tez-tez verilən suallar
Combine iOS 13, macOS 10.15, tvOS 13 və watchOS 6-dan etibarən mövcuddur. Bu, köhnə versiyaları dəstəkləməyi tələb edən layihələrdə istifadəsini məhdudlaşdırır. iOS 12 və aşağı üçün RxSwift və ya üçüncü tərəf kitabxanalar tətbiq olunur.
PassthroughSubject vəziyyəti saxlamır və son dəyəri yeni abunəçilərə təkrarlamır — onlar yalnız gələcək hadisələri alırlar. CurrentValueSubject cari dəyəri saxlayır və dərhal yeni abunəçiyə ötürür. CurrentValueSubject.value cari dəyəri sinxron oxumağa və yazmağa imkan verir.
Combine SwiftUI-nin əsasındadır: @Published Publisher yaradır, ObservableObject objectWillChange Publisher-dən istifadə edir. SwiftUI View avtomatik olaraq @ObservedObject və @StateObject-ə Combine boru kəməri vasitəsilə abunə olur və xassələr dəyişərkən View-i yenidən çəkir.
Backpressure — məlumat ötürülmə sürətini idarə etmə mexanizmi. Subscriber Subscription-a neçə dəyər emal etməyə hazır olduğunu bildirir (demand). Publisher tələb ediləndən çox yaya bilməz. Bu, şəbəkə soketlərindən böyük məlumat axınları ilə işləyərkən kritikdir.
catch operatoru xətanı tətikləyir və Publisher-i ehtiyatla əvəz edir. replaceError xətanı standart dəyərlə əvəz edir. retry xəta zamanı abunəliyi müəyyən sayda təkrarlayır. Bütün operatorlar subscribe-dən əvvəl yerləşdirilməlidir ki, Failure zamanı çökmə baş verməsin.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun