Skip to content

Instantly share code, notes, and snippets.

@minsOne
Last active February 28, 2022 09:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minsOne/e91b6617c831a66dcf457090bc063acb to your computer and use it in GitHub Desktop.
Save minsOne/e91b6617c831a66dcf457090bc063acb to your computer and use it in GitHub Desktop.
// workaround for Swift compiler bug, cheers compiler team :)
func castOptionalOrFatalError<T>(value: AnyObject?) -> T? {
if value == nil {
return nil
}
let v: T = castOrFatalError(value)
return v
}
func castOrThrow<T>(resultType: T.Type, _ object: AnyObject) throws -> T {
guard let returnValue = object as? T else {
throw RxCocoaError.CastingError(object: object, targetType: resultType)
}
return returnValue
}
func castOptionalOrThrow<T>(resultType: T.Type, _ object: AnyObject) throws -> T? {
if NSNull().isEqual(object) {
return nil
}
guard let returnValue = object as? T else {
throw RxCocoaError.CastingError(object: object, targetType: resultType)
}
return returnValue
}
func castOrFatalError<T>(value: AnyObject!, message: String) -> T {
let maybeResult: T? = value as? T
guard let result = maybeResult else {
rxFatalError(message)
}
return result
}
func castOrFatalError<T>(value: Any!) -> T {
let maybeResult: T? = value as? T
guard let result = maybeResult else {
rxFatalError("Failure converting from \(value) to \(T.self)")
}
return result
}
@noreturn func rxFatalError(lastMessage: String) {
// The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours.
fatalError(lastMessage)
}
@objc protocol CustomClassDelegate: class {
optional func willStart(customClass: CustomClass, _ str: String)
optional func DidEnd(customClass: CustomClass, _ str: String)
}
class CustomClass: NSObject {
weak var delegate: CustomClassDelegate? = nil
func start() {
self.delegate?.willStart!(self, "WillStart")
(0...100).forEach { print($0) }
self.delegate?.DidEnd!(self, "End")
}
}
public class RxCustomDelegateProxy: DelegateProxy, DelegateProxyType, CustomClassDelegate {
public class func currentDelegateFor(object: AnyObject) -> AnyObject? {
let custom: CustomClass = castOrFatalError(object)
return custom.delegate
}
public class func setCurrentDelegate(delegate: AnyObject?, toObject object: AnyObject) {
let custom: CustomClass = castOrFatalError(object)
custom.delegate = castOptionalOrFatalError(delegate)
}
public override class func createProxyForObject(object: AnyObject) -> AnyObject {
let custom = (object as! CustomClass)
return castOrFatalError(custom.rx_createDelegateProxy())
}
}
extension CustomClass {
func rx_createDelegateProxy() -> RxCustomDelegateProxy {
return RxCustomDelegateProxy(parentObject: self)
}
internal var rx_delegate: DelegateProxy {
return proxyForObject(RxCustomDelegateProxy.self, self)
}
var rx_willStart: Observable<(CustomClass, String)> {
return rx_delegate.observe(#selector(CustomClassDelegate.willStart(_:_:))).map { a in
let custom = try castOrThrow(CustomClass.self, a[0])
let str = try castOrThrow(String.self, a[1])
return (custom, str)
}
}
var rx_DidEnd: Observable<(CustomClass, String)> {
return rx_delegate.observe(#selector(CustomClassDelegate.DidEnd(_:_:))).map { a in
let custom = try castOrThrow(CustomClass.self, a[0])
let str = try castOrThrow(String.self, a[1])
return (custom, str)
}
}
}
class ViewController: UIViewController {
let disposeBag = DisposeBag()
let custom = CustomClass()
override func viewDidLoad() {
super.viewDidLoad()
custom.rx_delegate.setForwardToDelegate(self, retainDelegate: false)
custom
.rx_willStart
.subscribeNext { print($0.0, $0.1) }
.addDisposableTo(disposeBag)
custom
.rx_DidEnd
.subscribeNext { print($0.0, $0.1) }
.addDisposableTo(disposeBag)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
custom.start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment