앱의 실행과정과 Application Life Cycle

Jayven·2024년 5월 6일
0

iOS

목록 보기
1/4
post-thumbnail

안녕하세요 제이븐 입니다 😁
이번에는 앱이 실행되는 과정과 Application Life Cycle에 대해서 포스팅하려고 합니다.

  1. 앱이 실행되는 과정
  2. iOS Application Life Cycle
  3. iOS 13 버전 이전과 후의 라이프 사이클의 변경점
  4. Scene이란?
  5. AppDelegate, SceneDelegate
  6. 앱의 실행상태

순서대로 알아보겠습니다!


Application Life Cycle 란?


앱의 생명 주기는 앱이 실행되는 순간부터 종료되어서 메모리에서 해제 되기까지의 프로세스를 의미합니다

iOS에서는 다양한 상태를 거치면서 사용자 인터렉션, 시스템 상호작용과 같은 다양한 작업을 수행합니다.
앱의 생명주기를 이해하는게 중요한 이유는 생명주기를 통해서 효율적인 자원관리, 사용자 데이터 보호, 최적의 경험들을 제공할 수 있기 때문입니다.


앱이 실행되는 과정


iOS Application Lifecycle

애플리케이션 라이프 사이클 이미지입니다 위에부터 순서대로 알아보겠습니다.

1. 앱 실행

앱 아이콘을 터치해서 앱을 실행합니다.


2. main() 함수 호출

앱이 시작할 때, 일반적으로 모든 C 기반 애플리케이션과 마찬가지로 main() 함수에서 실행이 시작됩니다.
여기서 앱의 실행을 위한 초기 설정을 수행하고 UIApplicationMain()을 호출합니다.

Xcode가 자동으로 @main 어노테이션이 붙은 App 또는 UIApplicationDelegate 클래스를 사용하여 앱의 시작점을 처리합니다.

UIKit

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
}

SwiftUI

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

3. UIApplicationMain() 함수 호출

앱이 실행될 때 UIApplicationMain() 함수가 호출됩니다.
이 함수는 앱의 진입점(Entry Point)으로 몇가지 중요한 작업을 수행합니다.

  • UIApplication 객체를 생성합니다.

    • UIApplication 객체는 singleton 형태로 생성되어, UIApplication.shared의 형태로 앱 전역에서 사용할 수 있습니다.
    • 가장 중요한 역할은 사용자 이벤트에 반응하여 앱의 초기 설정을 하는 것입니다. (routing, handling)
  • 앱의 delegate, 즉 AppDelegate 객체를 생성하고, 이를 UIApplication의 delegate로 설정합니다.

실행할 준비를 마쳤다면 application(_:didFinishLaunchingWithOptions:) 를 호출합니다.


4. Event Loop

application(_:didFinishLaunchingWithOptions:) 메소드가 true를 반환하면, 앱은 메인 이벤트 루프를 실행합니다. 이 루프는 사용자의 입력을 처리하고, 화면을 갱신하며, 시스템 이벤트를 처리하는 역할을 합니다. 앱은 이 이벤트 루를 통해 계속해서 실행 상태를 유지합니다.

이 과정을 자세히 보면 다음과 같은 단계로 이루어 집니다.

1. 이벤트 발생
사용자의 상호작용이 발생하면, 터치 스크린, 마우스, 키보드 등의 하드웨어 장치에서 이벤트가 생성됩니다. 이는 사용자가 장치를 조작할 때마다 발생합니다.

2. 운영 시스템(OS)에 의한 이벤트 캡처
생성된 이벤트는 운영 시스템에 의해 캡처됩니다. iOS나 macOS와 같은 시스템에서는 이러한 이벤트들이 먼저 OS 레벨에서 처리되어 필터링되고, 적절한 형태로 변환됩니다.

3. 이벤트 포트를 통한 전달
OS는 이벤트를 애플리케이션의 이벤트 포트로 전달합니다. 이 포트는 애플리케이션과 OS 간의 커뮤니케이션 채널 역할을 하며, 이벤트가 앱에 도달할 수 있도록 합니다.

