Estou tentando injetar dados genéricos em um View Controller usando um parâmetro genérico T
. Tenho um protocolo Coordinator
que declara um tipo associado T e uma data
variável do tipo T
. Meu AppCoordinator
adota o Coordinator
protocolo e declara o tipo de T
como a String
. Na minha AppCoordinator
classe, estou tentando definir os dados em um view controller usando o parâmetro genérico T
.
Meu pensamento é que a classe WelcomeViewController
adota um tipo concreto de AppData
for data
quando implementa o protocolo Navigable, e então eu deveria ser capaz de definir o tipo dos dados no AppCoordinator, que é String neste caso, e ser capaz de definir isso no controlador de visualização também. De alguma forma, suponho que para que isso funcione, o tipo T no protocolo Coordinator deve corresponder ao tipo T no protocolo Navigable, mas quando tento fazer isso definindo associated type T: Navigable.T
no protocolo Coordinator, por exemplo, recebo este erro: "Não é possível acessar o tipo associado 'T' de 'Navigable'; use um tipo concreto ou base de parâmetro genérico em vez disso".
Li Como injetar dependências em um controlador de visualização do iOS? e as seções: Os problemas que os genéricos resolvem, Funções genéricas, Parâmetros de tipo, Nomeando parâmetros de tipo, Restrições de tipo, Tipos associados, Cláusulas Where genéricas, Tipos associados a uma cláusula Where genérica, de Genéricos .
Como posso resolver isso?
protocol Coordinator<T> {
associatedtype T
var navigationController: UINavigationController { get }
var data: T? { get }
func start<T>(data: T?, viewController: any Navigable)
}
class AppCoordinator: Coordinator {
typealias T = String
var data: T?
init(data: T? = nil, navigationController: UINavigationController) {
self.data = data
self.navigationController = navigationController
}
var navigationController: UINavigationController
func start<T>(data: T?, viewController: any Navigable) {
var viewController = viewController
viewController.data = data
}
}
protocol Navigable<T> where T == AppData {
associatedtype T
var data: T? { get set }
}
enum AppData {
case coordinatorData
}
class WelcomeViewController: UIViewController, Navigable {
var data: AppData?
var appCoordinator: (any Coordinator)?
typealias T = AppData
override func viewDidLoad() {
setUp()
}
}
Você pode adicionar uma restrição genérica à sua
start
função para atingir seu objetivo:Agora você pode usar seu Coordenador assim: