MVVM Tutorial with ReactiveCocoa

Part One

*MVC separates the UI into the Model that represents the application state, the View, which in turn is composed of UI controls, and a Controller that handles user interactions and updates the model accordingly.


*At the core of MVVM is the ViewModel, which is a special type of model that represents the UI state of the application. It contains that detail the state of each and every UI control.


*Rules:

1. The View has a reference to the ViewModel, but not vice-versa.

2. The ViewModel has a reference to the Model, but not vice-versa.

Advantages:

1. Lightweight Views - All your UI logic resides within the ViewModel, resulting in a very lightweight view.

2. Testing - you should be able to run your entire application without the View, greatly enhancing its testability.


*

    RAC(self.viewModel, searchText) =self.searchTextField.rac_textSignal;

You're adding the rac_textSignal property to the UITextField class by using a category within ReactiveCocoa. It's a signal that emits a next event containing the current text each time the text field updates.

The RAC marco is a binding; the above code updates the searchText property of the viewModel with the contents of each next event emitted by the rac_textSignal.


*

    RACSignal *validSearchSignal = [[RACObserve(self, searchText)map:^id(NSString *text) {

        return @(text.length >3);

    }] distinctUntilChanged];

    

    [validSearchSignal subscribeNext:^(id x) {

        NSLog(@"search text is valid %@", x);

    }];

The above code uses the RACObserve marco to create a signal from the ViewModel's searchText property (this is a ReactiveCocoa wrapper over KVO). Finally, distinctUntilChanges is used to ensure this signal only emits values when the state changes.


*RACCommand is a ReactiveCocoa concept that represents a UI action. It comprises a signal, which is the result of the UI action, and the current state, which indicates whether the action is currently being executed.


*   

    self.searchButton.rac_command = self.viewModel.executeSearch;

The rac_command property is a ReactiveCocoa addition to UIButton. The above code ensures that button taps result in the given command executing, and that the enabled state of the button reflects the enabled state of the command.

*

    RAC([UIApplicationsharedApplication],networkActivityIndicatorVisible) = self.viewModel.executeSearch.executing;

RACCommand exposes an executing property, and that's a signal that emits true and false events to indicate when the command starts and ends execution. You can use these to reflect the current command state elsewhere in your application.

*

 [self.viewModel.executeSearch.executionSignals subscribeNext:^(id x) {

        [self.searchTextField resignFirstResponder];

    }];

The executionSignals property emits the signals that generate each time the command executes. This property is a signal of signals. Whenever a new command execution signal is created and emitted, the keyboard is hidden.

*The ViewModel exposes properties that represent the UI state, it also exposes commands - and often methods - that represent UI actions. It's responsible for managing changes to the UI state based on user interactions.
However, it's not responsible for the actual business logic that executes because of these interactions. That is the job of the Model.

*The Model layer exposes a 'service' that the ViewModel consumes:
1. The Model layer exposes services and is responsible for providing business logic for the application. In this case, it provides a service to search Flickr.
2. The ViewModel layer represents the view-state of the application. It also responds to user interactions and 'events' that come from the Model layer, each of which are reflected by changes in view-state.
3. The View layer is very thin and simply provides a visualization of the ViewModel state and forwards user interactions.

*rac_signalForSelector:fromProtocol: method creates the successSignal, and it also creates signals from delegate method invocations. Each time the delegate method is invoked, a next event emits with a RACTuple that contains the method arguments.

*Are you wondering why the implementation of the signalFromAPIMethod:arguments:transform: doesn't use these macros when referencing self?
It's because the block serves as an argument to the createSignal: method, which doesn't form a strong reference between self and the block.

Part Two
*The above adds a doNext operation to the signal the search command creates when it executes. The doNext block creates the new ViewModel that displays the search results, and then pushes it via the ViewModel-services.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值