study record
[iOS] AppDelegate, SceneDelegate 본문
AppDelegate
AppDelegate는 App(application)이 해야할 일을 대신 구현한다는 의미이다.
앱이 해야할 일이란 백그라운드 진입, 포그라운드(Foreground) 진입, 외부에서의 요청 등이 있다.
1. 앱의 데이터 구조 초기화
2. 앱의 scene을 환경설정(Configuration) 하는 것
3. 앱 밖에서 발생한 알림(배터리 부족, 다운로드 완료 등)에 대응
4. 특정 scene, view, view controllers에 한정되지 않고 앱 자체 타겟이벤트에 대응
5. 애플 푸시 알림 서비스와 같이 실행 시 요구되는 모든 서비스 등록
AppDelegate 클래스 위에는 @main 어노테이션이 있다. 이 어노테이션으로부터 UIApllication이 AppDelegate가 본인의 역할을 위임받은 클래스임을 알 수 있다.
iOS13이전 12까지는 AppDelegate에서 작업을 다했지만 iOS 13부터 Session Lifecycle을 AppDelegate와 SceneDelegate가 나누어서 담당하고 있다.
iOS12까지는 하나의 앱에 하나의 window였지만 iOS13부터는 window의 개념이 scene으로 대체되고 하나의 앱에서 여러 개의 scene을 가질 수 있게 되었다.
AppDelegate 역할 중 하나였던 UI 상태를 알 수 있는 UILifeCycle을 SceneDelegate가 담당한다.
그리고 AppDelegate에 Session Lifecycle 역할이 추가되었다. Scene Session이 생성되거나 삭제될 때 AppDelegate에 알리는 메서드가 두개 추가되었다. Scene Session은 앱에서 생성한 모든 Scene의 정보를 관리한다.
AppDelegate 메서드
총 3가지의 메서드가 존재하는 것을 볼 수 있다.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
먼저 application:didFinishLaunchingWithOptions는 앱이 사용자에게 보여지기 전 초기화를 진행하는 단계이다.
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
AppDelegate에서 SceneSession을 통해 Scene에 대한 정보를 업데이트 받는다.
Scene Session이 새로 생겼을 때, SceneSession이 삭제되었을 때 호출되는 메서드이다. scene을 프로그래밍적으로 생성, 관리하는 메서드이다.
Scene, SceneSession이란?
Scene에는 UI의 하나의 인스턴스를 나타내는 windows와 view controllers가 들어있다. 또한 각 scene에 해당하는 UIWindowSceneDelegate객체를 가지고 있고, 이 객체는 UIKit과 앱 간의 상호작용을 조정하는데 사용한다. Scene들은 같은 메모리와 앱 프로세스 공간을 공유하면서 서로 동시에 실행된다. 결과적으로 하나의 앱은 여러 scene과 scene delegate객체를 동시에 활성화할 수 있다.
UISceneSession 객체는 scene의 고유의 런타임 인스턴스를 관리한다. 사용자가 앱에 새로운 scene을 추가하거나 프로그래밍적으로 scene을 요청하면 시스템은 그 scene을 추적하는 session 객체를 생성한다. 그 session에는 고유한 식별자와 scene의 구성 세부사항(configuration details)가 들어 있다. UIKit은 session 정보를 scene의 생애 동안 유지하고 사용자가 그 scene을 클로징하면 그 session을 파괴한다. session 객체는 직접 생성하지 않고 UIKit이 앱의 사용자 인터페이스에 대응하여 생성한다.
SceneDelegate
SceneDelegate는 화면에 무엇을 보여줄지 관리하는 역할을 한다.
scene(_: willConnectTo: options: )
UISceneSession life cycle에서 가장 먼저 불리는 메소드로 새로운 UIWindow를 생성하고 window의 rootViewController를 설정한다. 이 때의 window는 사용자가 보는 것이 아니라 앱이 작동하는 viewport이다. 첫 view를 만드는데 쓰이기도 하지만 과거에 disconnected된 UI를 되돌릴 때도 쓰기도 한다.
sceneWillEnterForeground(_ :)
scene이 세팅되고 화면에 보여지면서 사용될 준비가 완료된 상태이다. inactive -> active 전환 시에 불려진다.
sceneWillResignActive(_:)
active한 상태에서 inactive 상태로 빠질 때 불린다. 사용 중 전화가 오는 것처럼 임시적인 상황 때문에 발생할 수 있다.
sceneDidEnterBackground(_:)
scene이 포그라운드에서 백그라운드로 전환될 때 불리게 된다. 다음에 다시 포그라운드에 돌아올 때 복원할 수 있도록 상태 정보를 저장하거나, 데이터를 저장, 공유 자원 돌려주는 등의 일을 하도록 하면 된다.
sceneDidDisconnect(_:)
scene이 백그라운드로 들어갔을 때 시스템이 자원을 확보하기 위해 disconnect(scene이 이 메서드로 전해지면 session에서 끊어진다.)할 수도 있다. 이 메소드에서 가장 중요한 작업은 필요없는 자원을 돌려주는 것이다. 디스크나 네트워크를 통해 쉽게 불러올 수 있거나 생성이 쉬운 데이터들은 돌려주고, 사용자의 input과 같이 재생성이 어려운 데이터는 가지고 있게끔 하는 작업을 해준다.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var navigationController: UINavigationController?
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).
let rootVC = LaunchScreenVC()
rootVC.view.backgroundColor = .white
self.navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = self.navigationController
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
위와 같이 scene 내에서 일어나는 life cycle 이벤트에 대한 메서드가 정의되어 있다.
참고:
http://monibu1548.github.io/2018/08/28/appdelegate/
https://velog.io/@dev-lena/iOS-AppDelegate%EC%99%80-SceneDelegate
'iOS > iOS 정리' 카테고리의 다른 글
dequeueReusableCell(withIdentifier:for:) 의미와 장점 (0) | 2022.03.17 |
---|---|
[iOS] NotificationCenter (0) | 2022.03.16 |
[iOS] 왜 GCD(Grand Central DispatchQueue)를 사용하는가? (0) | 2022.03.07 |
[iOS] iOS TextView 행간, 자간 조절하기 (0) | 2022.03.02 |
[iOS] 스냅킷(SnapKit) inset과 offset (0) | 2022.03.01 |