RxSwiftの6.0が公開されたので変更点をサンプル付きでまとめました。
GitHubのリリースノートやDEV Communityでもまとめられています。
dynamicMemberLookup
を使用したバインダーの自動合成
今ままでは以下のような ExampleView
があったとき
class ExampleView: UIView {
var text: String
}
Binder
を毎回記述することで
extension Reactive where Base: ExampleView {
var text: Binder<String> {
Binder(base) { base, title in
base.text = text
}
}
}
このように stream
をクラスに bind
することができました。
let exampleView = ExampleView()
Observable.of("text").bind(to: exampleView.rx.text)
RxSwift 6
からは、どのクラスに対しても、Binderを自動的に合成します。そのため、上記のBinderのコードをすべて削除してコードをすっきりさせることができるようになりました。
Infallible
エラーを流さない Observable
です。
Infallible<String>.create { observer in
observer(.next("next"))
observer(.completed)
// これはコンパイルエラー
// observer(.error(NSError()))
return Disposables.create {}
}
Observable
と比べると微妙にメソッドが違います。
Observable<String>.create { observer in
observer.on(.next("next"))
observer.on(.error(NSError()))
observer.on(.completed)
return Disposables.create {}
}
また RxCocoa の Driver
と Signal
は常に MainScheduler
を使用しリソースを共有するのに対して、Infallible
、基本的に Observable
である点が異なります。
drive()
と emit()
で複数の observer
や relay
にバインドできるようになりました
let myButton = UIButton()
Driver.of(true).drive(myButton.rx.isEnabled, myButton.rx.isSelected)
Signal.of(true).emit(myButton.rx.isEnabled, myButton.rx.isSelected)
decode(type:decoder:)
が追加されました
Combineと同様に、Dataを出力するObservableに対して動作するデコード演算子が追加されました。
service
.fetchJSONUsers() // Observable<Data>
.decode(type: [Example].self, decoder: JSONDecoder()) // Observable<[Example]>
Single
が Swift
の Result
を使うようになりました。
subscribe の命名が変わったため警告が出るようになりました。
// RxSwift 5
// 'subscribe(onSuccess:onError:onDisposed:)' is deprecated: renamed to 'subscribe(onSuccess:onFailure:onDisposed:)'
single.subscribe(
onSuccess: { value in
print("Got a value: \(value)")
},
onError: { error in
print("Something went wrong: \(error)")
}
)
// RxSwift 6
single.subscribe(
onSuccess: { value in
print("Got a value: \(value)")
},
onFailure: { error in
print("Something went wrong: \(error)")
}
)
ReplayRelay
が追加されました
新しく ReplaySubject
をラップした ReplayReplay
が追加されました。
BehaviorRelay
や PublishRelay
と同様にエラーを流しません。
withUnretained
が追加されました
いままでは weak
キーワードを使い循環参照をせずにクラスに値を渡していました。
viewModel.importantInfo
.subscribe(onNext: { [weak self] info in
guard let self = self else { return }
self.doImportantTask(with: info)
})
.disposed(on: disposeBag)
RxSwift 6 からは withUnretained
を使うことで綺麗に記述することができます。
viewModel.importantInfo
.withUnretained(self) // (self, info) のタプルになる
.subscribe(onNext: { owner, info in
owner.doImportantTask(with: info)
})
.disposed(by: disposeBag)
distinctUntilChange(at:)
で Key Paths をつかるようになりました。
Observable.of(Example(text: "1"), Example(text: "2")).distinctUntilChanged(at: \.text)
struct Example {
let text: String
}
DisposeBag
のビルダー関数でSwiftUIのようにカンマを使わずに記述することができます。
var disposeBag = DisposeBag {
observable1.bind(to: input1)
observable2.drive(input2)
observable3.subscribe(onNext: { val in
print("Got \(val)")
})
}
disposeBag.insert {
observable4.subscribe()
observable5.bind(to: input5)
}
ignoreElements
が Observable<Never>
を返すようになりました
※ 修正前
public func ignoreElements() {
-> Completable {
return self.flatMap { _ in
return Observable<Never>.empty()
}
.asCompletable()
}
※ 修正後
public func ignoreElements() {
-> Observable<Never> {
self.flatMap { _ in Observable<Never>.empty() }
}
UIApplication
に Rx
の Extension
が追加されました
以下変数が追加されました
didEnterBackground
willEnterForeground
didFinishLaunching
didBecomeActive
willResignActive
didReceiveMemoryWarning
willTerminate
significantTimeChange
backgroundRefreshStatusDidChange
protectedDataWillBecomeUnavailable
protectedDataDidBecomeAvailable
userDidTakeScreenshot
命名変更
メソッドのリネームがありました。
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(_:) |
take(for:) |
skipWhile(_:) |
skip(while:) |
takeUntil(_:) |
take(until:) |
observeOn(_:) |
observe(on:) |
subscribeOn(_:) |
subscribe(on:) |
前のメソッドを使ってもエラーにはならずに以下のような警告が表示されます。
'catchError' is deprecated: renamed to 'catch(_:)'