Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What is going on with this article?
@decoch

RxSwift6 の変更点まとめ

RxSwiftの6.0が公開されたので変更点をサンプル付きでまとめました。
GitHubのリリースノートDEV Communityでもまとめられています。

New Logo

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 の DriverSignal は常に MainScheduler を使用しリソースを共有するのに対して、Infallible、基本的に Observable である点が異なります。

drive()emit() で複数の observerrelay にバインドできるようになりました

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]>

SingleSwiftResult を使うようになりました。

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 が追加されました。
BehaviorRelayPublishRelay と同様にエラーを流しません。

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)
}

ignoreElementsObservable<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() }
}

UIApplicationRxExtension が追加されました

以下変数が追加されました

  • 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(_:)'
6
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
decoch
フリーランスのiOSエンジニア。Swift / Firebase / CI/CD構築 / Flutter を主にやっています。
engineerlife
技術力をベースに人生を謳歌する人たちのコミュニティです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
6
Help us understand the problem. What is going on with this article?