RxSwift — τι είναι, δυνατότητες και αντιδραστικός προγραμματισμός

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-03 Χρόνος ανάγνωσης: 10 λεπ

RxSwift — είναι μια βιβλιοθήκη αντιδραστικού προγραμματισμού για iOS, που υλοποιεί το μοτίβο Observable και λειτουργικούς τελεστές για εργασία με ασύγχρονες ροές δεδομένων. Μεταφέρει τις έννοιες του ReactiveX (Rx) στη γλώσσα Swift, παρέχοντας ένα ενοποιημένο API για την επεξεργασία συμβάντων από το UI, δικτυακά αιτήματα, βάσεις δεδομένων και χρονοδιακόπτες. Σύμφωνα με στοιχεία του ReactiveX, 2025, η βιβλιοθήκη χρησιμοποιείται σε περισσότερα από 60.000 έργα στο GitHub και παραμένει το πρότυπο αντιδραστικού προγραμματισμού για Swift μέχρι την εμφάνιση του native Combine. Το RxSwift αντικαθιστά τα delegate, τα closures και τις ειδοποιήσεις με μια ενιαία αλυσίδα επεξεργασίας συμβάντων.

Κύρια σημεία

  • RxSwift — υλοποίηση του ReactiveX για Swift, βασισμένη στο μοτίβο Observable και αλυσίδες τελεστών
  • Observable — πηγή ασύγχρονων συμβάντων που μπορεί να ολοκληρωθεί επιτυχώς, με σφάλμα ή ατέρμονα
  • Subject — υβρίδιο Observable και Observer, που επιτρέπει τη μη αυτόματη αποστολή συμβάντων στη ροή
  • Schedulers διαχειρίζονται σε ποιο νήμα εκτελείται η εγγραφή, η παρατήρηση και η επεξεργασία συμβάντων
  • Τελεστές map, flatMap, filter, combineLatest μετασχηματίζουν και συνδυάζουν ροές χωρίς συνθήκες ανταγωνισμού

Τι είναι το RxSwift;

RxSwift — είναι η Swift-μεταφορά της βιβλιοθήκης ReactiveX (Rx), που δημιουργήθηκε από τη Microsoft για .NET το 2012. Η βασική ιδέα του Rx είναι να παρουσιάζει οποιαδήποτε ασύγχρονη πηγή δεδομένων ως Observable ακολουθία, στην οποία μπορούν να εφαρμοστούν λειτουργικοί τελεστές. Στην ανάπτυξη iOS, το RxSwift χρησιμοποιείται για τη σύνδεση UI-συμβάντων (πατήματα κουμπιών, εισαγωγή κειμένου, χειρονομίες) με τη λογική της εφαρμογής χωρίς ρητά delegate και target-action.

Η βιβλιοθήκη αποτελείται από τρεις ενότητες: RxSwift (πυρήνας — Observable, Operator, Scheduler), RxCocoa (ενσωμάτωση με UIKit — rx-επεκτάσεις για UIButton, UITextField, UITableView) και RxRelay (Subject χωρίς τερματικά συμβάντα). Αυτός ο διαχωρισμός επιτρέπει τη χρήση του πυρήνα σε server-side Swift και δοκιμές, συνδέοντας τη UI-υποδομή μόνο για εφαρμογές iOS.

Σύμφωνα με έρευνα του Stack Overflow, 2025, το RxSwift βρίσκεται στην κορυφαία 5 πιο χρησιμοποιούμενων τρίτων βιβλιοθηκών για iOS. Ο κύριος λόγος δημοτικότητας είναι η ομοιόμορφη επεξεργασία όλων των ασύγχρονων μοτίβων: δικτυακά αιτήματα μέσω URLSession, κινούμενα σχέδια μέσω UIViewPropertyAnimator, ειδοποιήσεις μέσω NotificationCenter και delegate μέσω DelegateProxy — όλα συνοψίζονται σε Observable με προβλέψιμο κύκλο ζωής.

