티스토리 뷰

iOS

iOS App Life Cycle

경표다 2021. 7. 11. 21:49

Life Cycle(생명 주기), 즉 실행부터 종료까지의 주기

Launch Sequence

About the App Launch Sequence - Apple Developer Documentation

앱이 실행되는 과정은 아래의 그림으로 나타낼 수 있다.

  1. 앱이 유저 혹은 시스템에 의해서 실행된다
  2. 프로그램의 시작점인 main() 함수에 의해 UIKit의 UIApplicationMain(_:_:_:_:) 메소드가 호출된다
  3. UIApplicationMain(_:_:_:_:) 메소드를 통해 UIApplication 싱글톤 객체와 AppDelegate 객체가 생성된다. 또한 main storyboard 혹은 nib file의 기본 인터페이스를 로드하고 초기 세팅값(info.plist)을 불러오고 앱을 Main Run Loop에 올려서 이벤트 처리를 시작하도록 한다.
  4. UIKit이 AppDelegate의 application(_:willFinishLaunchingWithOptions:) 메소드를 호출한다
  5. UIKit이 state 복구 과정을 수행한다.
  6. UIKit이 AppDelegate의 application(_:didFinishLaunchingWithOptions:) 메소드를 호출한다]

이렇게 실행 초기화 과정이 끝나면 시스템이 UI를 보여주고 생명주기를 관리하기 위해 SceneDelegate 혹은 AppDelegate를 이용하게 된다.

 

 

위 과정에서 UIApplication 객체와 AppDelegate 객체가 생성되는 과정을 좀 더 들여다 보자면,,

 

iOS 앱은 C 기반 프로그램이고 모든 C언어 기반 프로그램의 시작점은 main() 메소드이다.

 

iOS 앱 프로젝트를 생성할때 언어를 Swift로 설정하여 생성하면 AppDelgate.swift의 @main annotation을 통해 앱 진입점이 설정되어 있어서 따로 잡아주지 않아도 된다.

(Xcode 12버전부터 main annotation이 @main 으로 바뀌었다. 그전에는 @UIApplicationMain 이었다. Xcode 11에서 @main 하면 아마 오류뜸.)

 

Objective-C로 설정하여 프로젝트를 만들면 main.m 파일에서 바로 그 main() 메소드를 확인할 수 있다.

이렇게 UIApplicationMain() 메소드를 호출하는 것을 확인할 수 있다.

 

Swift 기반 프로젝트에서도 굳이굳이 해보자면 해볼 수 있다.

이렇게 하면 AppDelegate에 @main annotation이 없어도 main.swift(이때 이름은 무조건 main.swift 여야함..) 파일을 추가해서 UIApplicationMain() 메소드를 UIApplicationDelegate 클래스를 지정해서 명시적으로 호출하면 잘 실행이 된다. 근데 대부분의 앱의 경우 main 메소드를 건드릴 일이 없다고 한다.

 

여기서 main 메소드를 건드려야 할 경우가 어떤 경우냐면,,,

 

UIApplicationMain() 메소드의 3번째 인자로 String 타입의 UIApplication 클래스 혹은 서브클래스의 이름을 받을 수 있는데, 바로 이 경우, UIApplication을 서브클래싱 해야하는 경우에만,, 가능하면 안하면 좋겠지만~ 굳이굳이 해야한다면~ 이 경우에만,,

 

그럼 굳이굳이 이 UIApplication을 서브클래싱 해야하는 경우가 도대체 언제인가??

설명에 나와있듯이 앱에 들어오는 이벤트를 시스템이 처리하기 전에 직접 처리해야 하는 경우에 UIApplication을 서브클래싱 후 sendEvent() 혹은 sendAction() 을 재정의 하면 된다. 그리고 super.sendEvent() 로 시스템한테 꼭 되돌려줘야 한다~ 라고 신신당부를 합니다..

 

이렇게까지 이벤트를 인터셉트해서 뭔가를 하는 앱이 내가 사용하는 앱 중에 있을까? 곰곰히 생각해봐도 적절한 예시가 안떠오름,,,

 

 

아무튼!! 여기까지 앱의 실행 과정 자체를 살펴보았고,, 이제 앱의 상태 변화를 보자면,,

 

App State

UIApplicationDelegate(AppDelegate)를 이용해서 앱 상태 변화에 따라 응답할 수 있는데, iOS 13 부터 UISceneDelegate를 이용한 scene 기반 앱에서는 각 Scene 별로 다른 상태 변화에 응답할 수 있다.

  • Respond to App-Based Life-Cycle Events
  • Respond to Scene-Based Life-Cycle Events

위 그림처럼, iOS 앱의 상태는 5가지로 볼 수 있다.

  • Not Running
    • 아무것도 실행하지 않은 상태
  • Inactive
    • 앱이 Foreground 상태로 돌아가지만 이벤트는 받지 않는 상태,, 상태 전환 과정에서 잠깐 머무는 단계
    • Active와 Background 사이의 전환일 때 잠깐 Inactive 상태가 된다. 예를 들어 시스템이 앱 앞쪽으로 Alert를 보여줄때(다른 앱에서의 푸시를 보여줄때를 말하는 것 같은데 잘 모르곘음.), 그리고 Application Switcher를 보여줄때(홈버튼 두번탭하면 나오는 그거인듯) 등
  • Active
    • 앱이 Foreground에서 돌아가고 있는 일반적인 상태
  • Background
    • 앱이 Suspended(유예) 상태로 진입하기 전에 거치는 상태
  • Suspended
    • 앱이 Background 상태에 있지만, 아무 코드도 실행하지 않는 상태, 시스템이 임의로 Background 상태의 앱을 Suspended 상태로 만듦

AppDelegate 혹은 SceneDelegate의 아래 메소드들을 이용해서 앱의 상태가 변할 때 수행할 작업들을 설정할 수 있다.

AppDelegate

 

SceneDelegate

 

 

참고 🔍 
https://medium.com/@neroxiao/ios-app-life-cycle-ec1b31cee9dc
https://hcn1519.github.io/articles/2017-09/ios_app_lifeCycle 
https://zeddios.tistory.com/539 
https://qiita.com/KenNagami/items/cbbe98b736fbdb24fef8 
https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle
https://developer.apple.com/documentation/uikit/1622933-uiapplicationmain
https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence

'iOS' 카테고리의 다른 글

[번역] WatchKit  (0) 2022.01.20
iOS status bar style 변경하기  (1) 2021.11.18
Bastard Injection  (0) 2021.08.17
iOS TextField memory leak  (0) 2021.07.16
swift static, class, final class  (0) 2020.08.02