Short description of the issue:
I am getting "Type 'GIDSignIn' does not conform to protocol 'HasDelegate'" compile time error while trying to add GIDSignIn rx extension.
Expected outcome:
Not to get compile time "Type 'GIDSignIn' does not conform to protocol 'HasDelegate'" error.
What actually happens:
Compile time error.
Self contained code example that reproduces the issue:
extension GIDSignIn: HasDelegate {
public typealias Delegate = GIDSignInDelegate
}
open class RxGIDSignInDelegateProxy: DelegateProxy<GIDSignIn, GIDSignInDelegate>, DelegateProxyType, GIDSignInDelegate {
public weak private(set) var gidSignIn: GIDSignIn?
public init(gidSignIn: ParentObject) {
self.gidSignIn = gidSignIn
super.init(parentObject: gidSignIn, delegateProxy: RxGIDSignInDelegateProxy.self)
}
public static func registerKnownImplementations() {
self.register { RxGIDSignInDelegateProxy(gidSignIn: $0) }
}
open class func currentDelegate(for object: ParentObject) -> GIDSignInDelegate? {
return object.delegate
}
open class func setCurrentDelegate(_ delegate: GIDSignInDelegate?, to object: ParentObject) {
object.delegate = delegate
}
public func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
self._forwardToDelegate?.sign(signIn, didSignInFor: user, withError: error)
}
public func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
self._forwardToDelegate?.sign(signIn, didDisconnectWith: user, withError: error)
}
}
extension Reactive where Base: GIDSignIn {
public var delegate: DelegateProxy<GIDSignIn, GIDSignInDelegate> {
return RxGIDSignInDelegateProxy.proxy(for: base)
}
public var sign: Observable<Void> {
return delegate
.methodInvoked(#selector(GIDSignInDelegate.sign(_:didSignInFor:withError:)))
.map {_ in}
}
public var signOut: Observable<Void> {
return delegate
.methodInvoked(#selector(GIDSignInDelegate.sign(_:didDisconnectWith:withError:)))
.map {_ in}
}
}

Hi @IvanKalaica ,
I would assume that you would like your code to compile, but why do you think that we have a bug in this repo and that we can do something about this?
It's not clear to me what is wrong with this code, and that we can do something in this repo to fix this.
Hi @kzaher
I hope you are doing well. :)
Following the UIScrollView and RxScrollViewDelegateProxy example I made RxGIDSignInDelegateProxy.
GIDSignIn has delegate:
@property(nonatomic, weak) id<GIDSignInDelegate> delegate;
UIScrollView has delegate:
weak open var delegate: UIScrollViewDelegate?
When I add:
extension GIDSignIn: HasDelegate {
public typealias Delegate = GIDSignInDelegate
}
I get:
Type 'GIDSignIn' does not conform to protocol 'HasDelegate'
I assume It's probably swift/associatedtype and objc protocol compatibility issue or am I missing something?
Cheers,
Ivan
My RxGIDSignInDelegateProxy works without:
extension GIDSignIn: HasDelegate
Cool. Closing this not a bug issue. :)
Cheers,
Ivan
For me it's giving
Delegate proxy is already implementingsignIn:didSignInForUser:withError:, a more performant way of registering might exist.
error can anybody help?
TIA
Hey @VinayakDeshpande11,
Here is my implementation. Works without warnings.
Cheers,
Ivan
import RxSwift
import RxCocoa
open class RxGIDSignInDelegateProxy: DelegateProxy<GIDSignIn, GIDSignInDelegate>, DelegateProxyType, GIDSignInDelegate {
public weak private(set) var gidSignIn: GIDSignIn?
var signInSubject = PublishSubject<GIDGoogleUser>()
var disconnectSubject = PublishSubject<GIDGoogleUser>()
public init(gidSignIn: ParentObject) {
self.gidSignIn = gidSignIn
super.init(parentObject: gidSignIn, delegateProxy: RxGIDSignInDelegateProxy.self)
}
public static func registerKnownImplementations() {
self.register { RxGIDSignInDelegateProxy(gidSignIn: $0) }
}
open class func currentDelegate(for object: ParentObject) -> GIDSignInDelegate? {
return object.delegate
}
open class func setCurrentDelegate(_ delegate: GIDSignInDelegate?, to object: ParentObject) {
object.delegate = delegate
}
public func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let u = user {
self.signInSubject.on(.next(u))
} else if let e = error {
self.signInSubject.on(.error(e))
}
self._forwardToDelegate?.sign(signIn, didSignInFor: user, withError: error)
}
public func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
if let u = user {
self.disconnectSubject.on(.next(u))
} else if let e = error {
self.disconnectSubject.on(.error(e))
}
self._forwardToDelegate?.sign(signIn, didDisconnectWith: user, withError: error)
}
deinit {
self.signInSubject.on(.completed)
self.disconnectSubject.on(.completed)
}
}
extension Reactive where Base: GIDSignIn {
public var delegate: DelegateProxy<GIDSignIn, GIDSignInDelegate> {
return self.gidSignInDelegate
}
private var signIn: Single<GIDGoogleUser> {
let proxy = self.gidSignInDelegate
proxy.signInSubject = PublishSubject<GIDGoogleUser>()
return proxy.signInSubject
.asObservable()
.do(onSubscribed: {
proxy.gidSignIn?.signIn()
})
.take(1)
.asSingle()
}
private var signOut: Single<GIDGoogleUser> {
let proxy = self.gidSignInDelegate
proxy.signInSubject = PublishSubject<GIDGoogleUser>()
return proxy.disconnectSubject
.asObservable()
.do(onSubscribed: {
proxy.gidSignIn?.signOut()
})
.take(1)
.asSingle()
}
private var gidSignInDelegate: RxGIDSignInDelegateProxy {
return RxGIDSignInDelegateProxy.proxy(for: base)
}
}
Hi Ivan,
Thanks a lot for sharing the implementation, but now I am stuck with the subscription part. How will I subscribe this on the button tap? please let me know that would be of great help.
I tried with GIDSignIn().sharedInstance.rx.signIn but it didn't work.
TIA
Hi Ivan,
It worked for me but I had to remove the private from private var signIn: Single<GIDGoogleUser> from reactive extension. Please let me know if there is a work around without removing the private modifier.
TIA
@VinayakDeshpande11 that's fine ;)
How to call this method to get Auth Token.
GIDSignIn().sharedInstance.rx.signIn doesn't work
Neither return GIDSignIn.sharedInstance().rx.base.signIn()
i have method like this
here return type is Auth of Google
private func loginGoogle() -> Single
return GIDSignIn.sharedInstance().rx.base.signIn()
}
Although methods are striken through in suggestion.


Most helpful comment
Hey @VinayakDeshpande11,
Here is my implementation. Works without warnings.
Cheers,
Ivan