Φιλοσοφία του αντιδραστικού προγραμματισμού

Αντιδραστικός προγραμματισμός — είναι ένα παράδειγμα στο οποίο το πρόγραμμα αντιδρά σε αλλαγές δεδομένων, αντί να τα ελέγχει περιοδικά. Αντί να γράφει κανείς “λήψη δεδομένων → επεξεργασία → ενημέρωση UI”, ο προγραμματιστής περιγράφει μια αλυσίδα μετασχηματισμών: “όταν αλλάξουν τα δεδομένα, εφάρμοσε φίλτρο, μετά map, μετά ενημέρωσε το UI”. Το RxSwift υλοποιεί αυτό το παράδειγμα μέσω Observable αλυσίδων με τεμπέλη εκτέλεση — τίποτα δεν συμβαίνει μέχρι να εμφανιστεί ένας συνδρομητής.

Βασικά στοιχεία του RxSwift: Observable, Subject, Disposable

Observable — ο θεμελιώδης τύπος του RxSwift, που αντιπροσωπεύει μια ακολουθία συμβάντων στο χρόνο. Το Observable μπορεί να στείλει τρεις τύπους συμβάντων: next (νέα τιμή), error (σφάλμα που τερματίζει τη ροή) και completed (επιτυχής ολοκλήρωση). Υπάρχουν finite Observable (τερματίζονται μετά την αποστολή όλων των τιμών) και infinite Observable (π.χ. UI-συμβάντα — δεν τερματίζονται ποτέ).

Κύκλος ζωής του Observable

Κύκλος ζωής του Observable περιλαμβάνει τρία στάδια: δημιουργία (create, just, from), μετασχηματισμός (τελεστές map, filter, flatMap) και εγγραφή (subscribe). Χωρίς εγγραφή, το Observable δεν εκτελεί καμία ενέργεια — είναι μια τεμπέλη ακολουθία. Μετά την εγγραφή, το Observable αρχίζει να στέλνει συμβάντα στον συνδρομητή μέχρι να ολοκληρωθεί ή ο συνδρομητής να ακυρώσει την εγγραφή μέσω Disposable.

swift
import RxSwift

// Δημιουργία Observable από πίνακα
let numbers = Observable.from([1, 2, 3, 4, 5])

// Μετασχηματισμός μέσω τελεστών
let squared = numbers
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }

// Εγγραφή με επεξεργασία συμβάντων
let disposable = squared
    .subscribe(onNext: { print($0) },
               onError: { print("Error: \($0)") },
               onCompleted: { print("Ολοκληρώθηκε") })

Subject — είναι ένας τύπος που είναι ταυτόχρονα Observable (μπορεί κανείς να εγγραφεί σε αυτόν) και Observer (μπορεί κανείς να στείλει συμβάντα σε αυτόν). Το RxSwift παρέχει τέσσερις τύπους Subject: PublishSubject (μόνο νέα συμβάντα), BehaviorSubject (με αρχική τιμή), ReplaySubject (προσωρινή αποθήκευση των τελευταίων N συμβάντων) και AsyncSubject (μόνο η τελευταία τιμή πριν τον τερματισμό). Το Subject είναι χρήσιμο για την ενσωμάτωση επιτακτικού κώδικα (closures, delegate) σε μια αντιδραστική αλυσίδα.

Disposable — είναι ένα κουπόνι ακύρωσης εγγραφής. Όταν ο συνδρομητής δεν θέλει πλέον να λαμβάνει συμβάντα, καλεί το disposable.dispose(). Στην πράξη χρησιμοποιείται το DisposeBag: μια συλλογή από Disposable που ακυρώνει αυτόματα όλες τις εγγραφές κατά την αποδέσμευση του κατόχου (π.χ. UIViewController). Αυτό αποτρέπει διαρροές μνήμης, αναπόφευκτες με μη αυτόματη διαχείριση εγγραφών.

