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

#objective-c #oauth-2.0 #swift #selector #gtm-oauth2

#objective-c #oauth-2.0 #swift #селектор #gtm-oauth2

Вопрос:

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

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

 if (delegate_ amp;amp; finishedSelector_) {
  SEL sel = finishedSelector_;
  NSMethodSignature *sig = [delegate_ methodSignatureForSelector:sel];
  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
  [invocation setSelector:sel];
  [invocation setTarget:delegate_];
  [invocation setArgument:amp;self atIndex:2];
  [invocation setArgument:amp;auth atIndex:3];
  [invocation setArgument:amp;error atIndex:4];
  [invocation invoke];
}
  

Функция, которую я хотел бы вызвать, находится в моем swift 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» перед именем функции, но безрезультатно.

Комментарии:

1. Я предполагаю, что это должно быть Selector("authentication:finishedWithAuth:error:") , но на данный момент не могу его протестировать.

2. предположение @Martin верно, я его проверил. Селектор должен быть Selector("authentication:finishedWithAuth:error:")

Ответ №1:

Метод Swift

 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:")
  

Ответ №2:

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

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

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