79dc1626ab9344b8966d9bfae4ac7e9b
跟我学RxSwift02 - RxSwift环境搭建及简单使用

一、RxSwift 的安装与配置

1. 手动安装

(1)从 GitHub 上下载最新的代码
(2)将下载下来的源码包中 Rx.xcodeproj 拖拽至你的工程中
(3)工程 -> General-> Embedded Binaries 项,把 iOS 版的 RxSwift.frameworkRxCocoa.framework 添加进来

2. 通过CocoaPods安装

pod --version: 1.6.0.beta.2 已通过测试

# Podfile
use_frameworks!

target 'YOUR_TARGET_NAME' do
    pod 'RxSwift',    '~> 4.0'
    pod 'RxCocoa',    '~> 4.0'
end

# RxTests 和 RxBlocking 将在单元/集成测试中起到重要作用
target 'YOUR_TESTING_TARGET' do
    pod 'RxBlocking', '~> 4.0'
    pod 'RxTest',     '~> 4.0'
end

3. Carthage

carthage version: 0.31.2 已通过测试
添加到 Cartfile

github "ReactiveX/RxSwift" ~> 4.0
$ carthage update

最后,在需要使用 RxSwift 的地方 import 进来就可以了

import RxSwift
import RxCocoa

二、RxSwift 与 RxCocoa

我们注意到import Rx有两个: RxSwift 和 RxCocoa。 它们有什么作用呢?

  • RxSwift:它只是基于 Swift 语言的 Rx 标准实现接口库,所以 RxSwift 里不包含任何 Cocoa 或者 UI方面的类。
  • RxCocoa:是基于 RxSwift针对于 iOS开发的一个库,它通过 Extension 的方法给原生的比如 UI 控件添加了 Rx 的特性,使得我们更容易订阅和响应这些控件的事件。

环境搭建好了,是不是有点迫不及待了呢? 别着急,在正式介绍RxSwift之前,我想先通过一个简单demo演示下RxSwift能做什么,让大家对RxSwift有一个直观的了解:

三、传统方式与RxSwift方式的比较样例

tableView是我们开发中最为常用的一个UI控件,下面我们就以tableView为例为大家演示传统写法以及RxSwift响应式写法,大家可以比较下它们的区别。

  • 1. cell显示歌曲信息(歌曲名、歌手)
  • 点击任意一个cell,在控制台中打印出对应的歌曲信息。

显示效果

1、准备工作:
首先我们创建一个 Music 的结构体,用来保存歌曲名称、歌手名字。此外它还遵循CustomStringConvertible 协议,这样方便我们输出调试。

import UIKit

// 歌曲结构体
struct Music {
    let name: String // 歌名
    let singer: String // 演唱者
    // 初始化
    init(name: String, singer: String) {
        self.name = name
        self.singer = singer
    }
}

// 实现 CustomStringConvertible 协议,方便输出调试
extension Music: CustomStringConvertible {
    var description: String {
        return "name:\(name) singer:\(singer)"
    }
}

2、传统做法:
(1)首先写一个 model,设置数据源

import Foundation
// 歌曲列表数据源
struct MusicDataModel {
    let data = [
        Music(name: "光你之外", singer: "摩登兄弟"),
        Music(name: "去年夏天", singer: "王大毛"),
        Music(name: "你就不要想起我", singer: "田馥甄"),
        Music(name: "学猫叫", singer: "小潘潘/小峰峰"),
        Music(name: "左手", singer: "冯提莫"),
    ]
}

(2)在控制器中设置UITableView 的委托,并让视图控制器实现 UITableViewDataSourceUITableViewDelegate 协议,及相关的协议方法。相信大家早已滚瓜乱熟了。

import UIKit
import RxSwift

class ViewController: UIViewController {
    // tableView对象
     weak var tableView: UITableView!
    // 歌曲列表数据源
    let musicDataModel = MusicDataModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置代理
        tableView.dataSource = self
        tableView.delegate = self
    }
}

extension ViewController: UITableViewDataSource {
    // 返回单元格数量
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return musicDataModel.data.count
    }

    // 返回对应的单元格
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
        -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell")!
        let music = musicDataModel.data[indexPath.row]
        cell.textLabel?.text = music.name
        cell.detailTextLabel?.text = music.singer
        return cell
    }
}

extension ViewController: UITableViewDelegate {
    //单元格点击
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("你选中的歌曲信息【\(musicDataModel.data[indexPath.row])】")
    }
}

3、下面使用 RxSwift 进行改造(响应式编程)
(1)首先我们对MusicDataModel进行改造

  • 我们将 data 属性变成一个可观察序列对象(Observable Squence),而对象中的内容不变;
  • 关于可观察序列对象在后面的文章中我会详细介绍。简单说就是“序列”可以对这些数值进行“订阅(Subscribe)”,有点类似于“通知(NotificationCenter)”
import RxSwift

// 歌曲列表数据源
struct MusicDataModel {
    let data = Observable.just([
        Music(name: "光你之外", singer: "摩登兄弟"),
        Music(name: "去年夏天", singer: "王大毛"),
        Music(name: "你就不要想起我", singer: "田馥甄"),
        Music(name: "学猫叫", singer: "小潘潘/小峰峰"),
        Music(name: "左手", singer: "冯提莫"),
    ])
}

(2)在控制器中我们不再需要实现数据源和委托协议了。而是写一些响应式代码,让它们将数据和 UITableView 建立绑定关系。代码如下:

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    // tableView对象
     weak var tableView: UITableView!
    // 歌曲列表数据源
    let musicDataModel = MusicListViewModel()
    // 负责对象销毁
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        // 将数据源数据绑定到tableView上
        musicDataModel.data
            .bind(to: tableView.rx.items(cellIdentifier:"musicCell")) { _, music, cell in
                cell.textLabel?.text = music.name
                cell.detailTextLabel?.text = music.singer
            }.disposed(by: disposeBag)

        //tableView点击响应
        tableView.rx.modelSelected(Music.self).subscribe(onNext: { music in
            print("你选中的歌曲信息【\(music)】")
        }).disposed(by: disposeBag)
    }
}

代码的简单说明:

  • DisposeBag:作用是 Rx 在视图控制器或者其持有者将要销毁的时候,自动释法掉绑定在它上面的资源。它是通过类似“订阅处置机制”方式实现(类似于 NotificationCenter 的 removeObserver)。
  • rx.items(cellIdentifier:):这是 Rx 基于 cellForRowAt 数据源方法的一个封装。传统方式中我们还要有个 numberOfRowsInSection 方法,使用 Rx 后就不再需要了(Rx 已经帮我们完成了相关工作)。
  • rx.modelSelected: 这是 Rx 基于 UITableView委托回调方法 didSelectRowAt 的一个封装。

上下两种方法对比一下,是不是代码更加精简了? 不用遵循代理和协议,代码少了 1 / 4。

好了,本节内容到此告一段落,祝大家学习愉快。本节我们在对MusicDataModel改造时使用到了Observable,那Observable到底是什么?我们下节相约。

下节预告:跟我学RxSwift03 - Observable介绍及使用

© 著作权归作者所有
这个作品真棒,我要支持一下!
RxSwift系列教程, 从多个方面逐一介绍RxSwift的使用方法,不仅会介绍RxSwift的核心内容: 1. ...
1条评论
Nine
#1

很好的文章 支持

top Created with Sketch.