RxSwift・RxCocoaの.debugメソッドをカスタムしたい


概要

RxSwift、RxCocoaで、ログを出してくれる.debugメソッドですが、これの振る舞いを変えたいことがあると思います。

例えば、.debugメソッドでは内部で標準のprintメソッドを読んでいるだけなので、Xcodeのコンソールにはログが出てもデバイスのコンソールには出力してくれないため、代わりにNSLog等を使ってデバイスのコンソールにも出力したいなど。

.debugメソッドは通常のObservableType,その他PrimitiveSequence(Single, MayBe, Completable)、SharedSequence(Driver, Signal)の3つで定義されているので、ここではそれぞれ3つカスタムした.customDebugメソッドを用意します。

コード

RxSwiftDebug.swift
import Foundation
import RxCocoa
import RxSwift

//Debug.printが、自分で用意したロガー用のクラスだとします。

//ObservableType用
extension ObservableType {
   public func customDebug(_ identifier: String, file: String = #file, function: String = #function, line: Int = #line) -> Observable<Element> {
       return Observable.create { observer in
            Debug.print("subscribed \(identifier)", file: file, function: function, line: line)
           let subscription = self.subscribe { e in
                Debug.print("event  \(e) \(identifier)", file: file, function: function, line: line)
               switch e {
               case .next(let value):
                   observer.on(.next(value))

               case .error(let error):
                   observer.on(.error(error))

               case .completed:
                   observer.on(.completed)
               }
           }
           return Disposables.create {
                Debug.print("disposing \(identifier)", file: file, function: function, line: line)
                  subscription.dispose()
           }
       }
   }
}

//PrimitiveSequence(Single)用
extension PrimitiveSequenceType where Trait == SingleTrait {
    public func customDebug(_ identifier: String, file: String = #file, function: String = #function, line: Int = #line) -> Single<Element> {
        self.do(onSuccess: { e in
            Debug.print("Success \(e) \(identifier)", file: file, function: function, line: line)
        }, onError: { error in
            Debug.print("Error \(error) \(identifier)", file: file, function: function, line: line)
        }, onSubscribe: {
            Debug.print("subscribe \(identifier)", file: file, function: function, line: line)
        }, onSubscribed: {
            Debug.print("subscribed \(identifier)", file: file, function: function, line: line)
        }, onDispose: {
            Debug.print("disposed \(identifier)", file: file, function: function, line: line)
        })
    }
}

//SharedSequence用
extension SharedSequence {
    public func customDebug(_ identifier: String, file: String = #file, function: String = #function, line: Int = #line) -> SharedSequence {
        self.do(onNext: { e in
            Debug.print("next \(e) \(identifier)", file: file, function: function, line: line)
        }, onCompleted: {
            Debug.print("completed \(identifier)", file: file, function: function, line: line)
        }, onSubscribe: {
            Debug.print("subscribe \(identifier)", file: file, function: function, line: line)
        }, onSubscribed: {
            Debug.print("subscribed \(identifier)", file: file, function: function, line: line)
        }, onDispose: {
            Debug.print("disposed \(identifier)", file: file, function: function, line: line)
        })
    }
}

参考

RxSwift - Debugging
CustomOperators - RxSwift - GettingStarted.md