I have a mixed Swift and Objective C application. The swift app uses some ObjectiveC libaries to handle OAuth2 authentication. Part of that is a callback to a delegate method once the OAuth2 request for a token has completed.
The following code is being executed in an Objective C library (GTMOAuth2) which uses a selector which I have passed in:
if (delegate_ && finishedSelector_) {
SEL sel = finishedSelector_;
NSMethodSignature *sig = [delegate_ methodSignatureForSelector:sel];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setSelector:sel];
[invocation setTarget:delegate_];
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&auth atIndex:3];
[invocation setArgument:&error atIndex:4];
[invocation invoke];
}
The function I'd like this to invoke is in my swift viewController and looks like such:
func authentication(viewController: GTMOAuth2ViewControllerTouch, finishedWithAuth: GTMOAuth2Authentication, error: NSError)
{
if (error != nil)
{
var alertView: UIAlertView = UIAlertView(title: "Authorisation Failed", message: error.description, delegate: self, cancelButtonTitle: "Dismiss")
alertView.show()
}
else
{
// Authentication Succeeded
self.mytoken = finishedWithAuth.accessToken
}
}
The selector I am currently passing in is:
let mySelector: Selector = Selector("authentication:viewController:finishedWithAuth:error:")
and is being used as a parameter in this call:
let myViewController: GTMOAuth2ViewControllerTouch = GTMOAuth2ViewControllerTouch(authentication: auth, authorizationURL: authURL, keychainItemName: nil, delegate: self, finishedSelector: mySelector)
Can anyone tell me why my function is never being called? It always seems to fail on the line where it creates an NSInvocation.
I've tried multiple selector strings and each one seems to fail. Am I missing something?
I've also tried putting "@objc" in front of the func name, to no avail.
The Swift method
func authentication(viewController: GTMOAuth2ViewControllerTouch,
finishedWithAuth: GTMOAuth2Authentication,
error: NSError)
is exposed to Objective-C as
-(void)authentication:(GTMOAuth2ViewControllerTouch *) viewController
finishedWithAuth:(GTMOAuth2Authentication *) finishedWithAuth
error:(NSError *)error
which means that the selector is
Selector("authentication:finishedWithAuth:error:")
Generally, the first parameter name is not part of the selector. The only exception
are init
methods, where the first parameter name is merged into the Objective-C
method name. For example, the Swift initializer
init(foo: Int, bar: Int)
translates to Objective-C as
- (instancetype)initWithFoo:(NSInteger)foo bar:(NSInteger)bar
and the selector would be
Selector("initWithFoo:bar:")