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

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
125
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@usamik26

RxSwift で UIKit を扱う基本

RxSwift では、iOS や OS X の UI と連携する機能も用意されています。

どういったものがあるかは、API の RxCocoa extensions に記載があります。

以下、iOS で使う場合について記載します(OS X もほぼ同じ)。

基本パターン

let disposeBag = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()

    hogeButton.rx.tap
        .subscribe { [unowned self] _ in
            self.hoge()
        }
        .disposed(by: disposeBag)
}

基本的に、UIViewControllerviewDidLoad で UI アクションに対する subscribe を行うのが良いかと思います。

例えば UIButton には rx.tap が用意されています。これは、ボタンがタップされたことを通知してくれる Observable です。これを subscribe してタップ時の処理を記述します。

なお、RxSwift では DisposeBag というものが用意されています。.disposed(by: disposeBag) としておくことで、dispose(unsubscribe)を自動的に行ってくれる仕組みになっています。

NSNotification

Cocoa の通知の仕組みのひとつ NSNotification は、add した処理の remove が面倒で忘れがちです。

NotificationCenter.default.rx.notification(NSNotification.Name.UIApplicationDidBecomeActive)
    .subscribe { [unowned self] _ in
        self.hoge()
    }
    .disposed(by: disposeBag)

RxSwift ではとてもシンプルに書けて幸せですね。

URLSession

通信処理の Observable も用意されています。

let session: URLSession = ...
let request = URLRequest(...)

session.rx.response(request)
    .catchError {
        ...
    }
    .subscribe { (data, response) in
        ...
    }
    .disposed(by: disposeBag)

とはいえ、通信部分は外部ライブラリを使うことが多いように思います。

僕はよく APIKit を使います。APIKit を RxSwift で扱えるように Observable を実装して使っています。これについては、以前 関西モバイルアプリ研究会 で発表しました(参考 : RxSwift x APIKit )。

以下のように使えます。

let request = ...
AppAPI.responseFrom(request)
    .catchError {
        ...
    }
    .subscribe {
        ...
    }
    .disposed(by: disposeBag)

API の実装コードは以下のような感じです。

static func responseFrom<T: AppAPIRequest>(request: T) -> Observable<T.Response> {
    return create { (observer: AnyObserver<T.Response>) -> Disposable in
        let dataTask = Session.sendRequest(request) { result in
            switch result {
            case .success(let response):
                observer.on(.next(response))
                observer.on(.completed)
            case .failure(let error):
                observer.on(.error(error))
            }
        }
        return AnonymousDisposable {
            dataTask?.cancel()
        }
    }
}

まとめ

RxSwift のうち、RxCocoa 部分の基本的な使い方を整理して簡潔に書きました。

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
125
Help us understand the problem. What are the problem?