오늘부터 UIKit을 공부해보려고 한다. UIkit 내용만 적는 공간을 따로 만드려고 함
App의 생명 주기는 App의 실행/종료 및 App이 Foreground(화면이 띄워져 있고, 사용중이라고 생각하면 편할듯)/Background(실행중에 전화가 오거나 할 때) 상태에 있을 때, 시스템이 발생 시키는 event에 의해 App의 상태가 전환되는 일련의 과정을 뜻함.
앱의 실행 과정을 살펴보겠습니다.
사용자가 앱 아이콘을 탭 하면, 스프링보드(SpringBoard)가 앱을 실행시켜 줍니다.
스프링보드는 아이폰의 홈 스크린을 관리하는 기본 앱입니다. 기타 작업으로는 WindowServer 스타트, 앱의 시작 및 부트스트랩, 시작 시 일부 장치의 설정이 있습니다.
스프링보드가 앱의 시작 화면에 애니메이션을 적용하는 동안, 앱과 필요한 공유 라이브러리가 메모리에 로드 됩니다. 결국 앱 실행이 시작되고, 앱의 대리자(application delegate)가 알림을 받습니다.
AppDelegate는 앱 딜리게이트 객체입니다. 이것은
UIResponder
클래스를 상속하고,UIApplicationDelegate
프로토콜을 구현합니다.
iOS의 주요 엔트리는 UIApplicationDelegate
입니다. 이것은 프로토콜이고, 유저 이벤트 종류인 앱의 실행, 백그라운드나 포그라운드에 진입, 앱의 종료, 푸쉬 버튼 등의 알림을 받으려면 이를 앱에 구현해야 합니다.
UIResponder
클래스는 AppDelegate
를 유저 이벤트에 반응을 할 수 있게 만들어 줍니다. 그리고, UIApplicationDelegate
는 AppDelegate
가 앱의 라이프 사이클에 대한 응답과 관리를 하는 대리자 객체역할을 하게 해줍니다.
// 먼저 이 메소드는 앱이 시작되거나 초기화 되면 호출 된다.
// 루트 뷰 컨트롤러는 이 단계에서 인스턴스화 된다.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)
// 앱이 포그라운드에 들어가고, 활성화 되면, 아래 메서드를 호출합니다.
// 주로, 이 메소드에서 UI의 상태를 복원할 수 있습니다.
func applicationDidBecomeActive(_ application: UIApplication) {
...
}
// 이 메소드는 앱의 상태가 활성화에서 비활성화로 변경될 때 호출되고 알립니다.
// 주로 UI의 데이터를 저장할때 이 메소드에서 합니다
func applicationWillResignActive(_ application: UIApplication) {
...
}
// 이 메소드는 앱이 백그라운드에 들어가면 호출하고 알립니다.
// 이 메소드에서 우리는 유저 데이터를 저장하거나 파일 이나 데이터베이스 자원을 릴리즈 합니다.
func applicationDidEnterBackground(_ application: UIApplication) {
...
}
// 앱이 포그라운드에 들어가지만, 아직 활성화 상태가 아닐때 이 메소드가 호출됩니다.
// 이 메소드에서 유저 데이터를 복원합니다.
func applicationWillEnterForeground(_ application: UIApplication) {
...
}
// 앱이 종료되면 호출되고 알립니다.
// 이 메소드에서 자원을 릴리스 하고, 또한 유저 데이터를 저장합니다.
// 약 5초 동안 작업을 수행하고 리턴합니다. 시간이 만료되기 전에 메서드가 반환되지 않으면 시스템이 프로세스를 완전히 중지할 수 있습니다
func applicationWillTerminate(_ application: UIApplication) {
...
}
이는 유저가 일으키는 이벤트를 처리하는 프로세스 입니다.
App Delegate는 시작시에 메인 런 루프를 설정하고, 이벤트를 처리하고, 뷰 기반 인터페이스에 대한 업데이트를 다루는 데 사용합니다.
이는 View와 관련되어 있으므로 Main 쓰레드에서 실행됩니다.
메인 스레드는 직렬 스레드이며 이는 사용자 관련 이벤트가 수신된 순서대로 직렬로 처리되도록 합니다.
이를 순서로 정리하면
port
로 해당 이벤트가 앱으로 전달된다.Queue
형태로 정리되고 Event Queue
에 쌓임유저가 현재 백그라운드에 있는 앱을 실행하게 되면 먼저, 시스템은 앱을 비활성화 상태로 이동 시킨 다음 활성화 상태로 이동시킵니다.
유저가 앱을 처음 실행하거나, 장치를 재부팅 한 후거나, 시스템이 앱을 종료시킨 후라면 시스템은 앱을 활성화 상태로 옮깁니다.
opt out의 뜻을 잘 모르겠지만, 백그라운드 상태를 해제한다 라는 느낌인듯 ?
UIApplicationExitsOnSuspend
키를 앱의 info.plist
에 추가하고, 해당 값을 yes
로 설정하여 백그라운드 실행을 명시적으로 고를 수 있다.
백그라운드 상태를 선택 해제 하면, 앱 라이프 사이클은 not running, inactive
상태와 active
상태의 사이가 되며, 백그라운드나, 중단 상태로 전환 되지 않습니다.
일시적으로 앱을 비활성화 상태로 옮긴 후, 해당 방해 행위(중단)를 승인할지 무시할지 유저의 결정이 있을때 까지 상태를 유지한다.
beginBackgroundTask(expirationHandler handler: (() -> Void)? = nil)
메서드를 호출할 수 있습니다.performExpiringActivity(withReason:using:)
메소드를 호출하여서 가능합니다.이러한 객체들은 앱이 더 이상 포그라운드에 있지 않은 경우 더 많은 실행시간을 제공합니다. 이 API는 앱이 중단되기 전에 요청이 완료되도록 합니다.
뷰 컨트롤러도 라이프 사이클이 존재한다. 코드를 통해서 알아보자
// 스크린에 보일 때 뷰의 요소들이 메모리에 로드가 됨을 의미함.
override func viewDidLoad() {
super.viewDidLoad()
print("view did Load")
}
// 화면이 이제 보여질때 함수
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("view will appear")
}
// 화면이 보여지고 나서 호출되는 함수
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("view did appear")
}
// 화면이 사라질것을 나타내는 함수
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("view will disappear")
}
// 뷰가 사라지고 나서 호출되는 함수
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print("view did disappear")
}
// 출력 결과
// view did load
// view will appear
// view did appear
// view will disappear
// view did disappear
위의 코드에서 보다시피, viewDidLoad
가 제일 먼저 실행이 되고 그 다음 차례대로 실행이 된다.
이는 뷰의 컨트롤러가 메모리에 로드되고 난 후에 호출이 됨을 의미한다. (Called after the controller view is loaded into memory)
이 메소드는 뷰의 로딩이 완료 되었을 때 시스템에 의해 자동으로 호출되기 때문에 일반적으로 리소스를 초기화 하거나, UI의 초기 구성을 위해 주로 사용합니다. 처음 한 번만 실행이 되므로, 해당하는 코드를 이 부분에 작성해주면 된다.
네비게이션 컨트롤러를 통해 다른 뷰를 갔다가 다시 돌아오면, viewDidLoad는 실행이 되지 않는다. 따라서, 이러한 경우에 특정 액션을 주고 싶다면, viewWillAppear 내부에 액션을 작성하면 된다.
이는 뷰가 사라지고 나면 호출이 되는데, 만약 네비게이션 컨트롤러에서 다른 뷰로 넘어간다고 하였을 때, 다른 뷰의 viewDidLoad, viewWillAppear
가 먼저 일어난 후에 이전 뷰의 viewDidDisappear
가 수행이 된다.
물론 다른 뷰가
viewDidLoad
를 실행 한 적이 있다면, 그 다음에는 실행하지 않고,viewWillAppear
만 실행이 된다.
위 2가지 정도는 특별하게 더 알아두면 좋을듯 하다.
참조
https://manasaprema04.medium.com/application-life-cycle-in-ios-f7365d8c1636