iOS开发者进阶手机移动程序开发iOS开发

RxSwift使用详解

2019-08-21  本文已影响4人  __Mr_Xie__

简介

ReactiveX(简写: Rx) 是一个可以帮助我们简化异步编程的框架。

RxSwiftRxSwift 版本。

它尝试将原有的一些概念移植到 iOS / macOS 平台。

你可以在这里找到跨平台文档 ReactiveX.io

KVO,异步操作 和 流 全部被统一成抽象序列。这就是为什么 Rx 会如此简单,优雅和强大。

注:本文是根据官方文档整理的,适合刚开始学习 RxiOS 同行。其中剔除掉了很多不必要的东西,便于你的学习。

必备条件

对于 Xcode 10.1 以下版本,请使用 RxSwift 4.5

安装

安装 RxSwift 不需要任何第三方依赖。

以下是当前支持的安装方法:

手动安装如果不怕麻烦,你可以自己去尝试一下,我基本上都是使用 CocoaPods

pod 'RxSwift', '~> 5.0'
pod 'RxCocoa', '~> 5.0'

注:RxSwiftRxCocoa 的版本号以 官网 为准。

为什么要使用 RxSwift ?

RxSwift 能够帮助我们实现:

传统实现方法:

button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

func buttonTapped() {
    print("button Tapped")
}

通过 Rx 来实现:

button.rx.tap
    .subscribe(onNext: {
        print("button Tapped")
    })
    .disposed(by: disposeBag)

传统实现方法:

scrollView.delegate = self

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("contentOffset: \(scrollView.contentOffset)")
}

通过 Rx 来实现:

scrollView.rx.contentOffset
            .subscribe(onNext: { contentOffset in
                print("contentOffset: \(contentOffset)")
            })
            .disposed(by: disposeBag)

传统实现方法:

URLSession.shared.dataTask(with: URLRequest(url: url)) {
    (data, response, error) in
    guard error == nil else {
        print("Data Task Error: \(error!)")
        return
    }

    guard let data = data else {
        print("Data Task Error: unknown")
        return
    }

    print("Data Task Success with count: \(data.count)")
}.resume()

通过 Rx 来实现:

URLSession.shared.rx.data(request: URLRequest(url: url))
    .subscribe(onNext: { data in
        print("Data Task Success with count: \(data.count)")
    }, onError: { error in
        print("Data Task Error: \(error)")
    })
    .disposed(by: disposeBag)

传统实现方法:

var ntfObserver: NSObjectProtocol!

override func viewDidLoad() {
    super.viewDidLoad()

    ntfObserver = NotificationCenter.default.addObserver(
          forName: .UIApplicationWillEnterForeground,
          object: nil, queue: nil) { (notification) in
        print("Application Will Enter Foreground")
    }
}

deinit {
    NotificationCenter.default.removeObserver(ntfObserver)
}

通过 Rx 来实现:

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.rx
        .notification(.UIApplicationWillEnterForeground)
        .subscribe(onNext: { (notification) in
            print("Application Will Enter Foreground")
        })
        .disposed(by: disposeBag)
}

注:你不需要去管理观察者的生命周期,这样你就有更多精力去关注业务逻辑。

传统实现方法:

/// 用回调的方式封装接口
enum API {

    /// 通过用户名密码取得一个 token
    static func token(username: String, password: String,
        success: (String) -> Void,
        failure: (Error) -> Void) { ... }

    /// 通过 token 取得用户信息
    static func userinfo(token: String,
        success: (UserInfo) -> Void,
        failure: (Error) -> Void) { ... }
}
/// 通过用户名和密码获取用户信息
API.token(username: "beeth0ven", password: "987654321",
    success: { token in
        API.userInfo(token: token,
            success: { userInfo in
                print("获取用户信息成功: \(userInfo)")
            },
            failure: { error in
                print("获取用户信息失败: \(error)")
        })
    },
    failure: { error in
        print("获取用户信息失败: \(error)")
})

通过 Rx 来实现:

/// 用 Rx 封装接口
enum API {

    /// 通过用户名密码取得一个 token
    static func token(username: String, password: String) -> Observable<String> { ... }

    /// 通过 token 取得用户信息
    static func userInfo(token: String) -> Observable<UserInfo> { ... }
}
/// 通过用户名和密码获取用户信息
API.token(username: "beeth0ven", password: "987654321")
    .flatMapLatest(API.userInfo)
    .subscribe(onNext: { userInfo in
        print("获取用户信息成功: \(userInfo)")
    }, onError: { error in
        print("获取用户信息失败: \(error)")
    })
    .disposed(by: disposeBag)

注:这样你可以 避免回调地狱,从而使得代码易读,易维护。

例如,需要将两个网络请求合并成一个,

通过 Rx 来实现:

/// 用 Rx 封装接口
enum API {

    /// 取得老师的详细信息
    static func teacher(teacherId: Int) -> Observable<Teacher> { ... }

    /// 取得老师的评论
    static func teacherComments(teacherId: Int) -> Observable<[Comment]> { ... }
}
/// 同时取得老师信息和老师评论
Observable.zip(
      API.teacher(teacherId: teacherId),
      API.teacherComments(teacherId: teacherId)
    ).subscribe(onNext: { (teacher, comments) in
        print("获取老师信息成功: \(teacher)")
        print("获取老师评论成功: \(comments.count) 条")
    }, onError: { error in
        print("获取老师信息或评论失败: \(error)")
    })
    .disposed(by: disposeBag)

这样你可用寥寥几行代码来完成相当复杂的异步操作。

RxSwift 编程思想

RxSwift 采用的是 函数响应式编程 思想。


函数响应式编程 是种编程范式。它是通过构建函数操作数据序列,然后对这些序列做出响应的编程方式。它结合了函数式编程以及响应式编程

Author

如果你有什么建议,可以关注我的公众号:iOS开发者进阶,直接留言,留言必回。

上一篇 下一篇

猜你喜欢

热点阅读