2021 的開始,RxSwift 6 悄悄地上線啦!你可以從這個網站來看看有哪些更新,或看看這篇筆記📒
這次更新的項目為
- 新的 logo
- 將
Binder
從 RxCocoa 移植到 RxSwift - RxSwift 新增
withUnretained
- 透過
@dynamicMemberLookup
來自動建立Binder
s Infallible
Observable<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
來自動建立 Binder
s
在 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:) |