Τύπος SubjectΑρχική τιμήΕπαναλαμβάνει στον συνδρομητήΧρήση
PublishSubjectΌχιΜόνο νέα συμβάνταUI-συμβάντα, σπάνιες ειδοποιήσεις
BehaviorSubjectΝαιΤελευταίο + νέαΚατάσταση, ροή δεδομένων
ReplaySubjectΌχιΠροσωρινή μνήμη N + νέαΠροσωρινή αποθήκευση ιστορικού
AsyncSubjectΌχιΜόνο το τελευταίοΥπολογιστικές εργασίες
PublishRelayΌχιΜόνο νέαΧωρίς error/completed

Τελεστές μετασχηματισμού και φιλτραρίσματος ροών

Τελεστές του RxSwift — είναι συναρτήσεις που λαμβάνουν ένα Observable και επιστρέφουν ένα άλλο Observable, μετασχηματίζοντας τη ροή δεδομένων. Συνδυάζοντας τελεστές, ο προγραμματιστής δημιουργεί δηλωτικές αλυσίδες επεξεργασίας χωρίς ενδιάμεσες μεταβλητές και συνθήκες ανταγωνισμού. Όλοι οι τελεστές είναι τεμπέληδες: η αλυσίδα δημιουργείται κατά την περιγραφή και εκτελείται κατά την εγγραφή.

Τελεστές μετασχηματισμού αλλάζουν κάθε συμβάν στη ροή. Το map εφαρμόζει μια συνάρτηση σε κάθε στοιχείο, το flatMap ξεδιπλώνει το Observable από κάθε στοιχείο σε μια επίπεδη ροή, το scan συσσωρεύει ένα ενδιάμεσο αποτέλεσμα (ανάλογο του reduce, αλλά με εκπομπή κάθε βήματος). Το buffer ομαδοποιεί στοιχεία ανά χρόνο ή ποσότητα, το window διαιρεί τη ροή σε ένθετα Observable ανά παράθυρα.

swift
// Παράδειγμα αλυσίδας τελεστών: αναζήτηση με debounce
searchTextField.rx.text
    .orEmpty
    .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
    .distinctUntilChanged()
    .flatMapLatest { query -> Observable<[String]> in
        return apiService.search(query)
    }
    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { _, item, cell in
        cell.textLabel?.text = item
    }
    .disposed(by: disposeBag)

Τελεστές φιλτραρίσματος επιτρέπουν μόνο τα συμβάντα που ικανοποιούν μια συνθήκη. Το filter αποκλείει βάσει κατηγορήματος, το distinctUntilChanged επιτρέπει μόνο τιμές διαφορετικές από την προηγούμενη, τα take και takeWhile περιορίζουν τον αριθμό συμβάντων. Τα skip και skipWhile παραλείπουν τα πρώτα N συμβάντα ή συμβάντα μέχρι να εκπληρωθεί μια συνθήκη. Για διαχείριση σφαλμάτων χρησιμοποιούνται catchError (αναχαίτιση και αντικατάσταση) και retry (επανάληψη ακολουθίας σε περίπτωση σφάλματος).

Τελεστές συνδυασμού ενώνουν πολλά Observable σε ένα. Το combineLatest συνδυάζει τις τελευταίες τιμές από πολλές ροές σε μια πλειάδα, το zip συνδυάζει ζεύγη στοιχείων με ίδιους δείκτες, το merge ενώνει πολλές ροές σε μία με τη σειρά άφιξης συμβάντων. Το withLatestFrom συνδυάζει ένα συμβάν από την κύρια ροή με την τελευταία τιμή από άλλη ροή — χρήσιμο για UI-συμβάντα με τρέχουσα κατάσταση.

