RxSwift คือไลบรารีการเขียนโปรแกรมแบบรีแอคทีฟสำหรับ Swift ที่ใช้รูปแบบ Observable ตามข้อมูลจาก ReactiveX, 2025 นี่คือการนำ Reactive Extensions ไปใช้ที่ได้รับความนิยมมากที่สุดสำหรับระบบนิเวศของ Apple Observable ทำหน้าที่เป็นแหล่งของเหตุการณ์ ในขณะที่ Observer สมัครสมาชิกเพื่อรับเหตุการณ์เหล่านั้น
ประเด็นสำคัญ
RxSwift คือไลบรารีการเขียนโปรแกรมแบบรีแอคทีฟสำหรับภาษา Swift ที่พอร์ตมาจาก Reactive Extensions (Rx) ช่วยให้สามารถอธิบายโปรแกรมแบบอะซิงโครนัสและขับเคลื่อนด้วยเหตุการณ์ผ่าน Observable Sequence — ลำดับของข้อมูลที่พร้อมใช้งานในช่วงเวลา นักพัฒนา iOS ใช้ RxSwift สำหรับจัดการคำขอเครือข่าย เหตุการณ์ UI และข้อมูลสตรีมมิงโดยไม่ต้องใช้ callback ที่ซ้อนกัน
พื้นฐานของ RxSwift ประกอบด้วยโปรโตคอลหลักสองตัว: ObservableType — แหล่งของเหตุการณ์ที่สามารถส่งสัญญาณสามประเภท: .next(value), .error(error) และ .completed Observer สมัครสมาชิก Observable ผ่านเมธอด subscribe และรับเหตุการณ์เหล่านี้ โมเดลนี้เรียกว่า Reactive Streams และรับประกันว่าไม่มีเหตุการณ์สูญหายเมื่อสมัครสมาชิกอย่างถูกต้อง
RxSwift มี โอเปอเรเตอร์มากกว่า 300 ตัว สำหรับทำงานกับสตรีม: map แปลงแต่ละเหตุการณ์ filter ให้ผ่านเฉพาะเหตุการณ์ที่ตรงกัน flatMap คลาย Observable ที่ซ้อนกันเป็นสตรีมเดียว โอเปอเรเตอร์ถูกเชื่อมโยงเป็นลูกโซ่ สร้างไปป์ไลน์การประมวลผลข้อมูลแบบประกาศโดยไม่มีผลข้างเคียง
นอกจาก Observable พื้นฐานแล้ว RxSwift ยังมีประเภท wrapper เฉพาะทาง Single ส่งค่าเพียงค่าเดียวหรือข้อผิดพลาด — เหมาะสำหรับคำขอ HTTP Completable เสร็จสมบูรณ์ด้วยความสำเร็จหรือล้มเหลวโดยไม่มีค่า — สำหรับการดำเนินการเขียน Maybe รวมทั้งสองสถานการณ์: สามารถเสร็จสมบูรณ์ด้วยค่า ไม่มีค่า หรือมีข้อผิดพลาด Traits เหล่านี้ทำให้ความหมายง่ายขึ้นและทำให้โค้ดสามารถอธิบายตัวเองได้
การเขียนโปรแกรมแบบรีแอคทีฟใน RxSwift สร้างขึ้นบนรูปแบบ Observer ObservableSequence คล้ายกับ Sequence จากไลบรารีมาตรฐาน แต่มีการเข้าถึงองค์ประกอบแบบอะซิงโครนัส สตรีมเหตุการณ์ถูกส่งผ่านลูกโซ่ของโอเปอเรเตอร์ แต่ละตัวส่งคืน ObservableSequence ใหม่โดยไม่เปลี่ยนแปลงต้นฉบับ
โอเปอเรเตอร์ใน RxSwift คือฟังก์ชันบริสุทธิ์ที่รับ ObservableSequence หนึ่งตัวและส่งคืนตัวใหม่ ตัวอย่างเช่น map สร้างลำดับใหม่โดยใช้การแปลงกับแต่ละองค์ประกอบ การรวมโอเปอเรเตอร์เข้าด้วยกัน นักพัฒนาสร้างไปป์ไลน์ที่ข้อมูลผ่านทุกขั้นตอนการประมวลผลโดยไม่มีตัวแปรกลาง
Schedulers คือการทำให้เป็นนามธรรมเหนือเธรดการทำงานใน RxSwift Scheduler กำหนดว่าโค้ดจะทำงานบนเธรดใด: MainScheduler — เธรด UI, SerialDispatchQueueScheduler — คิวพื้นหลัง โอเปอเรเตอร์ subscribeOn และ observeOn ระบุว่างานทำที่ไหนและประมวลผลผลลัพธ์ที่ไหนตามลำดับ
RxSwift ประกอบด้วยประเภทพื้นฐานหลายประเภท แต่ละประเภทแก้ปัญหาของตัวเองในไปป์ไลน์แบบรีแอคทีฟ Single คือ Observable ที่ส่งค่าเพียงค่าเดียวหรือข้อผิดพลาด สะดวกสำหรับคำขอเครือข่าย Completable เสร็จสมบูรณ์ด้วยความสำเร็จหรือล้มเหลวโดยไม่มีค่า Maybe รวมคุณสมบัติของ Single และ Completable
Subject คือ Observable ร้อนที่ทำหน้าที่เป็น Observer ด้วย PublishSubject ส่งเฉพาะเหตุการณ์ใหม่ให้สมาชิก BehaviorSubject — เหตุการณ์ล่าสุดบวกเหตุการณ์ใหม่ Relay คือรูปแบบหนึ่งของ Subject ที่ไม่ส่ง .error หรือ .completed ทำให้มั่นใจในความต่อเนื่องของสตรีม BehaviorRelay เก็บค่าปัจจุบันและเหมาะสำหรับ UI ที่ขับเคลื่อนด้วยสถานะ
DisposeBag คือชุดรวมของ Disposable ที่ยกเลิกการสมัครสมาชิกทั้งหมดโดยอัตโนมัติเมื่อมีการจัดสรรหน่วยความจำใหม่ ใน iOS DisposeBag มักถูกเพิ่มใน UIViewController หรือ UIView เมื่อหน้าจอปิด DisposeBag จะถูกล้าง — ป้องกันการรั่วไหลของหน่วยความจำและการเข้าถึงองค์ประกอบ UI ที่ไม่มีอยู่
ด้านล่างเป็นตัวอย่างการสร้าง Observable จากอาร์เรย์ของข้อมูลโดยใช้โอเปอเรเตอร์ map เพื่อแปลงสตริง:
let observable = Observable.of("Swift", "RxSwift", "Reactive")
observable
.map { $0.uppercased() }
.subscribe(onNext: { value in
print("Received: \(value)")
})
.disposed(by: disposeBag)
ตัวอย่างที่สองแสดงการรวมคำขอเครือข่ายสองคำขอโดยใช้ zip — โอเปอเรเตอร์รอจนกว่า Observable ทั้งสองจะส่งค่าและรวมผลลัพธ์เป็น tuple:
let first = fetchUser(id: "123")
let second = fetchPosts(userId: "123")
Observable
.zip(first, second)
.observe(on: MainScheduler.instance)
.subscribe(onNext: { user, posts in
updateUI(user: user, posts: posts)
})
.disposed(by: disposeBag)
ตัวอย่างที่สามแสดงการใช้ BehaviorRelay เพื่อเก็บสถานะและอัปเดต UI โดยอัตโนมัติเมื่อมีการเปลี่ยนแปลง: การเปลี่ยนแปลง state.accept() แต่ละครั้งจะถูกส่งไปยังสมาชิกทันที ซึ่งเหมาะสำหรับรูปแบบสถานะในสถาปัตยกรรม MVVM
let state = BehaviorRelay(value: "idle")
state
.subscribe(onNext: { status in
print("Status: \(status)")
})
.disposed(by: disposeBag)
state.accept("loading") // Prints: Status: loading
RxSwift แตกต่างจากวิธีการแบบอะซิงโครนัสแบบดั้งเดิม (Delegation, NotificationCenter, Callback) ตรงที่มีลักษณะเป็นประกาศและสามารถประกอบกันได้ ต่างจาก Combine ที่ RxSwift รองรับ iOS 9+ และมีโอเปอเรเตอร์มากกว่า อย่างไรก็ตาม Combine ถูกรวมเข้ากับ Foundation และ SwiftUI ในระดับภาษา ทำให้ได้เปรียบในโครงการ Apple ใหม่
ข้อได้เปรียบหลักของ RxSwift เหนือ GCD (Grand Central Dispatch) คือความสามารถในการรวมและแปลงสตรีมข้อมูลในระดับนามธรรม แทนที่จะจัดการคิวด้วยตนเอง อย่างไรก็ตาม RxSwift ต้องการการเรียนรู้แนวคิดรีแอคทีฟ ซึ่งเพิ่มอุปสรรคในการเข้าสำหรับทีม
ในทางปฏิบัติ RxSwift ถูกใช้ในโครงการขนาดใหญ่ที่ลูกโซ่รีแอคทีฟเชื่อมต่อเหตุการณ์ UI ตรรกะทางธุรกิจ และการโต้ตอบเครือข่ายในไปป์ไลน์เดียว ตัวอย่างเช่น ในแอปพลิเคชันเทรดดิ้ง สตรีมราคาจะถูกประมวลผลผ่าน RxSwift: ticks มาจาก WebSocket ผ่านการกรอง ถูกจัดกลุ่มตามกรอบเวลา และแสดงบนกราฟแบบเรียลไทม์ สถานการณ์นี้ยากที่จะนำไปใช้ผ่าน Delegation หรือ NotificationCenter โดยไม่สูญเสียความสามารถในการอ่าน
ทางเลือกของ RxSwift ได้แก่ Combine (iOS 13+), AsyncSequence จาก Swift Concurrency (iOS 15+) รวมถึงไลบรารีของบริษัทอื่น เช่น ReactiveSwift ที่ไม่ผูกติดกับแพลตฟอร์ม Apple การเลือกขึ้นอยู่กับเวอร์ชัน iOS ขั้นต่ำที่รองรับและประสบการณ์ของนักพัฒนา สำหรับโครงการ iOS 15+ ใหม่ ทีมมักเลือก AsyncSequence — ไม่ต้องติดตั้งไลบรารีและใช้โครงสร้างภาษา Swift ดั้งเดิม
รูปแบบสถาปัตยกรรมกับ RxSwift มักเป็นไปตาม MVVM หรือ Clean Architecture ViewModel มีตรรกะทางธุรกิจทั้งหมดเป็นลูกโซ่ Observable View สมัครสมาชิกข้อมูลที่แปลงแล้ว รูปแบบ Input-Output แยกเหตุการณ์นำเข้า (แตะ, ป้อนข้อความ) จากสถานะส่งออก (ข้อความปุ่ม, การมองเห็น loader) วิธีการนี้ทำให้การทดสอบง่ายขึ้น: ViewModel ถูกทดสอบโดยไม่มี UI ผ่าน Schedulers เสมือน
RxSwift เหมาะสำหรับทั้งโครงการขนาดเล็กที่มีไม่กี่หน้าจอและแอปพลิเคชันระดับองค์กรขนาดใหญ่ที่มีโมดูลนับสิบ ในโครงการขนาดใหญ่ ลูกโซ่รีแอคทีฟแผ่ซ่านทั่วสถาปัตยกรรม: จากการสังเกต UserDefaults ผ่าน RxProperty ไปจนถึงคำขอเครือข่ายผ่าน Moya (wrapper RxSwift บน Alamofire) แต่ละโมดูลถูกแยกและสื่อสารผ่านอินเทอร์เฟสรีแอคทีฟ ซึ่งทำให้การเปลี่ยนการนำไปใช้ทำได้ง่ายโดยไม่ต้องเปลี่ยนสมาชิก ด้วยสถาปัตยกรรมที่เหมาะสม RxSwift ช่วยลดปริมาณโค้ดเมื่อเทียบกับวิธีดั้งเดิม เนื่องจากไม่ต้องเขียนโค้ดสำเร็จรูปสำหรับ KVO, Target-Action หรือ NotificationCenter
RxSwift ถูกใช้อย่างแข็งขันในโครงการที่มี RxDataSources — ไลบรารีสำหรับการทำงานแบบรีแอคทีฟกับ UITableView และ UICollectionView RxDataSources คำนวณความแตกต่างระหว่างชุดเซลล์เก่าและใหม่โดยอัตโนมัติ และใช้การเปลี่ยนแปลงแบบเคลื่อนไหว ช่วยให้นักพัฒนาไม่ต้องทำงานด้วยตนเองกับ beginUpdates/endUpdates และกำจัดข้อขัดข้องเนื่องจากข้อมูลไม่สอดคล้องกัน
สำหรับการดีบักลูกโซ่ RxSwift มีโอเปอเรเตอร์ debug() — มันบันทึกทุกเหตุการณ์: subscribe, next, error, completed, dispose เป็นเครื่องมือที่ขาดไม่ได้เมื่อพัฒนาไปป์ไลน์รีแอคทีฟที่ซับซ้อน debug(String) รับตัวระบุที่ปรากฏในบันทึก สำหรับการทำโปรไฟล์หน่วยความจำ RxSwift.Resources.total แสดงจำนวน Observable และ Disposable ที่ทำงานอยู่ในแอปพลิเคชัน — ช่วยระบุการรั่วไหลเมื่อ DisposeBag ไม่ถูกล้างหรือ retain cycle เก็บการสมัครสมาชิกไว้ โอเปอเรเตอร์เพิ่มเติม takeUntil(self.rx.deallocated) ยกเลิกการสมัครสมาชิกโดยอัตโนมัติเมื่อมีการจัดสรรหน่วยความจำของวัตถุ — นี่คืออีกชั้นหนึ่งของการป้องกันการรั่วไหล
เมื่อเขียนโค้ด RxSwift สิ่งสำคัญคือต้องปฏิบัติตามหลักการ หนึ่ง Observable ต่อการสมัครสมาชิก: ViewController แต่ละตัวไม่ควรสร้างการสมัครสมาชิกมากกว่าหนึ่งครั้งสำหรับ Observable เดียวกัน — ซึ่งช่วยลดความเสี่ยงของ race condition สำหรับการจดจำ Observable ใช้โอเปอเรเตอร์ share() ซึ่งเปลี่ยน Observable เย็นเป็นร้อนด้วยบัฟเฟอร์ replay ขนาด 1 เมื่อทำงานกับทรัพยากรที่ใช้ร่วมกัน ให้ใช้ connect() เพื่อควบคุมการเริ่มส่ง — รับประกันว่าสมาชิกทั้งหมดเชื่อมต่อก่อนเหตุการณ์แรก
การทดสอบโค้ด RxSwift ทำผ่าน TestScheduler — Scheduler เสมือนที่ช่วยให้จัดการเวลาได้ testScheduler.createHotObservable(values) สร้าง Observable ที่มีลำดับเหตุการณ์ที่กำหนดไว้ล่วงหน้าตามเวลาเสมือน testScheduler.start() เริ่มการประมวลผล TestScheduler ช่วยให้สามารถตรวจสอบลำดับและ timestamp เสมือนของเหตุการณ์โดยไม่มีความล่าช้าจริง ทำให้การทดสอบรวดเร็วและแน่นอน
คำถามที่พบบ่อย
Observable คือแหล่งเย็น: มันจะไม่ส่งเหตุการณ์จนกว่าจะมีการสมัครสมาชิก Subject คือแหล่งร้อน: มันส่งเหตุการณ์โดยไม่คำนึงถึงสมาชิกและอนุญาตให้แทรกค่าด้วยตนเองผ่าน onNext PublishSubject ส่งเฉพาะเหตุการณ์ใหม่ BehaviorSubject — เหตุการณ์ล่าสุดบวกเหตุการณ์ใหม่
DisposeBag เก็บการสมัครสมาชิก Disposable ทั้งหมด เมื่อ DisposeBag ถูกจัดสรรหน่วยความจำใหม่ (เช่น เมื่อปิด ViewController) การสมัครสมาชิกที่เก็บไว้ทั้งหมดจะถูกยกเลิกโดยอัตโนมัติ รับประกันว่า Observable จะไม่ส่งเหตุการณ์ไปยังวัตถุ UI ที่ถูกทำลาย
หากเวอร์ชัน iOS ขั้นต่ำคือ 13+ และทีมรู้จัก SwiftUI — เลือก Combine หากโปรเจกต์รองรับ iOS 12 และต่ำกว่าหรือต้องการโอเปอเรเตอร์มากกว่า — เลือก RxSwift Combine มีการรวมที่ดีกว่ากับ Foundation (URLSession, Timer, NotificationCenter)
Schedulers ทำให้เธรดการทำงานเป็นนามธรรม subscribeOn ระบุว่า Scheduler ใดดำเนินการสมัครสมาชิก (โดยปกติพื้นหลัง) observeOn กำหนด Scheduler ที่รับเหตุการณ์ (ส่วนใหญ่ MainScheduler สำหรับการอัปเดต UI) SerialDispatchQueueScheduler ทำงานผ่าน GCD
ได้ RxSwift สามารถรวมกับ SwiftUI ผ่าน ObservableObject ใช้ BehaviorRelay เป็นคุณสมบัติ @Published: การสมัครสมาชิก Relay จะกระจายการเปลี่ยนแปลงไปยัง Combine และ SwiftUI จะวาด View ใหม่ผ่าน @ObservedObject นี่เป็นรูปแบบการย้ายจาก UIKit ไปยัง SwiftUI ที่ได้รับความนิยม
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม