Contents
Chào mừng bạn đến với Fx Studio. Đây là bài viết mở đầu cho loạt series mới của Fx Studio, đó là RxSwift. Về bản thân RxSwift thì nó không phải là mới, thậm chí giới giang hồ đã cày nát nó rồi. Và Fx Studio cũng đã ra mắt các series Combine, tương tự như RxSwift.
Nhưng với tiêu chí
Cũ người mới ta
Thì đây cũng là phần rất hay dành cho các bạn đã học xong lập trình iOS cơ bản. RxSwift cũng là cửa ngõ cho rất nhiều thứ cao cấp hơn hay hợp thời hơn sau này.
Chuẩn bị
Như đã nói ở trên, đây là phần nâng cao trong iOS. Nên yêu cầu bạn phải có một lượng kiến thức kha khá để thấu hiểu chúng. Và nếu bạn là người mới thì mình xin giới thiệu series này:
Còn nếu bạn đã biết rồi, thì cũng cần phải nắm rõ các kiến thức nền tảng sau:
Đó chỉ là những cái cơ bản mà bạn sẽ dùng rất nhiều khi tìm hiểu về RxSwift. Và bây giờ, việc đầu tiên chúng ta cần tìm hiểu đó là các khái niệm trong RxSwift hay trong họ hàng nhà Reactive Programming.
Trong phạm vi bài viết, mình sẽ không đi vào giải thích hay định nghĩa chi tiết các khái niệm. Mình sẽ tập trung vào những gì bạn cần mà thôi. Ngoài ra, các khái niệm này có rất nhiều trên mạng, bạn chỉ cần vài đường Google là oke.
1. Asynchronous Programming
Đây quả thật là cả một bầu trời kiến thức cho bạn. Trước đây, khi tìm hiểu về RxSwift, bạn sẽ nghe khái niệm Reactive Programming là nhiều hơn. Nhưng với sự ra đời của Combine, nó mang lại thêm một sắc thái mới cho họ hàng nhà Rx. Nó không còn chỉ là React đơn thuần nữa. Mà đã tiến hoá thành Lập trình bất đồng bộ.
Nó là gì?
Câu hỏi này quá khó để sử dụng ngôn ngữ tự nhiên mà giải đáp. Vì có thể mình là một dev chứ không phải một nhà văn nhà thơ. Nhưng mình có thể tóm gọn qua vài ý sau đây:
- Tất cả các phần trong chương trình của bạn hoạt động độc lập với nhau.
- Module này không chờ module kia.
- Dữ liệu nhận được sẽ quyết định trạng thái của các thành phần.
- Không thể biết trước được dữ liệu nhận được như thế nào và thời điểm nào.
…
Ví dụ để dễ hiểu thì như sau: Chương trình của bạn phát một bài hát từ Internet. Bài hát sẽ được tải từ internet về điện thoại của bạn. Lúc đó, bạn vẫn điều khiển được UI của app cho các tác vụ khác (next, back, pause ….). Mọi thứ vẫn diễn ra như cuộc sống của bạn trôi đi mỗi ngày. Nhạc thì vẫn tải, bài hát thì vẫn phát, bấm nút thì vẫn chạy …
Có một điều, nếu bạn là một lập trình viên iOS và bạn đã sử dụng chúng nó quá nhiều. Tới mức mà không hề hay biết. Tất cả đều là thuyết âm mưu mà Apple đã dày công xây dựng.
1.1. Cocoa and UIKit asynchronous APIs
Mình sẽ liệt kê ra vài thứ gắn liền với tuổi thơ lập trình iOS của bạn như sau:
- Notification Center : Dùng để lắng nghe một sự kiện xảy ra, dù đang ở bất kì đâu. Như việc ẩn hiện bàn phím, thì sẽ nhận được các thông báo trạng thái của bàn phím ảo.
- The delegate pattern : Uỷ quyền cho một đối tượng nhằm để thực hiện một hoặc nhiều hành động khác lên một đối tượng khác.
- Grand Central Dispatch : Cách đơn giản nhất để thực hiện multi-threading hoặc lập lịch cho các task.
- Closures : Giúp cho các đoạn mã có thể bay nhảy xa hơn, thoát ra khỏi luân hồi.
Và đó cũng chính là những thứ mà bạn phải nắm được trước khi bước vào thế giới RxSwift.
Quan trọng cực kì luôn đó!
Tất cả những thứ trên, khi bạn viết vào chương trình của mình, thì mới hoàn thành được 1/2 công việc. Nó chỉ mang tính chất là thiết kế sẵn, là khung xương của ứng dụng. Tuy nhiên, linh hồn của ứng dụng sẽ được quyết định bằng luồng dữ liệu. Nếu luồng dữ liệu là đồng bộ thì sẽ là đồng bộ, ngược lại là bất đồng bộ thì là bất đồng bộ.
Ví dụ: in 100 số lên màn hình với 2 cách
- Đồng bộ với việc duyệt mãng từ 1~100 và
print
ra
var array = [1, 2, 3 ... 100] for number in array { print(number) }
- Bất đồng bộ với việc không xác định thời điểm số tiếp theo được in ra
var array = [1, 2, 3 ... 100] var currentIndex = 0 @IBAction func printNext(_ sender: Any) { print(array[currentIndex]) if currentIndex < array.count { currentIndex += 1 } }
1.2. Các thuật ngữ
1.2.1. State
- Đây chính là biểu hiện dữ liệu trong ứng dụng của bạn. Từ đó tạo ra các trạng thái cho toàn bộ ứng dụng hay từng thành phần nhỏ hơn như là ViewController, ViewModel …
- Dựa vào mỗi trạng thái mà giao diện ứng dụng sẽ thay đổi theo. Nó quyết định View sẽ hiển thị gì.
- Chúng có thể truyền đi và có thể sửa đổi được.
1.2.2. Imperative programming
- Cũng khá là quen thuộc với các bạn. Chính là việc điều kiển hoặc thay đổi các trạng thái trong chương trình thông qua các câu lệnh.
- Ví dụ: Load API -> Config Data > Config UI > Update UI
- Chúng sẽ được thực hiện tuần tự.
- Điểm hạn chế lớn nhất là bạn cần phải quan tâm tới thứ tự thực hiện các lệnh này. Nếu không, thì với sự thay đổi vị trí thì dẫn đến chương trình bạn hoạt động không theo ý muốn.
1.2.3. Side effects
- Side Effect là những thay đổi phía bên ngoài của một scope (khối lệnh).
- Bạn nên biết rằng, khi bạn tác động làm thay đổi trạng thái của 1 thành phần thì không chỉ thành phần đó sẽ thay đổi. Mà có thể nó sẽ ảnh hưởng tới các thành phần khác.
- Quan trong ở đây là bạn phải kiểm soát chúng nó. Để giảm đi hoặc không cho phép các hiệu ứng khác xảy ra khi trạng thái của một thành phần nào đó thay đổi.
1.2.4. Declarative code
Đây chính là các đoạn code của bạn nhằm để cân bằng việc.
- Thay đổi các trạng thái
- Giảm đi các hiệu ứng phụ xảy ra.
Cũng chính là cách mà bạn cần phải luyện tập để hướng tới. Mọi thứ (biến, class, action …) đều được khai báo và cài đặt sẵn các hành động nếu trạng thái của chúng bị thay đổi. Thì chúng sẽ tự thay đổi theo.
1.2.5. Reactive systems
Để đảm bảo được hiệu suất tối đa thì tất cả mọi thứ phải hoạt động nhịp nhàng. Từ đó khái niệm Reactive systems được ra đời. Đơn giản là để app iOS và web có thể giao tiếp với nhau một cách nhuần nhuyễn hơn.
Các khái niệm nhỏ liên quan như sau:
- Responsive
- Resilient
- Elastic
- Message driven
(Tạm thời mình liệt kê ra như vậy và để tránh lang mang thì sẽ giải thích ở một bài khác.)
2. RxSwift
Mô tả qua vài dòng về lịch sử ra đời của nó như sau:
- Khái niệm Reactive Programming đã xuất hiện từ rất lâu rồi.
- Chủ yếu trên các nền tảng web.
- Giúp người lập trình quản lý được tốt hơn khi xử lý giao diện và logic trở nên quá nhiều.
- Reactive Extensions cho .NET (Rx), Microsoft, solving the problems of asynchronous, scalable, real time
- Rx trở thành phần mở rộng cho .Net 3.5 và .Net 4.0 thì đc build sẵn trong core
- RxJS, RxKotlin, Rx.NET, RxScala, RxSwift …
- Tất cả đều tương đồng về API
- Xem thêm tại đây : http://reactivex.io
Có 3 thành phần quan trọng cấu hình lên RxSwift.
2.1. Observables
Observables là nguồn phát dữ liệu mà có thể quan sát được từ các đối tượng khác trong chương trình. Các đối tượng của nó đều thuộc class Observable trong RxSwift.
Về khả năng:
- Cho phép tạo ra 1 chuỗi các sự kiện không đồng bộ.
- Observer lắng nghe Observable —> bất kì nắng mưa, bão tố …
Về giá trị thì nó sẽ phát ra 3 kiểu sau đây:
element
error
completed
Trong thực tế, việc phát ra các dữ liệu hay sự kiện của Observable thì có 2 trường hợp điển hình.
- Các sự kiện được diễn ra theo 1 mạch logic nhất định.
API.download(file: "http://www...") .subscribe(onNext: { data in // Append data to temporary file }, onError: { error in // Display error to user }, onCompleted: { // Use downloaded file })
Việc download sẽ hoạt động theo một trình tự được thiết kế từ trước.
- Các sự kiện lặp đi lặp lại vô hạn.
UIDevice.rx.orientation .subscribe(onNext: { current in switch current { case .landscape: // Re-arrange UI for landscape case .portrait: // Re-arrange UI for portrait }})
Ứng dụng của bạn có thể xoay bất cứ lúc nào. Nên việc xử lý này cũng lặp đi lặp lại vô hạn.
2.2. Operators
Operators gọi là toán tử, hay là các function. Những toán tử là thứ, mà bạn sẽ phải sử dụng rất nhiều trong chương trình. Nó cũng là những thứ mà tạo nên tên tuổi cho RxSwift và họ hàng nhà React.
Ví dụ: Đơn giản, để biến đổi A -> B thì bạn có thể áp dụng các toán tử cho A và kết quả nhận được là B.
Các toán tử có thể nối đuôi nhau, đầu ra của 1 toán tử này chính là đầu vào của một toán tử khác. Chúng được chia thành nhiều nhóm. Mình sẽ viết ở các bài sau.
2.3. Schedulers
- Lập lịch hay còn có thể điều khiển việc xử lý, tương tương tác ở các thread khác nhau.
- Tối ưu việc đồng bộ và bất đồng bộ trong chương trình.
- Nếu muốn hiểu sơ qua thì nó như là GCD vậy, tuy nhiên nó là phần khó và mình sẽ đề cập sau.
3. App architecture
- Với kiến trúc project thì RxSwift không gây ra ảnh hưởng nào tới project.
- Các mô hình MVC, MVP hay MVVM thì không bị thay đổi khi thêm RxSwift vào.
- Kể cả bạn thay đổi 1 function hay viết mới lại chúng thì đều không ảnh hưởng tới các phần khác
- Với môi hình MVVM thì kết hợp với RxSwift thì tăng hiệu quả hơn rất nhiều.
- Cần nắm rõ cấu trúc app hiện tại của project mình rồi sẽ quyết định triển khai RxSwift vào.
Như vậy, bạn hãy tìm hiểu RxSwift với tâm thế nó là 1 framework giúp bạn nhiều việc. Đừng ép bản thân phải thay đổi quá nhiều khi bạn muốn dùng nó. Và các bài viết sẽ dần dần giúp bạn xây dựng lên cả một lâu đài bằng RxSwift.
OKAY! Tới đây cũng là khá nhiều cho bài mở đầu về RxSwift. Nếu có góp ý gì thì hãy để lại bình luận hoặc gởi mail cho mình theo trang Contact.
- Bài viết tiếp theo tại đây.
Cảm ơn bạn đã đọc vài viết này!
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
You may also like:
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)