4. 이벤트 큐
이벤트 포트를 통해 전달된 이벤트들은 이벤트 큐에 저장됩니다. 이 큐는 FIFO(First In, First Out) 방식으로 관리되며, 이벤트가 순차적으로 처리될 수 있도록 합니다.

5. 메인 런 루프
앱의 메인 런 루프는 지속적으로 이벤트 큐를 감시하며, 새로운 이벤트가 큐에 들어오면 이를 꺼내 처리합니다. 메인 런 루프는 애플리케이션의 핵심 처리 루프로서, UI 업데이트, 이벤트 처리, 애니메이션 등 애플리케이션의 주요 활동을 담당합니다.

6. 이벤트 처리
메인 런 루프에 의해 이벤트가 처리되면, 이벤트에 해당하는 액션(버튼 클릭 반응, 스크롤 이동 등)이 실행됩니다. 이 과정에서 필요에 따라 추가적인 이벤트가 생성되고, 반응이 사용자에게 표시됩니다.

5. 앱 종료

앱이 종료되었다면 AppDelegate의 applicationWillTerminate를 호출합니다.

  • 개발자는 이 시점에서 필요한 데이터를 저장하거나, 진행 중인 작업을 정리하고, 세션을 종료하는 등의 정리 작업을 수행할 수 있습니다.

정리

  1. 앱의 실행
  2. main() 호출
  3. UIApplicationMain() 함수 호출
  4. UIApplication 객체 생성
  5. AppDelegate 객체 생성 이를 UIApplication의 delegate로 설정
  6. didFinishLaunchingWithOptions 호출
  7. 메인 런 루프
  8. 앱종료
  9. WillTerminate 호출

UIApplicationMain, UIApplication

UIApplicationMain
애플리케이션 객체와 애플리케이션 델리게이트를 생성하고 이벤트 주기를 설정합니다.

UIApplication


Life Cycle Change


~ iOS 12 버전

iOS 12 이하 버전에서는 UIApplicationDelegate 객체를 사용해서 생명주기 이벤트에 대응했습니다.

iOS 12 이하 버전에서는 AppDelegate가 2가지 역할을 가지고 있었습니다.

  • Process Lifecycle
    • Process 에서의 Event를 알려준다.
  • UI Lifecycle
    • Application의 UI의 상태를 알려준다.

이 구조는 하나의 앱이 하나의 Process와 하나의 User Interface객체와 매칭되었습니다.


iOS 13 ~ 버전

iOS 13 이상 버전에서는 UIScenecDelegate에서 Scene기반의 앱의 생명주기 이벤트에 대응합니다.

iOS 13 이상 버전부터는 하나의 Process를 사용하는건 이전과 동일하지만 다수의 UI 객체나 Scene Session들을 가지게 됩니다.

그래서 AppDelegate의 Process Lifecycle은 유지하면서 UI Lifecycle을 SceneDelegate로 분리했습니다.


새로 추가된 Session Lifecycle

새로운 Scene Session이 생성되거나 기존에 존재하던 Scene Session이 사라지는 경우 알 수 있게 됐습니다.


iOS 13으로 넘어 오면서 바뀐 점 요약

  • AppDelegate의 UICycle부분을 SceneDelegate가 대체합니다.
  • AppDelegate에 Session LifeCycle이 추가 되었습니다.
  • 하나의 앱에서 여러개의 scene을 가질 수 있게 되었습니다.

UIScene


UIScene

Scene은 독립적인 사용자 인터페이스 인스턴스를 나타냅니다. 각 Scene은 여러 개의 윈도우(UIWindow)와 뷰 컨트롤러(UIViewController)를 포함할 수 있으며, 이러한 구성 요소들을 통해 앱의 시각적인 내용을 관리합니다.

각 Scene은 UIWindowSceneDelegate를 가지고 있으며, 이 델리게이트는 UIKit과 앱 사이의 상호작용을 관리합니다. 이를 통해 Scene의 생명 주기 이벤트에 반응할 수 있습니다.

