Swift 5 e Xcode 11
Portanto, no xCode 11, a solução da janela não é mais válida dentro do appDelegate. Eles mudaram isso para o SceneDelgate. Você pode encontrar isso no arquivo SceneDelgate.swift.
Você notará que agora tem um var window: UIWindow?presente.
Na minha situação, eu estava usando um TabBarController de um storyboard e queria defini-lo como rootViewController.
Este é o meu código:
sceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
self.window = self.window ?? UIWindow()//@JA- If this scene's self.window is nil then set a new UIWindow object to it.
//@Grab the storyboard and ensure that the tab bar controller is reinstantiated with the details below.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
for child in tabBarController.viewControllers ?? [] {
if let top = child as? StateControllerProtocol {
print("State Controller Passed To:")
print(child.title!)
top.setState(state: stateController)
}
}
self.window!.rootViewController = tabBarController //Set the rootViewController to our modified version with the StateController instances
self.window!.makeKeyAndVisible()
print("Finished scene setting code")
guard let _ = (scene as? UIWindowScene) else { return }
}
Adicione isso ao método de cena correto, como fiz aqui. Observe que você precisará definir o nome do identificador para o tabBarController ou viewController que você está usando no storyboard.

No meu caso, eu estava fazendo isso para definir um stateController para acompanhar as variáveis compartilhadas entre as visualizações de guia. Se você deseja fazer o mesmo, adicione o seguinte código ...
StateController.swift
import Foundation
struct tdfvars{
var rbe:Double = 1.4
var t1half:Double = 1.5
var alphaBetaLate:Double = 3.0
var alphaBetaAcute:Double = 10.0
var totalDose:Double = 6000.00
var dosePerFraction:Double = 200.0
var numOfFractions:Double = 30
var totalTime:Double = 168
var ldrDose:Double = 8500.0
}
//@JA - Protocol that view controllers should have that defines that it should have a function to setState
protocol StateControllerProtocol {
func setState(state: StateController)
}
class StateController {
var tdfvariables:tdfvars = tdfvars()
}
Nota: Apenas use suas próprias variáveis ou o que você está tentando acompanhar, apenas listei o meu como um exemplo na estrutura tdfvariables.
Em cada visualização do TabController, adicione a seguinte variável de membro.
class SettingsViewController: UIViewController {
var stateController: StateController?
.... }
Em seguida, nesses mesmos arquivos, adicione o seguinte:
extension SettingsViewController: StateControllerProtocol {
func setState(state: StateController) {
self.stateController = state
}
}
O que isso faz é permitir que você evite a abordagem de singleton para passar variáveis entre as visualizações. Isso permite facilmente o modelo de injeção de dependência, que é muito melhor a longo prazo do que a abordagem singleton.