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
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 👏