Im using Coordinator pattern and therefore setting window.rootViewController I need to perform some async operations.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var coordinator : MainCoordinator!
//I have added the async to scene func
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) async {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
window?.windowScene = windowScene
coordinator = MainCoordinator(window: window!)
await coordinator.start()
MainCoordinator call for setting rootVC
lazy var rootViewController: UIViewController = UIViewController()
lazy var tabCoordinator: TabCoordinator = TabCoordinator(tabBarController: rootViewController as! UITabBarController)
func start() async {
if UserDefaults.standard.bool(forKey: "Logged") {
await showTabVC()
} else {
showLoginVC()
}
}
func showTabVC() async {
rootViewController = tabBarController
tabCoordinator = TabCoordinator(tabBarController: rootViewController as! UITabBarController)
let tabVC = await tabCoordinator.start()
window.rootViewController = tabVC
window.makeKeyAndVisible()
}
As the TabCoordinator class has start method that returns UIViewController it is marked with @MainActor so the UI can update as well after finishing with start method.
With code structured like this after running it I end up with black screen and I don't know why?
I have managed to make it work if I change the scene method from scene delegate by removing the async from scene method and placing coordinator.start inside Task{} everything works well:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
window?.windowScene = windowScene
coordinator = MainCoordinator(window: window!)
Task{
await coordinator.start()
}
What is the problem that async cause to scene method as I consider this as just another way that is less pleasant to read?
Adding
asyncto a method changes its type signature.and
are two different methods.
The
UIWindowSceneDelegateprotocol requires the synchronous method, so addingasyncto it means that the method isn't matching the protocol requirement anymore, hence it won't be called by the system.You don't get a compiler error for this due to the fact that the method is an optional protocol requirement, so not implementing it doesn't actually break the protocol conformance.