2015-10-14 2 views
0

Я пишу контроллер представления веб-оболочку, которая динамически использует наиболее подходящий класс просмотра веб-страниц в зависимости от версии прошивкой, на котором она выполняется:Объявите переменную независимо от конкретного общего типа в Swift 2

protocol WebViewCommon: class { 
    func loadURL(url: NSURL) 
    func disableBouncing() 
    func haveLoadedPage() -> Bool 
} 

class WebWrapperViewController<T where T: UIView, T: WebViewCommon>: UIViewController { 

    var loginUrl: NSURL! 
    var webView: T! 

    // ... 
} 

я тогда нужно создать экземпляр правильного дженерик следующим образом:

var webWrapperVC: WebWrapperViewController // compiler error 

    if #available(iOS 8.0, *) { 
     webWrapperVC = WebWrapperViewController<WKWebView>() 
    } else { 
     webWrapperVC = WebWrapperViewController<UIWebView>() 
    } 

    webWrapperVC.loginUrl = targetURL // access WebWrapperViewController specific API 
    self.window!.rootViewController = webWrapperVC 

var декларация не компилируется, со следующей ошибкой:

Reference to generic type 'WebWrapperViewController' requires arguments in <...>

До сих пор я пытался:

var webWrapperVC: WebWrapperViewController<UIView<WebViewCommon>> 

(что приводит к: "Тип 'UIView' не соответствует протоколу 'WebViewCommon'")

и

var webWrapperVC: WebWrapperViewController<T where T: UIView, T: WebViewCommon> 

(что приводит к: «Ожидаемому»> «для заполнения списка общих аргументов»)

Мой вопрос: поэтому: Какая правильная декларация var в этом случае? Поскольку мне нужно получить доступ к API, который относится к WebWrapperViewController, объявление var должно включать этот тип.

+1

Почему не является обязательным? var webWrapperVC: WebWrapperViewController? – dirtydanee

+0

Поскольку я использую оператор 'if-else', переменная определенно будет инициализирована. На самом деле, даже Swift объявляет как «пусть» здесь. И объявление как необязательное не приводит к ошибке компилятора. –

ответ

0

Я не думаю, что вам нужно использовать дженерики в этом случае. Вместо этого у вас есть протокол. Определите контроллер представления без дженериков и используйте протокол как тип для webView.

class WebWrapperViewController: UIViewController { 

    var loginUrl: NSURL? 
    var webView: WebViewCommon? 

    // ... 
} 
+0

Затем я получаю эту ошибку компилятора: «WebWrapperViewController» требует, чтобы «WebViewCommon» наследовал от «UIView», поэтому я также попробовал «var webWrapperVC: WebWrapperViewController >' –

+0

Если это в 'WebWrapperViewController', то: 'var webWrapperVC: WebWrapperViewController ' –

+0

Извините - это в подклассе 'UIApplicationDelegate'. Я попытался переместить логику, из которой генерическая версия построена на статический заводский метод в «WebWrapperViewController», но столкнулась с той же проблемой с типом возврата этой функции и 'WebWrapperViewController ' не покрывала его. –

Смежные вопросы