Не удается заставить селектор работать для моей функции Swift

У меня есть смешанное приложение Swift и Objective C. Приложение Swift использует некоторые библиотеки ObjectiveC для обработки аутентификации OAuth2. Частично это является обратным вызовом метода делегата, когда запрос OAuth2 для токена завершен.

Следующий код выполняется в библиотеке Objective C (GTMOAuth2), которая использует селектор, который я передал:

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];
}

Функция, которую я бы хотел вызвать, находится в моем быстром viewController и выглядит так:

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
    }
}

Селектор, который я сейчас передаю:

let mySelector: Selector = Selector("authentication:viewController:finishedWithAuth:error:")

и используется в качестве параметра в этом вызове:

let myViewController: GTMOAuth2ViewControllerTouch = GTMOAuth2ViewControllerTouch(authentication: auth, authorizationURL: authURL, keychainItemName: nil, delegate: self, finishedSelector: mySelector)

Может кто-нибудь сказать мне, почему моя функция никогда не вызывается? Кажется, что всегда происходит сбой на линии, где он создает NSInvocation.

Я пробовал несколько строк селектора, и каждая из них, кажется, не удается. Я что-то пропустил?

Я также попытался поставить "@objc" перед именем функции, но безрезультатно.

2 ответа

Решение

Свифт метод

func authentication(viewController: GTMOAuth2ViewControllerTouch,
                  finishedWithAuth: GTMOAuth2Authentication,
                             error: NSError)

подвергается Objective-C как

-(void)authentication:(GTMOAuth2ViewControllerTouch *) viewController 
     finishedWithAuth:(GTMOAuth2Authentication *) finishedWithAuth
                error:(NSError *)error

это означает, что селектор

Selector("authentication:finishedWithAuth:error:")

Как правило, имя первого параметра не является частью селектора. Единственным исключением являются init методы, где имя первого параметра объединяется с именем метода Objective-C. Например, инициализатор Swift

init(foo: Int, bar: Int) 

переводится в Objective-C как

- (instancetype)initWithFoo:(NSInteger)foo bar:(NSInteger)bar

и селектор будет

Selector("initWithFoo:bar:")

Протестировал это, и это действительно так, как сказал Мартин Р.

let mySelector: Selector = Selector("authentication:finishedWithAuth:error:")

Первый параметр для функции swift, как правило, безымянный, если посмотреть на его селектор.

Другие вопросы по тегам