「iOS开发之框架详解——RxSwift」新手初体验


theme: vue-pro
highlight: vs

本专栏基于 Swift 语言,对响应式、函数式编程的著名框架 RxSwift 进行了核心流程分析和代码实战演示。

本文通过对比iOS开发中常用的实现方法展示了RxSwift的框架魅力。

传统实现与 RxSwift 对比

Target Action

传统实现方法:

func test() {
 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)

你不需要使用 Target Action,这样使得代码逻辑清晰可见。

代理

传统实现方法:

class ViewController: UIViewController {
 ...
 override func viewDidLoad() {
 super.viewDidLoad()
 scrollView.delegate = self
 }
}
extension ViewController: UIScrollViewDelegate {
 func scrollViewDidScroll(_ scrollView: UIScrollView) {
 print("contentOffset: (scrollView.contentOffset)")
 }
}

通过 Rx 来实现:

class ViewController: UIViewController {
 ...
 override func viewDidLoad() {
 super.viewDidLoad()
 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)
}

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

多个任务之间有依赖关系

例如,先通过用户名密码取得 Token 然后通过 Token 取得用户信息,

传统实现方法:

/// 用回调的方式封装接口
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)

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

KVO

传统实现方法:

func kvoTest() {
 self.person.addObserver(self, forKeyPath: "name", options: .new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
 print(change as Any)
}
deinit {
 self.removeObserver(self.person, forKeyPath: "name", context: nil)
}

通过 Rx 来实现:

self.person.rx.observeWeakly(String.self, "name")
 .subscribe { value in
 print(value as Any)
 }
 .disposed(by: disposeBag)

RxSwift 的优势

  • 复合 - Rx 就是复合的代名词
  • 复用 - 因为它易复合
  • 清晰 - 因为声明都是不可变更的
  • 易用 - 因为它抽象了异步编程,使我们统一了代码风格
  • 稳定 - 因为 Rx 是完全通过单元测试的

对于开发的优缺点

优点

  • 代码简洁明了,可读性提高;
  • 有效实现数据与业务分离,方便进行单元测试;
  • 不用担心资源管理,它已经帮我们做好了管理;
  • 因为它抽象的了异步编程,统一了代码风格。

缺点

  • 它是一整套框架,对于项目侵入性高;
  • 有一定的学习门槛,对于不熟悉原理的新手开发起来有难度。
作者:LmqLeo

%s 个评论

要回复文章请先登录注册