ΚατηγορίαΤελεστήςΤι κάνει
ΜετασχηματισμόςmapΜετατρέπει κάθε τιμή μέσω συνάρτησης
ΜετασχηματισμόςflatMapΞεδιπλώνει ένθετα Observable σε επίπεδη ροή
ΦιλτράρισμαfilterΕπιτρέπει τιμές βάσει κατηγορήματος
ΦιλτράρισμαdistinctUntilChangedΕπιτρέπει μόνο τιμές που άλλαξαν
ΣυνδυασμόςcombineLatestΣυνδυάζει τελευταίες τιμές από 2+ ροές
ΣυνδυασμόςzipΣυνδυάζει ζεύγη στοιχείων ανά δείκτη
ΔιαχείρισηdebounceΚαθυστερεί συμβάντα μέχρι παύση στη ροή
ΔιαχείρισηtakeΛαμβάνει τα πρώτα N συμβάντα και τερματίζει

Schedulers και διαχείριση νημάτων εκτέλεσης

Scheduler στο RxSwift — είναι μια αφαίρεση πάνω από ένα νήμα εκτέλεσης (ή ουρά). Ο Scheduler καθορίζει σε ποιο νήμα εκτελείται η δημιουργία συμβάντων, ο μετασχηματισμός και η εγγραφή. Σε αντίθεση με το GCD, όπου ο προγραμματιστής καθορίζει ρητά το DispatchQueue, το RxSwift χρησιμοποιεί δύο παραμέτρους: subscribeOn (σε ποιο νήμα εκτελείται το Observable) και observeOn (σε ποιο νήμα καλείται ο συνδρομητής).

MainScheduler και BackgroundScheduler

MainScheduler εκτελεί κώδικα στο κύριο νήμα — είναι υποχρεωτικό για ενημέρωση του UIKit (όλες οι UI-αλλαγές πρέπει να γίνονται στο main thread). Το SerialDispatchQueueScheduler τυλίγει μια σειριακή GCD-ουρά, το ConcurrentDispatchQueueScheduler — μια παράλληλη. Για εργασίες παρασκηνίου χρησιμοποιείται ConcurrentDispatchQueueScheduler με qos: .background ή .utility.

swift
// Τυπικό μοτίβο: εργασία στο παρασκήνιο + UI στο main
apiService.fetchData()
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { data in
        self.tableView.reloadData()
        self.loadingIndicator.stopAnimating()
    })
    .disposed(by: disposeBag)

Η σωστή χρήση του Scheduler αποτρέπει το μπλοκάρισμα του UI κατά τη διάρκεια δικτυακών αιτημάτων και βαρέων υπολογισμών. Το subscribeOn επηρεάζει ολόκληρο το upstream (όλοι οι τελεστές πριν από το observeOn εκτελούνται στον καθορισμένο προγραμματιστή). Το observeOn αλλάζει το downstream — όλοι οι τελεστές μετά το observeOn εκτελούνται στον καθορισμένο προγραμματιστή. Μπορεί να υπάρχουν πολλά observeOn στην αλυσίδα για εναλλαγή μεταξύ νημάτων σε διαφορετικά στάδια μετασχηματισμού.

SerialDispatchQueueScheduler εγγυάται σειριακή επεξεργασία συμβάντων, πράγμα σημαντικό για τη νηματοασφάλεια κοινών πόρων. Για λειτουργίες υψηλού φόρτου (επεξεργασία εικόνων, ανάλυση JSON) χρησιμοποιήστε ConcurrentDispatchQueueScheduler — το RxSwift διατηρεί τη σειρά συμβάντων εντός ενός Observable, αλλά διαφορετικά Observable μπορούν να υποστούν επεξεργασία παράλληλα.

Πρακτική εφαρμογή του RxSwift σε iOS

