I have delegate methods, which I need to wrap by Delegate Proxy in RxSwift. I have done it using Bond and Reactive, but here, in RxSwift, I am not able to find the proper way to convert it.
Follow is Protocols
import UIKit
/**
A protocol for the delegate of a `DetailInputTextField`.
*/
@objc
public protocol CardInfoTextFieldDelegate {
/**
Called whenever valid information was entered into `textField`.
- parameter textField: The text field whose information was updated and is valid.
- parameter didEnterValidInfo: The valid information that was entered into `textField`.
*/
func textField(_ textField: UITextField, didEnterValidInfo: String)
/**
Called whenever partially valid information was entered into `textField`.
- parameter textField: The text field whose information was updated and is partially valid.
- parameter didEnterPartiallyValidInfo: The partially valid information that was entered.
*/
func textField(_ textField: UITextField, didEnterPartiallyValidInfo: String)
/**
Called whenever more text was entered into `textField` than necessary. This can be used to provide this overflow as text in the next text field in the responder chain.
- parameter textField: The text field which received more information than required.
- parameter overFlowDigits: The overflow of text which does not fit into `textField` and might be entered into the next receiver in the responder chain.
*/
func textField(_ textField: UITextField, didEnterOverflowInfo overFlowDigits: String)
}
What I did earlier is
import Foundation
import Bond
import Caishen
extension DetailInputTextField {
var bnd_cardInfoDelegate: ProtocolProxy {
return protocolProxy(for: CardInfoTextFieldDelegate.self, setter: NSSelectorFromString("setCardInfoTextFieldDelegate:"))
}
var bnd_didEnterValidInfo: StreamSignal<NSString> {
return bnd_cardInfoDelegate.signal(for: #selector(CardInfoTextFieldDelegate.textField(_:didEnterValidInfo:)))
{ (s: PublishSignal<NSString>, _: UITextField, info: NSString) in
s.next(info)
}
}
var bnd_didEnterPartiallyValidInfo: StreamSignal<NSString> {
return bnd_cardInfoDelegate.signal(for: #selector(CardInfoTextFieldDelegate.textField(_:didEnterPartiallyValidInfo:)))
{ (s: PublishSignal<NSString>, _: UITextField, info: NSString) in
s.next(info)
}
}
var bnd_didEnterOverflowInfo: StreamSignal<NSString> {
return bnd_cardInfoDelegate.signal(for: #selector(CardInfoTextFieldDelegate.textField(_:didEnterOverflowInfo:)))
{ (s: PublishSignal<NSString>, _: UITextField, info: NSString) in
s.next(info)
}
}
}
How can I do same exercise in RxSwift. I tried DelegateProxy but its unclear how it properly wrap it.
Due to the popularity of this answer, I have written an article about it: Convert a Swift Delegate to RxSwift Observables
I believe this is the official way of converting a delegate into RxObservables:
class CardInfoTextField: NSObject {
weak var delegate: CardInfoTextFieldDelegate? = nil
}
@objc
protocol CardInfoTextFieldDelegate {
@objc optional func textField(_ textField: CardInfoTextField, didEnterValidInfo: String)
@objc optional func textField(_ textField: CardInfoTextField, didEnterPartiallyValidInfo: String)
@objc optional func textField(_ textField: CardInfoTextField, didEnterOverflowInfo overFlowDigits: String)
}
extension CardInfoTextField: HasDelegate {
public typealias Delegate = CardInfoTextFieldDelegate
}
class CardInfoTextFieldDelegateProxy
: DelegateProxy<CardInfoTextField, CardInfoTextFieldDelegate>
, DelegateProxyType
, CardInfoTextFieldDelegate {
//#MARK: DelegateProxy
init(parentObject: CardInfoTextField) {
super.init(parentObject: parentObject, delegateProxy: CardInfoTextFieldDelegateProxy.self)
}
public static func registerKnownImplementations() {
self.register { CardInfoTextFieldDelegateProxy(parentObject: $0) }
}
}
extension Reactive where Base: CardInfoTextField {
var delegate: CardInfoTextFieldDelegateProxy {
return CardInfoTextFieldDelegateProxy.proxy(for: base)
}
var didEnterValidInfo: Observable<String> {
return delegate.methodInvoked(#selector(CardInfoTextFieldDelegate.textField(_:didEnterValidInfo:)))
.map { $0[1] as! String }
}
var didEnterPartiallyValidInfo: Observable<String> {
return delegate.methodInvoked(#selector(CardInfoTextFieldDelegate.textField(_:didEnterPartiallyValidInfo:)))
.map { $0[1] as! String }
}
var didEnterOverflowInfo: Observable<String> {
return delegate.methodInvoked(#selector(CardInfoTextFieldDelegate.textField(_:didEnterOverflowInfo:)))
.map { $0[1] as! String }
}
}
Once you have the above, you should be able to:
let validInfo: Observable<String> = myCardInfoTextField.rx.didEnterValidInfo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With