Scene들은 같은 메모리와 앱 프로세스 공간을 공유하며 동시에 실행될 수 있습니다. 이는 하나의 앱에서 여러 개의 Scene을 동시에 사용할 수 있게 하며, 이를 통해 앱은 다중 화면 또는 다중 태스킹 환경에서 효과적으로 작동할 수 있습니다.


UIWindowScene

UIWindowScene

UIWindowScene은 UIScene의 하위 클래스로, 윈도우 기반의 UI를 관리합니다. 각 UIWindowScene 객체는 하나 이상의 UIWindow를 포함할 수 있으며, 각 윈도우는 앱의 실제적인 콘텐츠를 표시하는 데 사용됩니다. 예를 들어, 다중 디스플레이 환경에서 각각의 디스플레이는 별도의 UIWindowScene을 가질 수 있습니다.

공식문서에서 UIScene을 직접 사용하는것은 권장되지 않습니다. 이는 UIWindowScene이 윈도우 기반의 UI를 관리하기 위해 특화된 UIScene의 구현이기 때문입니다.


AppDelegate


UIApplicationDelegate
위에서 말한 UIApplicationMain() 함수에서 AppDelegate 객체를 생성하는데 그게 바로 이 객체이다. UIApplicationDelegate protocol을 채택하고 있다.

AppDelegate Default Method

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    // App이 실행 되면서 앱의 설정이 완료되었을 때 호출되는 메서드
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        //  앱의 초기 설정을 수행합니다. UIScene이 도입된 이후에는, 이 메서드에서 UIScene 설정을 제외한 일반적인 초기화 작업을 처리합니다.
        return true
    }

    // MARK: UISceneSession Lifecycle (iOS 13 이상에서 추가된 메서드)
    
    // 사용자나 시스템에 의해 새로운 UIScene 인스턴스가 생성될 때 호출됩니다. 즉, 앱에 새로운 윈도우나 뷰가 추가될 필요가 있을 때마다 이 메서드가 실행되어 적절한 UISceneConfiguration을 제공합니다.
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // 새 UIScene의 구성을 설정
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    // 유저가 app switcher를 통하여 Scene을 닫을 때 호출
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // 닫힌 UIScene 세션 처리 로직
    }
}

SceneDelegate


UISceneDelegate
UIScene 인스턴스의 생명주기를 관리합니다.

SceneDelegate Default Method

Scene의 상태들에 관련된 Default Method

    // Scene이 생성되고 시스템에 연결될 때 호출됩니다. 이 메서드를 통해 초기 UI 설정을 구성하고 필요한 데이터를 로드할 수 있습니다.
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
    }
    
    // Scene의 연결이 끊겼을 때 호출됩니다. 이 메서드는 Scene이 메모리에서 제거될 때 필요한 정리 작업을 수행하는데 사용됩니다.
    func sceneDidDisconnect(_ scene: UIScene) {
        
    }
    
    // Scene이 활성 상태가 되었을 때 호출됩니다. 씬이 활성화되면 이 메서드를 통해 앱이 사용자와의 상호작용을 시작할 준비를 합니다
    func sceneDidBecomeActive(_ scene: UIScene) {
        
    }

    // Scene 이 비활성 상태로 전환될 때 호출됩니다. 이 메서드는 예를 들어 사용자가 앱을 Background로 전환하거나 전화 통화를 받을 때 호출됩니다.
    func sceneWillResignActive(_ scene: UIScene) {
        
    }

    // Scene이 Foreground로 진입할 준비가 될 때 호출됩니다. 이 메서드는 앱이 사용자에게 다시 보이기 직전에 필요한 준비를 수행합니다.
    func sceneWillEnterForeground(_ scene: UIScene) {
        
    }

    // Scene이 Background 상태로 전환될 때 호출됩니다. 이 메서드는 데이터 저장, 사용자 세션 정리 등 백그라운드로 진입하기 전에 필요한 작업을 수행합니다.
    func sceneDidEnterBackground(_ scene: UIScene) {
        
    }

