iOS

App Delegate / Scene Delegate Method

JoonSwift 2021. 1. 15. 01:34

iOS 프로젝트를 제일 처음 만들면 AppDelegate.swift, SceneDelegate.swift파일 이렇게 두가지가 생성됩니다. 

여기 내부에 있는 메서드에 대해서 한번 알아보겠습니다!

App Delegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    return true
}

우선 didFinishLaunchingWithOptions 메서드입니다. App Delegate의 역할은 Process의 life-cycle, Session의 life-cycle을 관리하는 두가지의 역할을 가지고 있습니다. 이 메서드는 Process의 life-cycle을 관리하는 메서드 중 하나라고 보면 될 것 같습니다.

사용자가 앱을 제일 처음 실행하면 앱에 대한 process의 실행이 거의 완료(almost done) 되었고, 앱이 실행될 준비가 거의 끝났다는 것을 delegate에게 알려주는 역할을 합니다. 

보통 앱에 필요한, 한번만 실행해야하는 non-UI Setup을 이 메서드에서 호출하기도 한다고 하네요!

 

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)
}	

다음은 configurationForConnecting 메서드입니다. 이 메서드는 Session의 life-cycle을 관리하는 메서드중 하나입니다. 

앞서 살펴보았던 didFinishLaunchingWithOptions 메서드가 호출되고 나면 이 메서드가 호출됩니다. 

시스템은 Scene Session을 만들게 됩니다. 실질적인 UIScene을 만드는 것은 아니고, UIScene에 대한 Configuration이 진행되는 메서드라고 생각하면 될 것 같습니다.

어떤 scene delegate, storyboard 또는 어떤 scene subclass를 사용할 것인지에 대한 설정을 하는 메서드라고 볼 수 있습니다!

Code를 통해 dynamic하게 만들 수도 있고, Info.plist를 활용해 static하게 만드는 방법도 있습니다. 

 

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.
}

다음은 didDiscardSceneSessions 메서드 입니다. 이 메서드 역시 Session의 life-cycle을 관리하는 메서드중 하나이고, 대표적으로 실행중이던 앱을 홈화면으로 나와서 App Switcher에서 실행을 종료시켜버릴 때 호출되는 메서드 입니다. 

delegate에 유저가 하나 또는 여러개의 앱 scene을 app switcher에서 종료했다는 것을 알려주는 역할을 합니다. 그리고 이 메서드를 사용해서 앱의 데이터 구조를 업데이트 하거나, scene과 관련한 모든 자원들을 release할 수 있습니다!

 


Scene Delegate

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).
    guard let _ = (scene as? UIWindowScene) else { return }
}

App Delegate에서 Scene Session에 대한 Configuration이 끝나면 Scene Session이 생성되면서 이 메서드를 호출합니다. 하지만 유저에게 보여지는 UI는 아직 없을 것 입니다. 그렇기에 이 메서드에서 UIWindowScene을 등록하는 과정을 거치게 됩니다. 

delegate에게 앱에 scene이 추가되었다는 것을 알려주는 역할이라고 공식문서에 적혀있으며, 주로 앱이 UI 인스턴스를 생성하거나 복원할 때 호출됩니다.

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).
}

sceneDidDisconnect 메서드입니다. 

delegate에게 UIKit이 scene을 앱에서 제거해 버렸다는 것을 알려주는 메서드입니다. 

scene이 메모리에서 제거되기 전에 이 메서드를 사용해서 최종 정리를 하는 코드들을 구현하는 메서드로 사용할 수 있겠습니다. 

여기서 Disconnect란 scene을 메모리에서 release하는것. 즉, scene delegate가 메모리에서 release될 것이고, scene delegate가 들고있는 view hierarchies와 window hierarchies 또한 release해줄 것 입니다.

하지만 유저가 다시 돌아올 시를 대비해서, 유저가 하던 작업이나 데이터를 완전히 지우지는 않습니다!

 

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.
}

sceneDidBecomeActive 메서드입니다.

scene이 inactive 상태에서 active 상태로 전환되었을 때에 호출되는 메서드입니다. 

여기서 active상태란 Foreground에서 사용자에 의한 event들을 받을 수 있는 상태가 된 것을 의미합니다. 

 

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).
}

sceneWillResignActive 메서드입니다.

Resign은 사직하다는 의미를 가지고 있습니다. Scene이 active상태에서 inactive상태로 전환될 때 호출하는 메서드입니다. 대표적인 경우로, 앱을 사용하는 도중에 alert가 오거나, 전화가 오는 등의 인터럽트가 발생하면 호출되는 메서드입니다.

만약 유저가 사용중이던 scene에 저장하지 않은 data가 있다면 그것을 잃어버리지 않도록 이 메서드에서 저장합니다. (하지만 이 방법으로만 데이터를 저장하는 것은 좋지 않다고 하네요!) 간단하게 유저가 입력하고 있던 데이터 같은 것만 저장하지 중요한 데이터를 저장하는 것은 금물!

User가 앱을 swipe해서 홈화면으로 돌아갈때도 실행되는 메서드 입니다. 이 메서드가 호출되고 난 후에 didEnterBackground메서드를 호출합니다.

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.
}

sceneWillEnterForeground 메서드입니다. 

scene이 background에서 foreground로 이동할 때 호출되는 메서드입니다.

즉, delegate에게 scene이 foreground에서 시작될 것이고, user에게 보여질 것 이라는 것을 말해주는 역할을 가지고 있습니다. UIKit은 scene이 Foreground로 가기 직전에 이 메서드를 호출하고, 이 Foreground로 이동한다는 것은 foreground에 scene이 새로 생기거나 connected될 때 그리고 background에 있던 scene이 다시 foreground로 올라올 때를 의미합니다. 

 

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.
}

sceneDidEnterBackground 메서드입니다.

User가 앱을 swipe하여 홈화면으로 나오고 난 후 willResignActive메서드 다음에 호출되는 메서드입니다.

이후에는 didDisconnect 메서드가 호출됩니다.

즉, delegate에게 scene이 background에서 돌아가고(running) 있고, 더이상 onscreen상태가 아니라는 것을 알려주는 메서드입니다. 이 메서드가 반환되면 UIKit은 app switcher에 보여주기 위한 scene의 interface의 snapshot을 찍습니다.

 

참고 문헌

developer.apple.com/documentation/uikit/uiscenedelegate

 

Apple Developer Documentation

 

developer.apple.com

developer.apple.com/documentation/uikit/uiapplicationdelegate

 

Apple Developer Documentation

 

developer.apple.com

WWDC 2019 Architecting Your App for Multiple Windows 세션

'iOS' 카테고리의 다른 글

Asynchronous Operations Unit Test (URLSession Unit Test)  (0) 2021.01.27
iOS Application Life Cycle  (0) 2021.01.18
iOS UITableView  (0) 2020.12.23
ScrollView AutoLayout(with Code)  (0) 2020.12.22
Unit Test (XCTest)  (0) 2020.12.16