RxSwift σε έργα iOS χρησιμοποιείται συχνότερα για τη σύνδεση UI με δεδομένα μέσω αντιδραστικών αλυσίδων. Το RxCocoa παρέχει rx-επεκτάσεις για όλα τα τυπικά UIKit-στοιχεία: rx.tap για UIButton, rx.text για UITextField, rx.selectedRow για UIPickerView. Αυτό επιτρέπει την αντικατάσταση των @IBAction και delegate με δηλωτικές εγγραφές.

RxSwift σε συνδυασμό με MVVM

MVVM (Model-View-ViewModel) — αρχιτεκτονικό μοτίβο όπου το ViewModel διαχειρίζεται την κατάσταση και την επιχειρηματική λογική, ενώ το View εγγράφεται σε αντιδραστικές ιδιότητες του ViewModel. Το RxSwift ταιριάζει απόλυτα στο MVVM: το ViewModel δημοσιεύει Observable ή Driver για δεδομένα, το View εγγράφεται σε αυτά μέσω bind. Το ViewModel δεν έχει αναφορά στο View — επιστρέφει Observable που το View καταναλώνει.

swift
class LoginViewModel {
    let email = BehaviorRelay<String>(value: "")
    let password = BehaviorRelay<String>(value: "")

    var isFormValid: Observable<Bool> {
        return Observable
            .combineLatest(email, password) {
                !$0.isEmpty && $0.contains("@") && $1.count >= 6
            }
    }
}

// Στο ViewController:
viewModel.isFormValid
    .bind(to: loginButton.rx.isEnabled)
    .disposed(by: disposeBag)

Τα δικτυακά αιτήματα — είναι ο δεύτερος πιο συχνός τομέας εφαρμογής του RxSwift. Το URLSession.rx.response τυλίγει ένα HTTP-αίτημα σε Observable, το οποίο επιστρέφει (response, data) σε επιτυχία ή error σε αποτυχία. Σε συνδυασμό με Codable και τον τελεστή map προκύπτει ένα συμπαγές αντιδραστικό επίπεδο API: Observable χωρίς callbacks και διαχείριση σφαλμάτων σε κάθε μέθοδο. Σε περίπτωση σφάλματος δικτύου, ο τελεστής retry(3) επαναλαμβάνει αυτόματα το αίτημα τρεις φορές με εκθετική καθυστέρηση.

RxSwift vs Combine

Combine — είναι ένα native πλαίσιο της Apple, που παρουσιάστηκε στο iOS 13. Επιλύει τα ίδια προβλήματα με το RxSwift: εργασία με ασύγχρονα συμβάντα μέσω Publisher, Subscriber και τελεστών. Ωστόσο, το Combine έχει βασικές διαφορές: αυστηρή τυποποίηση σφαλμάτων μέσω τύπου Failure, ενσωματωμένη υποστήριξη Swift Concurrency (async/await) και ενσωμάτωση με SwiftUI μέσω @Published και ObservableObject.

RxSwift υπερέχει σε συμβατότητα προς τα πίσω — υποστηρίζει iOS 8+, ενώ το Combine απαιτεί iOS 13+. Το RxSwift έχει μια πιο πλούσια οικοσύστημα τρίτων επεκτάσεων (RxDataSources, RxGesture, RxAnimated) και λεπτομερή τεκμηρίωση τελεστών. Για έργα με υποστήριξη παλαιότερων εκδόσεων iOS, το RxSwift παραμένει η μόνη επιλογή.

Για νέα έργα με iOS 13+, η Apple συνιστά το Combine. Είναι στενά ενσωματωμένο με SwiftUI, έχει μικρότερο μέγεθος δυαδικού αρχείου και επίσημη υποστήριξη. Ωστόσο, η μετεγκατάσταση υπάρχοντος RxSwift-κώδικα στο Combine απαιτεί επανεγγραφή όλων των Observable → Publisher, και το οικοσύστημα του RxCocoa δεν έχει πλήρες Combine-ανάλογο — το UIKit δεν διαθέτει native [Publisher] για όλα τα UI-στοιχεία.

