Combine big framework từ iOS 13

by TienVV8
148 views

Định nghĩa

Combine là một framework của Apple được tích hợp từ iOS 13. Combine cung cấp các API cho phép khai báo để xử lý các giá trị theo thời gian. Các giá trị này có thể đại diện cho nhiều loại sự kiện không đồng bộ. Combine cung cấp các Publishers hiển thị các giá trị có thể thay đổi theo thời gian và subscribers nhận các giá trị đó từ Publishers.

Reactive có nghĩa là lập trình với các luồng giá trị không đồng bộ. Các bạn có thể tìm hiểu thêm về Reactive ở đây

Functional programming là tất cả các chức năng trong lập trình. Trong Swift, các hàm có thể được truyền dưới dạng đối số cho các hàm khác, được trả về từ các hàm, được lưu trữ trong các biến và cấu trúc dữ liệu và được xây dựng trong thời gian chạy dưới dạng bao đóng.

Trong style của declarative, bạn mô tả những gì chương trình thực hiện mà không mô tả luồng điều khiển. Theo style imperative, bạn viết cách thức hoạt động của chương trình bằng cách triển khai và xử lý một loạt tác vụ. Các chương trình imperative chủ yếu dựa vào trạng thái, thường được sửa đổi bằng các bài tập.

Lập trình với Combine là sự kết hợp của declarative, reactive và functional. Nó liên quan đến các chức năng xâu chuỗi và chuyển các giá trị từ cái này sang cái khác. Điều này tạo ra các luồng giá trị, chảy từ đầu vào đến đầu ra.

Lý thuyết là vậy, nhưng nếu chúng ta bỏ qua hết các định nghĩa thì Combine được thể hiện đơn giản như hình ảnh bên dưới đây:

Và thệm trí có thể ngắn gọn hơn:
Combine = Publishers + Subscribers + Operators

Đến đây có vẻ chúng ta đã hiểu được Combine là gì rồi nhỉ, Tiếp tục đi đến các thành phần khác trong combine nhé.

Publisher là gì?

Publisher là gửi chuỗi giá trị theo thời gian đến một hoặc nhiều subscribers

Combine publishers được tuân thủ theo protocol sau:


Một publisher có thể gửi giá trị hoặc terminate với thành công hoặc lỗi. Output xác định loại giá trị mà publisher có thể gửi. Failure xác định loại lỗi mà nó có thể thất bại.

Mothod receive(subscriber:) kết nối subscriber với publisher. Nó xác định hợp đồng: đầu ra của publisher phải khớp với đầu vào của subscriber và các loại lỗi cũng vậy.

Subscriber là gì?

Subscriber là để nhận các giá trị từ Publisher



Một subscriber có thể nhận nhận giá trị với type Input hoặc termination với thành công hoặc lỗi

các mothods receice mô tả các bước khác nhau trong vòng đời của người đăng ký. Chúng ta sẽ tìm hiểu vòng đời của subscriber này ở phần tiếp theo nhé!

Kết nối Publisher với Subscriber

Combine có hai methods được tích hợp sẵn: Subscribers.Sink và Subscribers.Assign. Bạn có thể kết nối chúng bằng cách gọi một trong hai method này bên dưới publisher

  • Sink(receiveCompletion:receiveValue:) để xử lý phần tử mới hoặc sự kiện hoàn thành trong một lần đóng.
  • assign(to:on:) để ghi phần tử mới vào một thuộc tính.


1. Tạo ra một publisher Just gửi một signle giá trị và sau đó hoàn thành. Combine sẵn một số built-in trong đó có Just
2. Kết nối publisher với subscriber bằng method sink

Kết quả in ra lần lượt là:

1
finished

Sau khi send 1 thì publisher tự động kết thúc, ở đây chúng ta không xử lý bất kì error nào, bởi vì Just không bao giờ thật bại.

Subjects là gì?

Subject là một lại publisher đặc biệt, nó có thể insert giá trị, truyền được giá trị từ bên ngoài vào. Giao diện của Subject cung cấp ba cách khác nhau để gửi các elements



Combine có hai chủ thể tích hợp sẵn: PassthroughSubject và CurrentValueSubject.

Bắt đầu với PassthroughSubject


