🚴🏻 app life cycle 이란?
app 의 life cycle 이라는 것은 앱의 생명 주기를 의미한다.
우리 앱이 켜지고, 데이터 들이 메모리의 올라가고, 앱을 끈 것은 아니지만 다른 앱을 사용하고 있고, 결국에는 앱을 종료하게 되는 이 주기를 말한다.
애플에서는 이러한 상태에 맞춰서 호출 되는 메서드들을 정의해 놓았다.
그래서 어떤 메서드가 언제 호출 되는지 알고 있다면, 그 상태에 맞는 적절한 대응을 해줄 수 있다.
(예를 들면 앱이 꺼지기 전에 데이터를 저장 한다든지 하는...)
📱 앱의 상태
Not Running
앱이 시작되지 않았거나 실행되었지만 시스템에 의해 종료된 상태
Inactive
앱이 전면에서 실행 중이지만, 아무런 이벤트를 받지 않고 있는 상태
Active
앱이 전면에서 실행 중이며, 이벤트를 받고 있는 상태
Background
앱이 백그라운드에 있지만 여전히 코드가 실행되고 있는 상태, 대부분의 앱은 suspended 상태로 이행하는 도중에 일시적으로 이 상태에 진입하지만 파일 다운로드, 업로드, 연산 처리 등 여분의 실행 시간이 필요한 경우 특정 시간 동안 이 상태로 남아있는다.
Suspended
앱이 메모리에 유지되지만 실행되는 코드가 없는 상태, 메모리가 부족한 상황이 오면 Suspended 상태에 있는 앱들을 특별한 알림 없이 정리한다.
🧪 호출하는 메서드들
(출처: 공식문서 이미지를 2차 가공하여 만듬 feat siwon)
전체적으로는 이런 식으로 작동한다.
원래는 AppDelegate 에서 모든 것을 처리했지만
split view 가 등장하면서 scene 의 상태 == app 의 상태
라는 공식이 깨지면서 AppDelegate 와 SceneDelegate 가 이 역할을 나눠 가지게 되었다.
이에 대한 자세한 내용은
WWDC: Architecting Your App for Multiple Windows
이 WWDC를 보면 소개하고 있다.
이제부터 저 그림에 나온 메서드들을 하나씩 살펴보자.
📱 AppDelegate에서 실행되는 메서드
앱이 준비를 완료 했을 때
func application(_:willFinishLaunchingWithOptions:) -> Bool
func application(_:didFinishLaunchingWithOptions:) -> Bool
프로세스가 실행될 준비가 (앱이 준비)완료되기 직전에 willFinish
완료 된 후에 didFinish
메서드를 호출해 앱이 원활한 작동을 할 수 있는지 Bool값을 통해 dalegate에게 알린다.
앱이 URL 리소스를 처리할 수 없거나 사용자의 작업을 처리할 수 없다고 판단하면, false를, 정상 작동이 가능하면, true를 반환한다.
해당 메서드는 window 및 UI가 표시되기 전에 호출되며,
이후 포그라운드 또는 백그라운드로 진입하기 위해 delegate의 해당 상태로 진입할 수 있는 메서드를 호출한다.
앱이 씬을 만들 때
func application(_:configurationForConnecting:options:)
AppDelegate는 위의 메서드를 통해 새로운 Scene 객체에 사용될 UISceneConfiguration
객체를 생성해 반환한다.
UISceneConfiguration
객체는 새로 생성할 Scene의 SceneDelegate, Storyboard, Scene 객체 등 세부 정보를 담고 있다.
표를 보면 알겠지만 이
특정한 씬을 삭제 했을 때
func application(_:didDiscardSceneSessions:)
해당 메서드는 사용자가 특정 scene을 제거하였을 때 메모리에서 해당 scene객체를 삭제하기 위해 호출한다.
또한 시스템 판단해 해당 메서드를 호출하는 경우도 있는데 이는 해당 scene를 표시할 수 없다고 판단되면, 해당 메서드를 호출해 해당 scene을 메모리에서 해제한다. 만약 앱이 실행되고 있지 않다면 앱이 시작될때 해당 메서드를 호출한다.
하지만, 시스템이 메모리 확보만을 위해서 해당 메서드를 호출하지 않는다고 한다.😅
앱이 제거 되기 직전에
func applicationWillTerminate(_ application: UIApplication)
이 메서드는 앱이 메모리에서 완전히 제거될 때 호출 된다.
이 메서드를 사용해 앱의 마지막 작업들을 마무리하는 일을 할 수 있다.
공유 리소스들을 해제하거나, 데이터를 저장하거나, 타이머를 종료하는 등의 일을 이 메서드에서 실행할 수 있다.
공식 문서에 따르면 이 메서드는 메서드 안에서 일어나는 일이 다 끝나지 않았어도 5초가 넘으면 앱을 메모리에서 해제 시킨다고 한다.
그래서 오래 시간이 걸리는 마무리 작업은 그 전 단계에서 하는 것이 좋다.
🏞️ SceneDelegate에서 실행되는 메서드
scene이 앱에 추가 될 때
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
)
scene이 앱에 추가될 때 호출되는 메서드이다.
해당 메서드에서 화면에 보여질 구성요소(뷰컨 등)를 설정한다. 이 시점엔 UI는 그려지지 않는다.
scene이 준비 되었지만 아직 화면에 나타나지 않았을 때
func sceneDidBecomeActive(_ scene: UIScene)
이 메서드를 씬이 준비되었을 때 그렇지만 화면에 나타나지 않았을 때 호출되는 메서드 이다.
View에 채워져 있던 content 를 refrash 하거나 타이머를 시작하는데 사용 할 수 있다.
이 메서드를 사용하기 위해서는 UISceneDelegate 프로토콜을 채택해야 한다. 그리고 씬을 설계(configure) 해야 한다.
이 메서드를 호출할 때, UIKit 은 didActivateNotification
그리고 didBecomeActiveNotification
라는 Notification 을 호출한다.
원하면 이런 noti 들을 받아서 볼 수 있다.
씬이 준비되어서 이 메서드를 호출하면 App delegate 에 있는 applicationDidBecomeActive(_:)
메서드를 호출되지 않는다.
앱이 일시 정지 되었을 때
func sceneWillResignActive(_ scene: UIScene)
scene 이 일시정시 된다?
여기서 말하는 일시정지는 앱이 잠깐 멈춘 상태를 의미한다.
예를 들어 앱이 작동되고 있는 상황에서 홈 바를 쓸어 올렸거나, 홈 버튼을 눌렀거나 전화 등의 다른 작업이 들어와서 앱이 잠깐 멈춰 있는 상황을 말한다.
(예를 들어 금융 앱과 같은 경우 앱을 위로 밀면, 보이던 개인 정보들을 가리기 위해 placeholder 화면이 나온다던가 하는 기능들이 존재한다.)
이 메서드는 scene이 일시정지 된 경우 호출된다. 진행되던 게임이나 타이머를 멈춰두거나, 유저와의 상호작용을 중지하거나, 중요한 개인정보등을 숨기는 작업에 사용할 수 있다.
이 메서드를 사용하기 위해서는 UISceneDelegate 프로토콜을 채택해야 한다. 그리고 씬을 설계(configure) 해야 한다.
이 메서드를 호출하는 때에 willDeactivateNotification
이라는 Noti 를 보낸다.
scene이 Foreground로 넘어가기 직전에
func sceneWillEnterForeground(_ scene: UIScene)
UIkit 은 씬이 포어그라운드로 넘어가기 전에 sceneDidBecomeActive(_:)
가 호출되고 나서 이 메서드를 호출한다.
새로 생성되고 연결된 씬에도, 이미 백그라운드에서 일하고 있다가 불려지게 된 씬 모두에게 이 메서드를 거친다.
이 메서드를 호출할 때 UIKit 은 didActivateNotification
과 willEnterForegroundNotification
Notification 을 보낸다.
scene이 Background 로 넘어갔을 때
func sceneDidEnterBackground(_:)
해당 메서드는 사용자가 보고 있는 scene이 백그라운드로 진입했을 당시 호출된다.
또한 해당 메서드가 호출된 직후 시스템은 앱 전환기에 표시할 scene의 인테퍼이스의 스냅샷을 만든다.
scene이 메모리에서 해제 될 때
func sceneDidDisconnect(_ scene: UIScene)
씬이 메모리에서 해제되기 전에 사용된다.
파일이나 공유 리소스에 대한 참조를 해제하고 사용자 데이터를 저장하는 용도로 이 메서드를 활용할 수 있다.
씬을 삭제하기 전에 씬의 연결을 먼저 제거 한다.
UIKit은 사용자가 앱의 장면을 명시적으로 닫으면 장면의 연결을 끊는다.
사용자가 다른 앱으로 전환할 때 UIKit은 씬의 연결을 자동으로 끊지 않는다.
UIKit은 또한 다른 작업중의 메모리가 필요하면 씬을 해제하기도 한다.
UIKit은 또한 이 메서드를 호출하는 것 외에도 didDisconnectNotification 알림을 게시한다.
📄 참고 문서
- Managing your app’s life cycle
- 각 메서드 들의 공식 문서 참고
'🍎 iOS > 🍏 UIKit' 카테고리의 다른 글
인스타그램 스타일 Page Control (0) | 2023.07.04 |
---|---|
[iOS] 키보드야 텍스트 가리지마 (0) | 2023.01.06 |
[iOS]사용자의 폰트 사이즈 정보에 따라 UI 바꿔주기 (0) | 2023.01.06 |
[iOS] delegate 구현하기 (0) | 2023.01.06 |
[iOS] Notification Center 구현하기 (0) | 2023.01.06 |