이번 포스트에서는 iOS 앱의 생명주기에 대해서 알아보도록 하겠습니다. iOS 13에서 Scene이라는 개념이 나오면서, 생명주기의 개념에 변화가 생겼습니다. 이 포스트에서는 기존의 생명주기 개념과, 새롭게 도입된 생명주기를 알아보도록 하겠습니다.
이 포스트는 다음 문서를 참고하여 작성되었습니다.
Managing Your App’s Life Cycle
-
생명주기란
생명주기라는 것은 앱의 최초 실행부터 앱이 완전이 종료되기까지 앱이 가지는 상태와 그 상태들 사이의 전이를 뜻합니다. 앱의 상태는 앱이 현재 어떠한 것을 할 수 있는가를 결정합니다. 예를 들어, 포어그라운드의 상태의 애플리케이션은 유저와 직접 상호작용하기 때문에 시스템 자원 사용 등에서 우선순위를 가집니다. 반면 백그라운드 상태의 앱은 스크린에 드러나지 않기 때문에 작업을 하지 않거나, 하더라도 최소한의 작업만 수행해야 합니다.앱의 상태가 변하게 되면, 이 상태에 따라 앱의 행동을 조절해줘야 합니다. 이 조절 작업을 하기 위해서, UIKit은 특정 위임 객체(delegate object)에 메시지를 보내게 됩니다.
-
iOS 13이후에는 SceneDelegate를 사용할 수 있습니다. 이는 햐나의 앱이 여러개의 UI를 띄울 수 있게 되면서, 이 UI가 별도의 생명주기를 가질 필요가 생겼기 때문입니다. 따라서 기존 AppDelegate가 수행했던 생명주기 관리의 많은 부분이 SceneDelegate로 옮겨가게 되었습니다. 여기서 AppDelegate는 앱의 초기 구동과 앱 전체에 관련된 이벤트의 처리정도 만을 담당하도록 기능이 축소되었습니다.
-
iOS 12 이하의 경우에는 여전히 생명주기 관리에 AppDelegate를 사용합니다. iOS 13 이상이더라도 Scene을 지원하지 않게 만들었다면, 여전히 AppDelegate를 사용합니다.
-
Scene 기능은 Opt-in 기능(명시적으로 사용한다고 표시해야만 사용이 가능)이기 때문에 Info.plist에 UIApplicationSceneManifest 키를 추가해야 합니다. 설정 방법은 관련 가이드를 참조해주세요. 또한 iOS 12이하에서는 이 기능이 활성화 되더라도 appDelegate만을 사용하게 됩니다.
-
App 기반 생명주기
Scene을 지원하지 않는 경우, 모든 생명주기 관련 이벤트들은 appDelegate에 전달됩니다. appDelegate 객체는 app의 모든 window를 관리하기 때문에, 앱의 상태 변화는 앱의 모든 UI에 영향을 미칩니다.앱이 처음 실행되면, 앱은 LaunchScreen을 띄우고 앱을 실행시킬 준비를 합니다. 이때 앱 실행 전에 추가적인 요청이 없다면 inactive 상태가 됐다가 UI가 띄워지면 자동으로 active 상태로 전환되고, 추가적인 요청으로 처리해야할 일이 있다면 background 상태가 됩니다. background 상태에서 요청의 처리가 완료되면 inactive 상태로 갔다가 active 상태로 전환됩니다. 이러한 전환은 시스템에 의해 자동으로 일어나며, 앱은 종료될 때까지 active와 background 둘 중 하나의 상태를 가지게 됩니다. 이 때 중간 전환 단계인 Inactive 상태를 거칩니다.
- 앱이 최초로 실행되면, 앱의 자료구조와 UI를 초기화합니다.
- active 상태가 될 때, UI 설정을 마치고, 사용자와 상호작용 할 준비를 합니다
- inactive 상태가 될 때, 데이터를 저장하고, 앱의 주요 동작을 멈춥니다(아래 추가 설명을 참고해주세요).
- background 상태가 될 때, 중요한 작업을 마무리하고 메모리를 최대한 해제해줍니다. 또 앱의 스냅샷을 찍을 준비를 합니다.
- 앱이 종료되면 모든 작업을 멈추고, 모든 리소스를 해제합니다.
‘앱의 주요 동작을 멈추기’(quiet your app’s behavior)는 다음과 같은 것을 말합니다.
- 사용자 데이터를 디스크에 저장하고, 모든 파일을 담는다.
- DispatchQueue와 OperationQueue의 동작을 중단한다.
- 새로운 Operation이 스케쥴되지 않습니다.
- 모든 타이머를 무효화합니다.
- 게임을 자동으로 일시정지합니다.
-
Scene 기반 생명주기
Scene을 사용하는 앱이라면, Scene별로 별도의 생명주기를 가지게 됩니다. scene하나는 디바이스에서 돌아가는 앱의 UI 인스턴스 하나를 나타냅니다. 하나의 앱은 여러개의 scene을 가질 수 있으며, 이를 개별적으로 띄우거나 숨길 수 있습니다.사용자나 시스템이 새로운 scene을 만들어달라고 요청하면, UIKit은 이를 만들어 unattached 상태로 만듭니다. 사용자가 요청한 scene은 곧장 foreground inactive상태를 거쳐 active 상태가 되고, 시스템이 요청한 scene은 보통 background 상태가 되어 이벤트를 처리한 뒤에 foreground로 올라옵니다. 사용자가 앱의 UI를 닫게 되면, 해당하는 scene은 UIKit에 의해 background 상태로 갔다가 suspended 상태가 됩니다. UIKit은 언제든지 이 background나 suspended 상태인 scene을 회수해서 unattached 상태로 되돌려 놓을 수 있습니다.
-
scene이 UIKit에 의해 앱과 연결되면 scene의 초기 UI가 설정되고, scene이 필요한 데이터가 로드됩니다.
- foreground active 상태로 전환될 때, UI를 설정하고, 사용자와 상호작용할 준비를 합니다.
- foreground active상태에서 inactive상태가 될 때, 데이터를 저장하고 앱의 주요 동작을 멈춥니다.
- background 상태가 될 때, 중요한 작업을 마무리하고 메모리를 최대한 해제해줍니다. 또 앱의 스냅샷을 찍을 준비를 합니다.
- scene이 앱에서 연결이 해제될 때, scene에 관련된 모든 리소스를 해제한다.
- 앱의 최초 실행 같은 경우는 여전히 appDelegate를 거칩니다. 또한 Scene의 생성과 삭제시 appDelegate가 관여하게 됩니다.
-
앱의 생명주기를 잘 이용하면 여러 상황에 좀 더 잘 대처할 수 있는 견고한 애플리케이션을 만드는 데 도움이 됩니다.