1. Tạo ra một passthrough subject. Chúng ta set Failure type là Never để cho nó biết rằng nó luôn kết thúc thành công.
2. Đăng ký subject(hay nhớ rằng đó vẫn là một publisher).
3. Gửi hai giá trị tới luồng và sau đó hoàn thành nó.

Kết quả lần lượt như sau:

Hello,
World!
finished

Tiếp theo mình đi đến CurrentValueSubject


1. Tạo ra một subject với giá trị khởi tạo là 1
2. In ra giá trị hiện tại
3. Cập nhật giá trị hiện tại thành 2 và in nó ra
4. Đăng ký publisher

Kết quả lần lượt như sau:

1
2
2

Combine Publisher and Subscriber Life Cycle

Như đề cập ở bên trên, bây giờ chúng ta cùng tìm hiểu về life cycle của Publisher và Subscriber nhé!!!

Sự kết nối giữ Publisher và Subscriber được gọi là subscription. Thông qua các bước của kết nối như vậy xác định vòng đời của Publisher và Subscriber


Để ý đến operator print(_:to:) ở trên. Nó in ra các thông báo cho tất cả các sự kiện của Publisher vào console, từ các log được in ra thì chúng ta cũng có thể nắm được một phần nào đó về vòng đời của Publisher và Subscriber. Đây là log được ghi nhận từ console

Từ log bên trên chúng ta đã có manh mối về vòng đời của publisher-subscriber. Với log ghi được, chúng ta sẽ đi phân tích từ đầu đến cuối nhé

1. Subscriber kết nối với Publisher bằng cách gọi subscribe(S).

2. Tạo một đăng ký tới Publisher bằng cách gọi receive(subscriber: S) trên chính nó.

3. Publisher nhận yêu cầu đăng ký. Nó gọi receive(subscription:) trong subscriber

4. Subscriber đăng ký một phần tử mà nó muốn nhận, Nó gọi đến request(:) và chuyển Request dưới dạng tham số. Nhu cầu xác định số lượng mục mà publisher có thể gửi cho subsriber thông qua subscription. Trong trường hợp này thì nhu cầu là không giới hạn (unlimited)

5. Publisher gửi giá trị thông bằng cách gọi receive(_:) trên subscriber. Method này trả về một Demand, cho biết có bao nhiêu items mà subscriber mong muốn nhận được. Subscriber chỉ có thể tăng demand hoặc để nguyên, không thể giảm demand đi

6. Kết thúc đăng ký với một trong những kết quả sau đây:
– Cancelled Điều này có thể tự động xảy ra khi publisher được giải phóng, được hiển thị trong ví dụ bên trên. Một cách khác là hủy thủ công: token.cancel().
– Finish thành công
– Fail với một error.

Chaining Publishers với Operators

Operators là các methods đặc biệt được gọi bên dưới Publisher và trả ra một Publisher khác. Điều này cho phép áp dụng chúng một cách lần lượt, tạo ra một chuỗi. Mỗi operator đều biến đổi publisher cũ và được trả ra từ chính publisher cũ đó.

Một operator đều tạo mới một publisher. Sau đó, các operators có thể áp dụng lần lượt. Mỗi operator nhận được được tạo ra từ publisher trước đó trong chỗi. Ở đây mình đề cập đến thứ tự tương đối của opetator là ngược dòng, nghĩa là operator liền trước và tiếp theo.

Bây giờ chúng ta cùng nhau đến một ví dụ thông qua đó có thể xem cách xâu chuỗi operators khi xử lý request HTTP URL với Combine



1. Tạo một request để tải kho GitHub. Mình đang sử dụng API GitHub REST.
2. Combine được tích hợp tốt vào Swift system frameworks và SDK iOS. Điều này cho phép chúng ta sử dụng publisher để xử lý các tác vụ dữ liệu URLSession.
3. Truyền dữ liệu phản hồi. Chúng ta sử dụng toán tử map(_:), biến đổi giá trị ngược dòng từ (data: Data, response: URLResponse) thành Data.
4. Decode nội dung phản hồi bằng JSONDecoder.
5. Kết nối sink subscriber. Nó in số lượng kho lưu trữ đã nhận và hoàn thành.

Và đây là kết quả:

V8tr has 30 repositories
finished

Thông qua bài này mình đã giới thiệu Combine đến các bạn
Mình hi vọng bài viết có thể giúp ích được cho các bạn. Chúc các bạn thành công!

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.