UIKit으로 ios 프로젝트를 만들면 AppDelegate.swift 파일을 자동으로 생성해준다.
파일을 열어보면 AppDelegate 클래스는 UIApplicationDelegate protocol을 구현하고 있음을 확인할 수 있다.
이 AppDelegate 클래스와 UIApplicationDelegate protocol 에 대해서 알아보자
c에서는 프로그램의 시작점인 entry point가 바로 main() 함수이다. 그렇다면 ios 에서의 entry point는 어디일까?
바로 UIApplicationMain() 함수이다.
이 함수는 앱의 핵심 객체를 생성하는 프로세스를 실행하고, UI를 읽고 커스텀 코드를 호출하는 등의 앱 생성 초기 과정을 담당한다.
이 객체를 통해 생성되는 객체가 바로 UIApplication 객체이다.
swift에서는 @main 어노테이션 또는 @UIApplicationMain 어노테이션을 통해 시스템에게 클래스 정보를 전달한다.
UIApplication 객체
UIApplication 객체는 앱 프로세스가 메모리에 등록될 때, 이때의 프로세스가 바로 객체이다.
이벤트 루프, 높은 단계의 앱 동작, 이벤트를 델리게이트 객체에 알려주는 등 중요한 역할을 한다.
ios에서는 이 클래스를 바로 서브클래싱 하지 않고 AppDelegate라는 대리 객체를 이용해서 커스텀 코드에 관한 코드를 처리한다.
즉 UIApplication 객체는 앱의 생명 주기 관리 또는 이벤트 처리와 같은 앱에서 아주 중요한 역할을 담당하고 이에 관해 작성해야 할 커스텀 코드가 있다면 AppDelegate 클래스에 작성해야 한다.
AppDelegate 객체
UIApplication의 대리 객체이다. 즉 UIApplicationDelegate protocol을 구현하는 객체이다. 이 AppDelegate 객체는 싱글톤 패턴이다. 즉 ios 애플리케이션에서 하나의 인스턴스만 존재하도록 시스템이 보장해준다. 따라서 마음대로 생성할 수 없고, 참조만 허용 가능하다.
이 객체는 앱이 생성되면 자동으로 같이 생성되고, 앱이 종료되면 같이 소멸된다. 즉 앱의 전체 라이프 사이클과 함께 유지되는 객체이다.
따라서 이 클래스에 저장된 데이터는 앱이 종료되기 전까지는 사라지지 않는다.
앱의 상태 변화
앱의 상태 변화는 ios 운영 체제가 처리한다. 즉 ios system이 알아서 발생하는 특정 상황에 맞게 앱의 상태 변화를 제어한다.
이러한 상태 변화는 UIApplication 객체가 처리하기 때문에, 이에 대한 커스텀 코드를 작성 가능한 메소드는 UIApplicationDelegate protocol을 구현한 객체, 즉 AppDelegate 클래스에서 작성할 수 있다.
UIApplicationDelegate protocol에 들어있는 메소드는 많다. 진짜 많다.
이게 다가 아니다..스크롤 하면 더 있음
이 중에서 세번째 영역에 위치한 [Responding to App Life-Cycle Events] 부분만 살펴보자
IOS App Life Cycle
이렇게 상태가 변환하면서 어떤 메소드들이 호출되는지 알아보자
applicationDidBecomeActive(_:)
application이 Active 상태가 되었음을 알려준다. (상태 변화 후 실행됨)
optional func applicationDidBecomeActive(_ application: UIApplication)
Active 상태를 이해하기 위해서는 우선 foreground, background 부터 알아야 한다.
foreground
foreground 상태는 쉽게 말해 사용자가 보는 화면이다. foreground 상태에 진입한다는 것은 한마디로 user action을 받는다는 것이다.
애플 공식 문서에도 다음과 같이 나와있다.
Use a foreground transition to update your app’s UI, acquire resources, and start the services you need to handle user requests.
즉 사용자 입력을 받고, UI를 보여주고, cpu의 자원 우선순위가 높게 배정되는 상태를 말한다.
background
foreground와 반대로 사용자는 보지 못한다. 이때 시스템 리소스 해제 등을 통해 메모리 공간을 아주 적게 할당받고 자원의 우선순위도 foreground에게 내어준다.
If your app was previously in the foreground, use the background transition to stop tasks and release any shared resources. If your app enters the background to process an important event, process the event and exit as quickly as possible.
Active 상태는 이 중에서도 foreground에 속한 상태이다.
즉 앱이 전면에서 실행중이며 이벤트를 받는 상태를 말한다.
applicationWillResignActive(_:)
application이 InActive 상태로 진입하는 것을 알려준다. (진입 전 실행됨)
optional func applicationWillResignActive(_ application: UIApplication)
InActive 상태 또한 foreground에 속하는 상태이다. 하지만 Active와 달리 앱이 전면에서 실행중임에도 이벤트를 받지 않는 상태이다.
예를 들면 맨 처음 앱을 열때 실행되는 LaunchScreen은 사용자의 화면에 보이지만, 아무런 이벤트를 받지 않는 Inactive 상태이다.
application의 상태가 Active에서 InActive로 전환되는 이유는 다양하다. 애플 개발자 문서에는 다음과 같이 나와있다.
The app moves to the inactive state because of temporary interruptions like an incoming phone call or SMS message, or when the user quits the app and it begins the transition to the background state.
전화 수신, SMS 문자 등의 일시적인 방해의 경우 또는 앱이 종료되어 background process로 들어가기 전에 Active 상태가 거쳐가는 상태이다. 즉 다음과 같이 Active에서 background 로 진입하거나 혹은 그 반대의 경우에 반드시 InActive 상태를 거치게 된다.
Active <-> InActive <-> background
applicationDidEnterBackground(_:)
applicatoin이 background에 진입했음을 알려준다. (진입 후 실행됨)
optional func applicationDidEnterBackground(_ application: UIApplication)
애플 문서에는 다음과 같이 나와있다.
이 함수에서 shared resources, save information 등의 작업을 하지만 이 구현은 대략 5초이내에 종료되어야 한다. 즉 ASAP 종료해야 한다. 또한 이 메소드의 끝 부분에서 beginBackgroundTask(expirationHandler:)를 호출해서는 안된다. system이 종료될 가능성이 있기 때문이다.
applicationWillEnterForeground(_:)
application이 foreground 상태에 진입하는 것을 알려준다. (진입 전 실행됨)
optional func applicationWillEnterForeground(_ application: UIApplication)
ios는 사실 storyboard 기반으로 프로젝트를 생성하면 SceneDelegate.swift 파일을 하나 더 생성해준다.
그럼 얘는 어디에 쓰이는 것일까?
정답은 얘도 같은 역할이라는 것이다.
ios 13 이상에서는 UISceneDelegate 객체가 life-cycle 이벤트를 관리하고
ios 12 이하에서는 UIApplicationDelegate 객체가 관리한다.
다음번에는 UISceneDelegate를 알아보자
'MOBILE > ios' 카테고리의 다른 글
[swift] Property Wrapper: what does @ mean in swift? (0) | 2022.04.02 |
---|---|
[iOS] URLSession을 사용하여 POST method 통신하기 (0) | 2022.04.01 |
[iOS] segue 객체를 이용한 화면 전환 처리하기 (0) | 2022.03.27 |
[iOS] core data를 이용하여 데이터를 영구 저장하기 (0) | 2022.03.26 |
[iOS] UITableViewController delegate method 모아보기 (0) | 2022.03.25 |