ΧαρακτηριστικόRxSwiftCombine
Ελάχιστη iOSiOS 8+iOS 13+
Τύπος σφάλματοςError (οποιοδήποτε)Generic Failure
UI-επεκτάσειςRxCocoa (UIKit, AppKit)@Published (SwiftUI)
Τελεστές400+ τελεστές~100 τελεστές
Swift ConcurrencyΜέσω γέφυραςNative υποστήριξη
ΚατάστασηΤρίτη πλευράΕπίσημο από Apple

Συχνές ερωτήσεις

Ποια είναι η διαφορά μεταξύ Observable και Subject στο RxSwift;

Observable — πηγή συμβάντων με τεμπέλη εκτέλεση. Το Subject είναι ταυτόχρονα Observable και Observer — μπορείτε να εγγραφείτε σε αυτό και να στέλνετε νέα συμβάντα χειροκίνητα. Το Subject είναι χρήσιμο για την ενσωμάτωση επιτακτικού κώδικα σε αντιδραστικές αλυσίδες.

Πότε να χρησιμοποιώ RxSwift αντί για Combine;

RxSwift επιλέγεται όταν απαιτείται υποστήριξη iOS 11-12, όταν υπάρχει υπάρχουσα βάση κώδικα RxSwift ή όταν χρειάζεται πλούσιο οικοσύστημα τελεστών (400+ έναντι ~100 στο Combine). Για νέα έργα σε iOS 13+ προτιμάται το Combine.

Τι είναι το DisposeBag και γιατί χρειάζεται;

DisposeBag — συλλογή από Disposable κουπόνια, που ακυρώνει αυτόματα όλες τις εγγραφές κατά την αποδέσμευση του κατόχου. Χωρίς DisposeBag, η εγγραφή δημιουργεί strong reference στο closure, οδηγώντας σε διαρροή μνήμης κατά την καταστροφή του UIViewController.

Πώς γίνεται η διαχείριση σφαλμάτων στο RxSwift;

Χρησιμοποιήστε catchError για αντικατάσταση σφάλματος με προεπιλεγμένη τιμή, retry για επανάληψη του Observable, materialize για μετατροπή σφάλματος σε συμβάν. Στο UI-επίπεδο, τα Driver και Signal δεν μεταδίδουν σφάλματα — αντιμετωπίζονται εσωτερικά.

Σε τι διαφέρει το Driver από το Observable στο RxCocoa;

Driver — είναι ένας ειδικός τύπος Observable που εγγυάται εκτέλεση στο MainScheduler, απουσία σφαλμάτων και κοινή χρήση πόρων. Το Driver εγγυάται ότι οι UI-ενημερώσεις γίνονται στο κύριο νήμα. Το Observable δεν παρέχει τέτοιες εγγυήσεις — απαιτείται observeOn.

Συμπεράσματα

  • RxSwift — βιβλιοθήκη αντιδραστικού προγραμματισμού για iOS, που υλοποιεί το μοτίβο Observable και 400+ τελεστές μετασχηματισμού
  • Observable, Subject, Disposable — τρεις θεμελιώδεις τύποι που αποτελούν τη βάση όλων των αντιδραστικών αλυσίδων
  • Τελεστές map, flatMap, filter, combineLatest, debounce επιτρέπουν τη δημιουργία δηλωτικών αλυσίδων χωρίς συνθήκες ανταγωνισμού
  • Schedulers (subscribeOn / observeOn) διαχειρίζονται τα νήματα εκτέλεσης, αποτρέποντας το μπλοκάρισμα του UI
  • RxCocoa παρέχει rx-επεκτάσεις για UIKit, αντικαθιστώντας delegate και target-action με αντιδραστικές εγγραφές
  • Combine — native εναλλακτική από την Apple για iOS 13+, αλλά το RxSwift παραμένει σχετικό για παλαιότερες εκδόσεις

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης