[iOS development] Summary of the use of ReactiveObjC (RAC)


quote

RAC refers to RactiveCocoa, an open source framework on Github, which can help us provide a lot of convenient event handling solutions, allowing us to handle events more simply and rudely. Now it is divided into ReactiveObjC and ReactiveSwift. The functions of the two frameworks are similar. It is written in OC, so record the usage of ReactiveObjC.


pod 'ReactiveObjC', '~> 3.0.0'

https://github.com/ReactiveCocoa/ReactiveObjC

1. RACSignal signal
/* create signal */
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

    /* send signal */
    [subscriber sendNext:@"send signal"];

    return nil;
}];

/* Subscribe to signals */
RACDisposable *disposable = [signal subscribeNext:^(id  _Nullable x) {

    NSLog(@"Signal content: %@", x);
}];

/* unsubscribe*/
[disposable dispose];


2. The RACSubject

signal is similar to the usage of the proxy and is usually used to replace the proxy. With it, it is unnecessary to define the proxy.
/* create signal */
RACSubject *subject = [RACSubject subject];

/* send signal */
[subject sendNext:@"send signal"];

/* Subscribe to signals (usually subscribed in other view controllers, similar to the usage of delegates) */
[subject subscribeNext:^(id  _Nullable x) {

    NSLog(@"Signal content: %@", x);
}];


3. RACTuple ancestor

The ancestor of RAC is actually the same as our OC array. It is actually an array that encapsulates our OC.
/* create tuple */
RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil];

/* Get content from another array */
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"1", @"2", @"3", @"4", @"5"]];

/* Use RAC macros to quickly encapsulate */
RACTuple *tuple = RACTuplePack(@"1", @"2", @"3", @"4", @"5");

NSLog(@"Get the content of the ancestor: %@", tuple[0]);
NSLog(@"The first element: %@", [tuple first]);
NSLog(@"The last element: %@", [tuple last]);


4. Convenience of Array arrays and Dictionary dictionaries

You can omit the use of for loops to traverse.
/* loop through the array */
NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
[array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {

    NSLog(@"Array content: %@", x); // x can be any object
}];

/* iterate over the dictionary */
NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
[dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) {

    RACTupleUnpack(NSString *key, NSString *value) = x; // x is a tuple, this macro can unpack key and value
    NSLog(@"dictionary content: %@:%@", key, value);
}];


The following two methods are to replace all the contents of the array with 0. The first one is a single operation, and the second one is to replace all at once. Neither method will change the contents of the original array, and a new one will be generated after the operation. Arrays, eliminating the need to create a mutable array and then traverse out the individual additions.
/* Content manipulation */
NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
NSArray *newArray = [[array.rac_sequence map:^id _Nullable(id  _Nullable value) {

    NSLog(@"Array content: %@", value);

    return @"0"; // replace everything with 0

}] array];

/* Content quick replacement */
NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
NSArray *newArray = [[array.rac_sequence mapReplace:@"0"] array]; // replace everything with 0

5. Monitor the input changes of the TextField You

can save the steps of setting the delegate and implementing the proxy method.
/* Listen to the input of the TextField (it will be called when the content changes) */
[[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
    NSLog(@"Input box content: %@", x);
}];

/* Add listener condition */
[[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
    return value.length > 5; // Indicates that the following block will only be called when the length of the input text is > 5
}] subscribeNext:^(NSString * _Nullable x) {
     NSLog(@"Input box content: %@", x);
}];

6. Listening to the Button click event

can save the steps of adding events and creating methods to addTarget.
[[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
    NSLog(@"%@ button was clicked", x); // x is the button button object
}];

7. Real-time monitoring of the status of the login button

The following means that the login button can be clicked only when the contents of the user name and password input boxes are greater than 0, and the status is monitored in real time, and this function can be completed with a single code.
RAC(_loginButton, enabled) = [RACSignal combineLatest:@[_username.rac_textSignal, _password.rac_textSignal] reduce:^id _Nullable(NSString * username, NSString * password){
    return @(username.length && password.length);
}];

8. Listening to Notification notification events The steps of clearing the notification and listening to the notification creation method in -(void)dealloc {}

can be omitted.
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
    NSLog(@"%@Keyboard up", x); // x is the notification object
}];

9. Instead of the delegate method, the steps of monitoring and setting the delegate can be

omitted . The following means that as long as the btnClick method is executed in the view, a signal will be sent to execute the callback.
[[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
    NSLog(@"The button in the view was clicked");
}];

10. Replacing KVO

monitoring Instead of KVO monitoring, the following means to convert the change of the frame attribute of the monitoring view into a signal, as long as the value changes, the signal will be sent.
[[view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id  _Nullable x) {
    NSLog(@"property change: %@", x); // x is the result of monitoring the property change
}];

There is also a simpler way of writing, which is to use the RAC macro, which has the same effect as the above.
[RACObserve(view, frame) subscribeNext:^(id  _Nullable x) {
    NSLog(@"property change: %@", x); // x is the result of monitoring the property change
}];

11. Instead of NSTimer Timer

can be used instead of NSTimer.
@interface ViewController ()

@property (nonatomic, strong) RACDisposable *disposable;

@end

/* Define the timer listener */
self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {

    NSLog(@"Current time: %@", x); // x is the current system time

    /* close the timer */
    [_disposable dispose];
}];


Continue to update, learn new knowledge and record it, you can collect it if you need it.
In the future, you will definitely be grateful to yourself who is working hard now, and hope that the development road of yourself and your readers will be infinitely better.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326224760&siteId=291194637