原文地址:http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1
As an iOS developer,nearly every line of code you write is in reaction to someevent; a button tap,a received network message,a property change (via Key Value Observing) or a change in user’s location via CoreLocation are all good examples. However,theseeventsare all encoded in different ways; as actions,delegates,KVO,callbacks and others.ReactiveCocoadefines a standard interface forevents,so they can be more easily chained,filtered and composed using a basic set of tools.
Sound confusing? Intriguing? … Mind blowing? Then read on :]
ReactiveCocoa combines a couple of programming styles:
- Functional Programmingwhich makes use of higher order functions,i.e. functions which take other functions as their arguments
- Reactive Programmingwhich focuses of data-flows and change propagation
For this reason,you might hear ReactiveCocoa described as a Functional Reactive Programming (or FRP) framework.
Rest assured,that is as academic as this tutorial is going to get! Programming paradigms are a fascinating subject,but the rest of this ReactiveCocoa tutorials focuses solely on the practical value,with work-through examples instead of academic theories.
The Reactive Playground
Throughout this ReactiveCocoa tutorial,you’ll be introducing reactive programming to a very simple example application,the ReactivePlayground. Download thestarter project,then build and run to verify you have everything set up correctly.
ReactivePlayground is a very simple app that presents a sign-in screen to the user. Supply the correct credentials,which are,somewhat imaginatively,userfor the username,andpasswordfor the password,and you’ll be greeted by a picture of a lovely little kitten.
Awww! How cute!
Right now it’s a good point to spend a little time looking through the code of this starter project. It is quite simple,so it shouldn’t take long.
OpenRWViewController.mand take a look around. How quickly can you identify the condition that results in the enabling of theSign Inbutton? What are the rules for showing / hiding thesignInFailure
label? In this relatively simple example,it might take only a minute or two to answer these questions. For a more complex example,you should be able to see how this same type of analysis might take quite a bit longer.
With the use of ReactiveCocoa,the underlying intent of the application will become a lot clearer. It’s time to get started!
Adding the ReactiveCocoa Framework
The easiest way to add the ReactiveCocoa framework to your project is viaCocoaPods. If you’ve never used CocoaPods before it might make sense to follow theIntroduction To CocoaPodstutorial on this site,or at the very least run through the initial steps of that tutorial so you can install the prerequisites.
Note:If for some reason you don’t want to use CocoaPods you can still use ReactiveCocoa,just follow theImporting ReactiveCocoasteps in the documentation on GitHub.
If you still have theReactivePlaygroundproject open in Xcode,then close it now. CocoaPods will create an Xcode workspace,which you’ll want to use instead of the original project file.
Terminal. Navigate to the folder where your project is located and type the following:
touch Podfile open -e Podfile |
This creates an empty file calledPodfileand opens it withTextEdit. Copy and paste the following lines into theTextEditwindow:
platform :ios,'7.0' pod 'ReactiveCocoa','2.1.8' |
This sets the platform to iOS,the minimum SDK version to 7.0,and adds the ReactiveCocoa framework as a dependency.
Once you’ve saved this file,go back to theTerminalwindow and issue the following command:
pod install |
You should see an output similar to the following:
Analyzing dependencies Downloading dependencies Installing ReactiveCocoa (2.1.8) Generating Pods project Integrating client project [!] From now on use `RWReactivePlayground.xcworkspace`. |
This indicates that the ReactiveCocoa framework has been downloaded,and CocoaPods has created an Xcode workspace to integrate the framework into your existing application.
Open up the newly generated workspace,RWReactivePlayground.xcworkspace,and look at the structure CocoaPods created inside the Project Navigator:
You’ll notice this project’s name isReactivePlayground
,so that must mean it’s time to play …
Time To Play
As mentioned in the introduction,ReactiveCocoa provides a standard interface for handling the disparate stream ofeventsthat occur within your application. In ReactiveCocoa terminology these are called signals,and are represented by theRACSignal
class.
Open the initial view controller for this app,55)">RWViewController.m,and import the ReactiveCocoa header by adding the following to the top of the file:
#import <ReactiveCocoa/ReactiveCocoa.h> |
You aren’t going to replace any of the existing code just yet,for now you’re just going to play around a bit. Add the following code to the end of theviewDidLoad
method:
[self.usernameTextField.rac_textSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; |
Build and run the application and type some text into the username text field. Keep an eye on the console and look for an output similar to the following:
2013-12-24 14:48:50.359 RWReactivePlayground[9193:a0b] i 2013-12-24 14:48:50.436 RWReactivePlayground[9193:a0b] is 2013-12-24 14:48:50.541 RWReactivePlayground[9193:a0b] is 2013-12-24 14:48:50.695 RWReactivePlayground[9193:a0b] is t 2013-12-24 14:48:50.831 RWReactivePlayground[9193:a0b] is th 2013-12-24 14:48:50.878 RWReactivePlayground[9193:a0b] is thi 2013-12-24 14:48:50.901 RWReactivePlayground[9193:a0b] is this 2013-12-24 14:48:51.009 RWReactivePlayground[9193:a0b] is this 2013-12-24 14:48:51.142 RWReactivePlayground[9193:a0b] is this m 2013-12-24 14:48:51.236 RWReactivePlayground[9193:a0b] is this ma 2013-12-24 14:48:51.335 RWReactivePlayground[9193:a0b] is this mag 2013-12-24 14:48:51.439 RWReactivePlayground[9193:a0b] is this magi 2013-12-24 14:48:51.535 RWReactivePlayground[9193:a0b] is this magic 2013-12-24 14:48:51.774 RWReactivePlayground[9193:a0b] is this magic? |
You can see that each time you change the text within the text field,the code within the block executes. No target-action,no delegates — just signals and blocks. That’s pretty exciting!
ReactiveCocoa signals (represented byRACSignal
) send a stream of events to their subscribers. There are three types of events to know:next,55)">errorandcompleted. A signal may send any number of next events before it terminates after an error,or it completes. In this part of the tutorial you’ll focus on thenextevent. Be sure to read part two when it’s available to learn about error and completed events.
RACSignal
has a number of methods you can use to subscribe to these different event types. Each method takes one or more blocks,with the logic in your block executing when an event occurs. In this case,you can see that thesubscribeNext:
method was used to supply a block that executes on eachnextevent.
The ReactiveCocoa framework uses categories to add signals to many of the standard UIKit controls so you can add subscriptions to their events,which is where therac_textSignal
property on the text field came from.
But enough with the theory,it’s time to start making ReactiveCocoa do some work for you!
ReactiveCocoa has a large range of operators you can use to manipulate streams of events. For example,assume you’re only interested in a username if it’s more than three characters long. You can achieve this by using thefilter
operator. Update the code you added previously inviewDidLoad
to the following: