RxSwift 6 上線啦!

2021 的開始,RxSwift 6 悄悄地上線啦!你可以從這個網站來看看有哪些更新,或看看這篇筆記📒

這次更新的項目為


  • 新的 logo
  • Binder 從 RxCocoa 移植到 RxSwift
  • RxSwift 新增 withUnretained
  • 透過 @dynamicMemberLookup 來自動建立 Binders
  • Infallible
  • Observable<Data> 新增 decode(type:decoder:)
  • Variadic drive() 和 emit()
  • Single 的結果調整成 Result
  • distinctUntilChange(at:) 支援 Key Paths
  • 新增 ReplayRelay
  • 新增 DisposeBag 的 functional builder
  • 重新命名運算子

powered by dev.to
powered by dev.to

Binder 從 RxCocoa 移植到 RxSwift


原本 Binder 是屬於 RxCocoa 裡頭的元件,而在社群大家的討論下,便在這一次的更新內容,將其收納進了 RxSwift 之中。

RxSwift 新增 withUnretained


我們在寫 RxSwift 時,還是得注意 retain cycle 的問題,而多半我們處理的方式如下

someObservable.subscribe(onNext: { [weak self] value in
	guard let self = self else { return }
	self.doSomething(with: value)
})
.disposed(by: disposeBag)

而在導入了 withUnretained 之後,便等於是直接包裝掉這部分的處理

someObservable.withUnretained(self)
	.subscribe(onNext: { owner, value in
		owner.soSomething(with: value)
	})
	.disposed(by: disposeBag)

透過 @dynamicMemberLookup 來自動建立 Binders


在 Swift 5.1 導入了 @dynamicMemberLookup 機制之後,RxSwift 6 也做出了相對應的處理;若沒有要做特定的動作的話,我們將可以不用將元件的變數一個一個地去撰寫 Binder,而是可以直接使用 @dynamicMemberLookup 所提供的好處。

如上述圖片顯示,我們不必 import RxCocoa 也可以直接對 UILabel().rx.text 做 binder 原本做的事。

Infallible


簡單來說,Infalliable 就是字面上的意思,為一個只可以發送 .completed.next(Element) 的元件;不同於原本在 RxCocoa 裡頭的 DriverSignal,它並不會被要求在 MainScheduler 下執行且它隸屬於 RxSwift。

Observable<Data> 新增 decode(type:decoder:)


Observable<Data> 提供了 decode(type:decoder:),讓網路請求的處理可以更簡潔!

service.rx
       .fetchJSONUsers() // Observable<Data>
       .decode(type: [User].self, decoder: JSONDecoder()) // Observable<[User]>

Variadic drive() 和 emit()


在 RxSwift 5 裡頭有介紹到 variadic bind 的使用

viewModel.string.bind(to: input1, input2, input3)

而 RxSwift 6 則在 drive()emit() 上提供了 variadic 的操作。

viewModel.string.drive(input1, input2, input3)
viewModel.number.emit(input4, input5)

Single 的結果調整成 Result


Single 現在的 action 從原本的 onSuccessonError 調整成 Result 的格式,也就是 onSuccess 以及 onFailure

distinctUntilChanged(at:) 支援 Key Paths


distinctUntilChanged 提供了一種支援 Key Paths 的方式,讓我們能夠從原先的

someObservable.distinctUntilChanged { $0.someVariable == $1.someVariable }

改成對該物件的變數去操作

someObservable.distinctUntilChanged(at: \.someVariable)

新增 ReplayRelay


ReplayRelay 就直接上 code 來理解!

新增 DisposeBag 的 functional builder


這邊直接複製 原文 的教學內容

var disposeBag = DisposeBag { 
    observable1.bind(to: input1)
    observable2.drive(input2)
    observable3.subscribe(onNext: { val in 
        print("Got \(val)")
    })
}

// Also works for insertions
disposeBag.insert {
    observable4.subscribe()

    observable5.bind(to: input5)
}

重新命名運算子


RxSwift 5RxSwift 6
catchError(_:)catch(_:)
catchErrorJustReturn(_:)catchAndReturn(_:)
elementAt(_:)element(at:)
retryWhen(_:)retry(when:)
takeUntil(_:)take(until:)
takeUntil(behavior:_:)take(until:behavior:)
takeWhile(_:)take(while:)
takeWhile(behavior:_:)`take(while:behavior:)
take(.seconds(3))`take(for: .seconds(3))
skipWhile(_:)`skip(while:)
takeUntil(_:)take(until:)
observeOn(_:)`observe(on:)
subscribeOn(_:)subscribe(on:)
comments powered by Disqus