Wrapping custom class delegates into RxSwift Observables

Viewed 753

I am trying to observe on custom class delegates. I started with

public var didTapAvatar: Observable<()> {
    return delegate
        .methodInvoked(#selector(JSQMessagesCollectionViewDelegateFlowLayout.collectionView(_:didTapAvatarImageView:at:)))
        .map { _ in ()
    }
}

which will cause an error as below

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RxCocoa.RxCollectionViewDelegateProxy collectionView:layout:heightForCellTopLabelAtIndexPath:]: unrecognized selector sent to instance 0x618000298b00

I later tried this

public var jsqdelegate: DelegateProxy {
    return RxJSQMessageCollectionViewCellProxy(parentObject: base)
}

public var didTapAvatar: Observable<()> {
    return jsqdelegate
        .methodInvoked(#selector(JSQMessagesCollectionViewDelegateFlowLayout.collectionView(_:didTapAvatarImageView:at:)))
        .map { _ in ()
    }

which will succeed on running but will immediately complete and dispose as shown by printing them out onto the console:

self.collectionView.rx.didTapAvatar.asObservable()
    .subscribe(onNext: { (event) in
        print("next")
    }, onError: { (error) in
        print("error")
    }, onCompleted: { 
        print("complete")
    }, onDisposed: { 
        print("disposed")
    }).disposed(by: disposeBag)

RxJSQMessageCollectionViewCellProxy.swift

public class RxJSQMessageCollectionViewCellProxy: DelegateProxy, JSQMessagesCollectionViewDelegateFlowLayout, DelegateProxyType {

public class func currentDelegateFor(_ object: AnyObject) -> AnyObject? {
    let collectionView: JSQMessagesCollectionView = object as! JSQMessagesCollectionView
    return collectionView.delegate
}

public class func setCurrentDelegate(_ delegate: AnyObject?, toObject object: AnyObject) {
    let collectionView: JSQMessagesCollectionView = object as! JSQMessagesCollectionView
    collectionView.delegate = delegate as? JSQMessagesCollectionViewDelegateFlowLayout
}

}

JSQMessagesCollectionView+RxCreate.swift

extension Reactive where Base: JSQMessagesCollectionView {
    public var didTapAvatar: Observable<()> {
        return delegate.methodInvoked(#selector(JSQMessagesCollectionView.messagesCollectionViewCellDidTapAvatar(_:))).map { _ in () }
    }
}
0 Answers
Related