포어그라운드와 백그라운드
포어그라운드는 앱을 사용자가 보고 있는 상태로 CPU 자원 사용의 우선순위가 높은 상태를 말한다.
백그라운드는 앱을 사용자가 보고 있지 않으며 실행 중인 상태로 음악, 네비게이션 등 다른 앱을 실행 하거나 다른 화면을 보고 있는 상태를 말한다. 백그라운드 상태에서는 CPU 자원의 우선순위가 낮으며 이 포어그라운드와 백그라운드에서 데이터 처리를 매끄럽게 해주지 않으면 유저의 사용성이 떨어질 수 있다.
앱의 상태
이름 | 설명 |
---|---|
Not Running | 앱이 아예 실행되지 않았거나 시스템에 의해 종료된 상태 |
Inactive | 앱이 포어그라운드에서 실행 중이지만 현재 이벤트를 받지 못하는 상태(전화) |
Active | 앱이 포어그라운드에서 실행 중이면서 이벤트를 받고 있는 상태, 일반적으로 앱을 사용 중인 상태 |
Background | 앱이 백그라운드에서 실행 중이며 코드를 실행 중인 상태 |
Suspended | 앱이 백그라운드에서 실행 중이며 코드를 실행하고 있지 않은 상태, 사용자가 앱을 종료하거나 시스템이 메모리 확보를 위해 앱을 종료할 때 발생 |
앱의 상태는 아래와 같은 도식을 따라 변하게 된다.
이러한 앱의 상태 변화는 일반적으로 delegate 패턴을 통해 appDelegate에서 조정할 수 있다. 하지만 iOS 13 이후 아이패드 다중 화면 대응을 위해 이제는 sceneDelegate에서 조정한다.
AppDelegate
현재 iOS 최소버전을 13이상으로 하고 프로젝트를 생성하면 AppDelegate에는 아래와 같은 메소드가 존재한다.
메소드 | 설명 |
---|---|
didFinishLaunchingWithOptions | 앱의 ui를 생성하고 앱의 데이터 구조를 초기화 시킨다. deprecated 되진 않았지만 이 메소드를 사용하지 않는 것이 좋다. willFinishLaunchingWithOptions, didFinishLaunchingWithOptions를 대신 사용하는 것이 좋다. |
connectingSceneSession | UIKit의 설정 값을 가져와서 새로운 scene을 생성한다. |
didDiscardSceneSessions | 유저가 앱을 app switcher에서 종료했을 때 실행된다. 만약 앱이 실행중이지 않다면 uikit이 다음 앱 실행때 이 메소드를 실행한다. 앱의 데이터 구조를 업데이트하고 scene 관련 리소스를 해제할 때 사용한다. |
iOS 13 이후 appDelegate의 생명 주기 관리 역할은 sceneDelegate가 가져갔다. 그렇다면 appDelegate의 남은 역할은 무엇일까?
현재 appDelegate는 앱의 데이터 구조를 초기화하는 것, scene에 대한 환경설정을 하는 것(sceneSession 설정), 앱 밖에서 발생한 알림(배터리 부족, 다운로드 완료)에 대응 하는 것, 푸시 알림 등 실행 시에 요구되는 서비스를 등록하는데 사용한다.
SceneDelegate
메소드 | 설명 |
---|---|
scene | UIWindow를 UIWindowScene에 제공한다. storyboard를 사용중이라면 window가 자동으로 scene에 적용된다. |
sceneWillEnterForeground | Scene이 포어그라운드 상태에 들어가려고 할 때 호출, 앱이 백그라운드 상태에 들어 갈 때 변경된 점을 되돌리는 코드들을 넣는다. |
sceneDidBecomeActive | sceneWillEnterForeground 다음에 바로 호출된다, scene이 inactive상태가 되어 멈춘 작업들을 실행하는 코드들을 넣는다. |
sceneWillResignActive | scene이 active 상태에서 빠져 나온다, 전화가 오는 등 앱이 갑작스러운 방해를 받을 때 실행된다.(inactive) |
sceneDidEnterBackground | scene이 백그라운드 상태에 들어간다, 백그라운드에 들어가기전에 데이터를 저장한다. 현재 상태를 저장해서 백그라운드에서 다시 돌아올 때 필요한 작업들을 실행한다. |
sceneDidDisconnect | iOS가 리소스 확보를 위해 Scene을 삭제한다, scene이 백그라운드에 들어가거나, sceneSession이 버려질때 실행된다. scene이 재 연결될 때 실행될 작업들을 여기서 해준다. 이 sceneSession은 다시 app과 연결될 수 있으므로 씬 관련된 정보들을 여기서 저장해준다. |
메소드 명을 보면 쉽게 이 Scene, 즉 앱이 어떤 상태인지 알 수 있다. 각 상태에 따라 맞는 코드를 넣어줄 수 있다.
SceneSession
UISceneSession을 하나의 scene의 런타임 인스턴스를 관리한다. scene이 추가되면 그 scene을 하는 scene 객체를 생성하는데, 이 객체에는 scene의 id와 구성 세부사항이 들어간다. 유저가 앱을 보는지, app switcher로 끄는지 등에 대응하여 UIKit이 이 session을 알아서 생성하거나 파괴한다.
App, SceneDelegate 호출순서
앱을 실행할 때 위 메소드들의 호출 순서는 아래와 같다.
Delegate | 메소드 | |
---|---|---|
AppDelegate | didFinishLaunchingWithOptions | |
AppDelegate | configureationForSession | App이 scene과 연결 |
SceneDelegate | willConnectTosession | |
SceneDelegate | willConnectTo | |
SceneDelegate | willResignActive | 앱이 inactive 상태로 들어감 |
SceneDelegate | didEnterBackground | |
SceneDelegate | didDisconnect | |
AppDelegate | didDiscardSceneSessions |
참조
[iOS] AppDelegate와 SceneDelegate
https://sueaty.tistory.com/134
https://velog.io/@nnnyeong/iOS-AppDelegate-SceneDelegate
iOS - App States(앱의 상태)란