Обертывание типа обратного вызова протоколами Swift

Допустим, я имею дело с библиотекой, которую не контролирую, и пытаюсь обернуть класс, определяющий тип обратного вызова, чтобы отделить мой код для целей тестирования. Вот класс внутри модуля AXSwift:

public class Application {
  public typealias Callback = (element: UIElement) -> ()
  public func createObserver(callback: Callback) -> Observer? {
    // ...
  }
}

Вот протокол оболочки для тестирования:

protocol UIElementProtocol {}
extension AXSwift.UIElement: UIElementProtocol {}

protocol ApplicationProtocol {
  func createObserver(callback: (element: UIElementProtocol) -> ()) -> Observer?
}
extension AXSwift.Application: ApplicationProtocol {}

Я получаю Тип «Приложение» не соответствует протоколу «ApplicationProtocol». Если я изменю UIElementProtocol внутри обратного вызова ApplicationProtocol на UIElement, это сработает. Но UIElement соответствует UIElementProtocol, так почему же это не работает?

Второй вопрос: есть ли лучший способ спроектировать API библиотеки, чтобы учесть такие вещи?


person tmandry    schedule 24.10.2015    source источник


Ответы (1)


Решение было действительно простым, просто внедрите протокол в расширение с помощью метода, который вызывает исходный метод:

extension AXSwift.Application: ApplicationProtocol {
  func createObserver(callback: (element: UIElementProtocol) -> ()) -> Observer? {
    return createObserver(callback as Callback)
  }
}

Где Callback — ожидаемый тип. По-видимому, вы должны явно указывать общий тип функции как более конкретный тип.

person tmandry    schedule 24.10.2015