12/08/2018, 13:55

Giới thiệu về Reactive cocoa

Gần đây chúng ta được nghe nói nhiều về Reactive cocoa. Theo như mình hiểu thì Reactive Cocoa là một Design Patterns mới được xây dựng dựa trên các Function. Nó là sự kết hợp giữa hai phong cách lập trình. Functional Programming Reactive Programming Từ phiên bản ReactiveCocoa 2.x mang lại ...

Gần đây chúng ta được nghe nói nhiều về Reactive cocoa. Theo như mình hiểu thì Reactive Cocoa là một Design Patterns mới được xây dựng dựa trên các Function. Nó là sự kết hợp giữa hai phong cách lập trình.

  • Functional Programming
  • Reactive Programming

Từ phiên bản ReactiveCocoa 2.x mang lại một số khái niệm trìu tượng trên các tín hiệu (Signal) và đại diện là RACStream.

RACStream sẽ gửi 3 kiểu event khác nhau cho các đối tượng đã đăng kí:

  • The next event: nó cung cấp một giá trị mới sau khi thay đổi giái trị đó (có thể nil).
  • The error event: Chỉ ra lỗi xảy ra trước khi tín hiệu được hoàn thành. Sự kiện này có thể chứa một NSError cung cấp thông tin về lỗi.
  • The completed event: Tín hiệu đã kết thúc thành công.

Với RACStream được chia ra làm 2 kiểu: push-driven RACSignal và pull-driven RACSequence

  • Push-driven (RACSignal) Có nghĩa là giá trị cho các tín hiệu không được xác định tại thời điểm tạo ra tín hiệu. Nó được cập nhật tại một diểm nào đó. (ví dụ, kết quả sau khi request API, hoặc giá trị người dùng nhập vào (hoặc các thao tác người dùng) khi ứng dụng đang chạy).

  • Pull-driven (RACSequence) có nghĩa là các giá trị trong các sequence được định nghĩa tại thời điểm tạo ra tín hiệu và chúng ta có thể truy vấn từng giá trị một. Trong ReactiveCocoa sequences thường được tạo ra từ các Cocoa collections như NSArray, NSSet, NSDictionary hoặc thậm chí NSIndexSet.

Mối quan hệ qua lại giữa RACSequence <=> RACSignal.

  • RACSequence và RACSignal có thể hoán đổi cho nhau.
 RACSequence *sequence = [@[@1, @2, @3] rac_sequence];
    RACSignal *signal = [sequence signalWithScheduler:[RACScheduler mainThreadScheduler]];
RACSignal *signal = ...;
    NSArray *buffer = [signal toArray];
    RACSequence *sequence = [buffer rac_sequence];

UIKit Categories Trong ReactiveCocoa sẽ cũng cấp cho chúng ta toàn bộ các file category của các lớp trong UIKit. Ở đó có các Method khai báo các tín hiệu cho các sự kiện người dùng tạo ra các bạn có thể xem trong resource của ReactiveCocoa.

KVO observing Như chúng ta biết Signal thường được tạo bởi các block. Tuy nhiên signal cũng có thể được tạo bằng observer.

  RACSignal *signal = RACObserve(object, propertyToObserve);

Cài đặt Reactive Cocoa:

pod 'ReactiveCocoa'

Để sử dụng Reactive cocoa chúng ta import the ReactiveCocoa header :

#import <ReactiveCocoa/ReactiveCocoa.h>

Ví dụ:

[self.usernameTextField.rac_textSignal subscribeNext:^(id x) {
  NSLog(@"%@", x);
}];

2016-9-26 14:48:50.359 ViewController[9193:a0b] a
2016-9-26 14:48:50.436 ViewController[9193:a0b] al
2016-9-26 14:48:50.541 ViewController[9193:a0b] ala
2016-9-26 14:48:50.625 ViewController[9193:a0b] alad
2016-9-26 14:48:50.715 ViewController[9193:a0b] alada
2016-9-26 14:48:50.845 ViewController[9193:a0b] aladan
2016-9-26 14:48:50.955 ViewController[9193:a0b] aladanh
2016-9-26 14:48:51.025 ViewController[9193:a0b] aladanhv
2016-9-26 14:48:51.135 ViewController[9193:a0b] aladanhva
2016-9-26 14:48:51.205 ViewController[9193:a0b] aladanhvac
2016-9-26 14:48:51.295 ViewController[9193:a0b] aladanhvaca
2016-9-26 14:48:51.375 ViewController[9193:a0b] aladanhvacay
2016-9-26 14:48:51.455 ViewController[9193:a0b] aladanhvacayx
2016-9-26 14:48:51.515 ViewController[9193:a0b] aladanhvacayxi
2016-9-26 14:48:51.585 ViewController[9193:a0b] aladanhvacayxil
2016-9-26 14:48:51.665 ViewController[9193:a0b] aladanhvacayxila
2016-9-26 14:48:51.735 ViewController[9193:a0b] aladanhvacayxilan
2016-9-26 14:48:51.825 ViewController[9193:a0b] aladanhvacayxilanh

Trong đoạn code trên ta đã đăng kí theo dõi sự thay đổi của usernameTextField mỗi khi text thay đổi sẽ log chuỗi string đó ra. Nó tương đương với delegate trong UITextField

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSLog(@"%@", textField.text);
    return YES;
}

Có thể bạn dã dùng cấu trúc Reactive rồi nhưng bạn không để ý. Như một ví dụ đơn giản tôi hay làm đó là show một AlertView lên có sử dụng block.

[MTAlertView showOnView:self.view Handle:^(id object, BOOL isError) {
    // blah blah
}];

Kết Luận: Với ReactiveCocoa bạn hãy quên delegate, datasource và cả MVC mô hình mà người ta vẫn gọi là "The King of Design Patterns" đi. Trong bài sau tôi sẽ nói về Reactive cocoa và MVVM. Còn trong bài này do thời gian có hạn tôi chỉ giới thiệu qua về Reactive cocoa.

Reactive Cocoa vẫn là một phong cách lập trình mới cần có thời gian để mọi người làm quen với nó, cảm nhận đầu tiền của tôi thấy nó khá hay và đáng để bỏ thời gian ra nghiên cứu             </div>
            
            <div class=

0