앱 실행 상태


iOS 13 이상 버전에서 Scene이라는 개념이 도입 되면서 하나의 앱이 여러 개의 Scene을 가질 수 있게 되었습니다.
Scene에 개별적인 Life Cycle이 존재하고 각 Scene 별로 다른 상태를 가지고 있을 수 있습니다.

각 Scene은 아래와 같은 상태 전환을 보여줍니다.

Unattached

UIScene 객체가 생성되었으나 아직 시스템에 의해 활성화되거나 어떠한 UIWindowScene에도 연결되지 않은 상태입니다.

앱이 시작될 때 각 UIScene 인스턴스는 처음에 이 상태에 있습니다. 사용자에 의해 앱이 처음 열리거나, 외부 디스플레이에 연결될 때 새로운 UIScene이 생성되고 초기 구성을 기다립니다.

Foreground - Inactive

앱이 전면에는 있지만, 아직 활성 상태는 아닌, 일시적으로 비활성화된 상태입니다.

이 상태는 주로 시스템이나 다른 앱의 중요한 UI 상호작용이 필요할 때 발생합니다. 예를 들어, 사용자가 알림을 받거나 설정을 변경하는 동안, 전화가 오는 경우 등이 이에 해당합니다. 이 때 앱은 사용자의 입력을 받지 않습니다.

Foreground - Active

앱이 전면에서 활성화되어 사용자와 완전히 상호작용할 수 있는 상태입니다.

사용자가 앱을 직접 조작하고 있을 때 이 상태입니다. 대부분의 UI 업데이트, 이벤트 처리, 데이터 통신 작업이 이때 이루어집니다.

Background

앱이 백그라운드에서 실행되고 있지만 사용자에게 보이지 않는 상태입니다.

사용자가 홈 버튼을 누르거나 다른 앱을 전면으로 열어 앱이 백그라운드로 전환될 때 이 상태가 됩니다. 백그라운드에서 앱은 오디오 재생, 위치 업데이트, 완료해야 할 네트워크 요청 등 제한된 작업을 계속 수행할 수 있습니다.

Suspended

앱이 메모리에는 존재하지만, 어떠한 코드도 실행되지 않는 상태입니다.

시스템이 자원을 절약하기 위해 백그라운드 앱을 중지시킬 때입니다. 앱은 이 상태에서는 CPU 자원을 사용하지 않으며, 필요시 시스템에 의해 메모리에서 제거될 수 있습니다. 이 상태에서 앱을 다시 전면으로 가져오려면, 메모리 내의 상태가 유지되어 있는 경우 빠르게 재개될 수 있습니다.

UIScene.ActivationState


참고자료


https://velog.io/@minni/iOS-Application-Life-Cycle
Managing your app’s life cycle 공식 문서


마무리


이번에는 앱의 실행과정부터 Application Life Cycle에 대해서 쭉 정리를 해보았는데 이번 포스팅을 하게된 이유는 앱이 어떤 방식으로 실행되고 어떠한 생명주기는 갖고 있는지에 대한 부분이 궁금했고 이미 아는 부분 그리고 자주 사용해서 익숙한 부분도 있었지만 다시 공부하면서 많은 부분을 다시 되짚어보는 시간이었던 것 같습니다

그리고 애플 공식문서 App and evironmnet에 Life cycle에서 많은 정보를 얻을 수 있었습니다.
역시 공식문서를 통해서 많은 정보를 얻을 수 있었지만 영어로 되어있다보니 볼 수록 집중력이 떨어지는건 저만 그런건지 모르겠네요... ㅠㅠ

시간이 오래 걸릴 수도 있지만 정확한 정보를 습득하려면 공식문서만한게 없는 것 같습니다
앞으로 자주 보고 익숙해지려고 노력해야 될 것 같네요 ㅠㅠ

질문과 피드백은 언제나 감사합니다 🙇🙇

profile
iOS 개발자

0개의 댓글