2021 的開始,RxSwift 6 悄悄地上線啦!你可以從這個網站來看看有哪些更新,或看看這篇筆記📒
這次更新的項目為
- 新的 logo
- 將
Binder從 RxCocoa 移植到 RxSwift - RxSwift 新增
withUnretained - 透過
@dynamicMemberLookup來自動建立Binders InfallibleObservable<Data>新增decode(type:decoder:)- Variadic drive() 和 emit()
- 將
Single的結果調整成Result distinctUntilChange(at:)支援Key Paths- 新增
ReplayRelay - 新增
DisposeBag的 functional builder - 重新命名運算子
新的 logo
將 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 裡頭的 Driver 和 Signal,它並不會被要求在 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 從原本的 onSuccess 和 onError 調整成 Result 的格式,也就是 onSuccess 以及 onFailure。
distinctUntilChanged(at:) 支援 Key Paths
distinctUntilChanged 提供了一種支援 Key Paths 的方式,讓我們能夠從原先的
someObservable.distinctUntilChanged { $0.someVariable == $1.someVariable }
改成對該物件的變數去操作
someObservable.distinctUntilChanged(at: \.someVariable)
新增 ReplayRelay
新增 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 5 | RxSwift 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:) |


