标签: ReactiveCocoa是一个框架,它能让你在iOS应用中使用函数响应式编程(FRP)技术。在本系列教程的第一部分中,你学到了如何将标准的动作与事件处理逻辑替换为发送事件流的信号。你还学到了如何转换、分割和聚合这些信号。 在本系列教程的第二部分,你将会学到一些ReactiveCocoa的高级功能,包括: 是时候深入研究一下了。 在本教程中你将要开发的应用叫Twitter Instant(基于Google Instant的概念),这个应用能搜索Twitter上的内容,并根据输入实时更新搜索结果。 这个应用的初始工程包括一些基本的UI和必须的代码。和第一部分一样,你需要使用CocoaPods来获取ReactiveCocoa框架,并集成到项目中。初始工程已经包含必须的Podfile,所以打开终端,执行下面的命令: 如果执行正确的话,你能看到和下面类似的输出: 这会生成一个Xcode workspcae,TwitterInstant.xcworkspace 。在Xcode中打开它,确认其中包含两个项目: TwitterInstant :应用的逻辑就在这里。 Pods :这里是外部依赖。目前只包含ReactiveCocoa。 构建运行,就能看到下面的界面:
花一些时间来熟悉应用的代码。这个是一个很简单的应用,基于split view controller。左栏是RWSearchFormViewController,它通过storyboard在上面添加了一些UI控件,通过outlet连接了search text field。右栏是RWSearchResultsViewController,目前只是UITableViewController的子类。
打开RWSearchFormViewController.m,能看到在viewDidLoad方法中,首先定位到results view controller,然后把它分配给resultsViewController私有属性。应用的主要逻辑都会集中在RWSearchFormViewController,这个属性能把搜索结果提供给RWSearchResultsViewController。
首先要做的就是验证搜索文本,来确保文本长度大于2个字符。如果你完成了本系列教程的第一部分,那这个应该很熟悉。
在RWSearchFormViewController.m中的viewDidLoad 下面添加下面的方法:
- (BOOL)isValidSearchText:(NSString *)text { return text.length > 2;}
这个方法就只是确保要搜索的字符串长度大于2个字符。这个逻辑很简单,你可能会问“为什么要在工程文件中写这么一个单独的方法呢?”。
目前验证输入有效性的逻辑的确很简单,但如果将来逻辑需要变得更复杂呢?如果是像上面的例子中那样,那你就只需要修改一个地方。而且这样写能让你代码的可读性更高,代码本身就说明了你为什么要检查字符串的长度。
在RWSearchFormViewController.m的最上面,引入ReactiveCocoa:
#import <ReactiveCocoa.h>把下面的代码加到viewDidLoad的最下面 :
[[self.searchText.rac_textSignal map:^id(NSString *text) { return [self isValidSearchText:text] ? [UIColor whiteColor] : [UIColor yellowColor]; }] subscribeNext:^(UIColor *color) { self.searchText.backgroundColor = color; }];?
上面的代码做了什么呢?
构建运行,观察在输入文本过短时,text field的背景会变成黄色来标示输入无效。
用图形来表示的话,流程和下面的类似:
当text field中的文字每次发生变化时,rac_textSignal都会发送一个next 事件,事件包含当前text field中的文字。map这一步将文本值转换成了颜色值,所以subscribeNext:这一步会拿到这个颜色值,并应用在text field的背景色上。
你应该还记得本系列教程第一部分里这些内容吧?如果忘了,建议你先停在这里,回去看一下第一部分。
在添加Twitter搜索逻辑之前,还有一些有意思的话题要说说。
当你在探索如何格式化ReactiveCocoa的代码时,惯例是每个操作新起一行,垂直对齐每个步骤。
在下图中你能看到比较复杂的代码是如何对齐的,这是第一部分教程中的代码。
这样对齐能让你很容易的看到每一步的操作。同时你还应该减少每个block中的代码量,如果block中的代码超过几行时,就应该新写一个私有方法。
很不幸的是,Xcode不是很喜欢这种风格的格式化,所以你会发现Xcode的自动缩进逻辑总是和你过不去。
看一下你添加到TwitterInstant中的代码,你是否好奇创建的这些管道是如何持有的呢?显然,它并没有分配给某个变量或是属性,所以它也不会有引用计数的增加,那它是怎么销毁的呢?
ReactiveCocoa设计的一个目标就是支持匿名生成管道这种编程风格。到目前为止,在你所写的所有响应式代码中,这应该是很直观的。