Jak ustawić ekran wejściowy z poziomu kodu w Scene Delegate

Opublikowano

Tworząc aplikacje dla iOS przyzwyczailiśmy się już, że wszelkie ustawienia oraz akcje związane z cyklem życia aplikacji realizujemy z poziomu AppDelegate. Np. ustawienie początkowego ekranu poprzez przypisanie ViewController’a do UIWindow. Takie podejście skończyło się wraz z wprowadzeniem nowej wersji iOS 13.0, w której możliwe stało się uruchomienie wielu ekranów danej aplikacji prezentujących różną treść. Często jest to wykorzystywane np. w iPadach. Łatwo sobie wyobrazić kilka okien notatnika, które możemy także otwierać w widoku wielu okien, pracując jednocześnie nad tekstem i czytając książkę w drugim oknie. 

Obsługa tej nowej funkcjonalności możliwa jest dzięki wprowadzeniu SceneDelegate. To właśnie tutaj następuje aktualnie ustawienie okien oraz zachowania w poszczególnych fazach cyklu życia aplikacji. Domyślnie, jako pierwszy ekran załadowany zostanie ViewController ustawiony jako Root View Controller w pliku main.storyboard. Tak było dawniej gdy używany był AppDelegate oraz tak jest aktualnie gdy wszedł SceneDelegate.

Jednakże korzystając z dobrych praktyk, często chcielibyśmy ustawić ekran wejściowy aplikacji ręcznie, z poziomu kodu . Poniżej postaram się opisać ten proces krok po kroku.

1. Usuń niepotrzebne pliki

Po utworzeniu nowego projektu, automatycznie zostają utworzone pliki: Main.storyboard oraz ViewController. Usuwamy je.

2. Zaktualizuj Info.plist

Aktualnie w pliku Info.plist zachowane są informacje dot. wykorzystania ekranu zdefiniowanego w pliku Main.storyboard jako ekranu wejściowego. Musimy zaktualizować te parametry wg następującego schematu (odpowiednie rekordy zaznaczono także na rysunku poniżej):

  • usunąć rekord Storyboard Name
  • usunąć rekord Main storyboard file base name
Plik Info.plist

Uruchomienie aplikacji na tym etapie spowoduje wyświetlenie czarnego ekranu, co jest rezultatem pożądanym, jako że został odpięty domyślny ekran startowy zdefiniowany w Main.storyboard.

3. Utwórz nowy ekran

Na tym etapie utwórz nowy ekran, który wykorzystasz jako ekran wejściowy. Na potrzeby tego tutorial’a wykorzystam także bibliotekę Fastlee (mojego autorstwa), która usprawnia konfigurację i zarządzanie koordynacją ekranów poprzez wzorzec Coordinator.

Jeśli chcesz pominąć wykorzystanie biblioteki Fastlee, możesz stworzyć własny ViewController, który wykorzystasz do przypisania w SceneDelegate. Natomiast w przypadku wykorzystania wzorca Coordinator, który zasadniczo polecam, rozpoczniemy od utworzenia głównego koordynatora aplikacji – MainCoordinator oraz LoginCoordinator – odpowiedzialny za proces autentykacji:

import Foundation
import Fastlee

class LoginCoordinator: NavigationCoordinator {
    
    override func start() {
        let view = LoginModule.build(for: self)
        setViewControllers([view], animated: false)
    }
}
import Foundation
import Fastlee

class MainCoordinator: AppCoordinator {
    
    override func start() {
        let flow = LoginCoordinator()
        add(coordinator: flow)
        setRoot(flow.navigationController)
    }
}

Mając przygotowane wszystkie powyższe komponenty, przejdź do skonfigurowania hierarchii widoku z poziomu kodu.

4. Konfiguruj SceneDelegate

Otwórz klasę SceneDelegate znajdującą się w pliku SceneDelegate.swift w której dodasz implementację w funkcji odpowiedzialnej za podłączenie sceny do sesji:

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    var appCoordinator: MainCoordinator!

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let scene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: scene)
        appCoordinator = .init(window: window!)
    }

// ...
}
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scene = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: scene)
    window?.rootViewController = LoginViewControler()
    window?.makeKeyAndVisible()
}

5. Podsumowanie

W tym momencie uruchamiając aplikację powinien Ci się ukazać ekran przypisany do UIWindow. Gratulacje 👏

Autor: macuser

Na co dzień pracuje jako iOS Developer, a w czasie wolnym uwielbia tworzyć muzykę w swoim domowym studio. Lubi czytać książki na temat psychologii, technik marketingu, oraz być ciągle na bieżąco z nowymi trendami w świecie technologii.