Swift

8. [Swift] App’s Life Cycle(앱 생명주기)

Daesiker 2022. 8. 17. 13:52
반응형

개요

지난 포스팅에는 뷰의 생명주기에 대해 공부 했었는데 이번에는 App의 생명주기에 대해 공부해보고자 한다.

앱의 생명주기(App’s Life Cycle)이란 App의 실행/종료 및 App이 Foreground/Background 상태에 있을 때 시스템이 발생시키는 이벤트에 의해 App의 상태가 전환되는 일련의 과정을 말한다.

✓ Foreground : 앱이 화면에 올라와 있는 상태

✓ Background : 앱이 화면상에서 보여지지 않는 상태


앱 상태

앱의 상태는 총 5가지로 구분된다.

1. Not Running

앱이 실행되지 않았거나, 완전히 종료되어 동작하지 않는 상태

2. Inactive(Foreground)

앱이 실행되면서 foreground에 진입하지만, 어떠한 이벤트도 받지 않는 상태이다. 앱의 상태전환과정에서 잠깐 머무는 단계이다.

3. Active(Foreground)

앱이 실행 중이며, foreground에 있고, 이벤트를 받고 있는 상태이다.

4. Background

앱이 백그라운드에 있으며, 다른 앱으로 전환되었거나 홈버튼을 눌러 밖으로 나갔을 때의 상태이다. 앱을 실행중에 전화가 오는 경우에도 앱의 상태는 Background 상태로 전환된다.

5. Suspanded

앱이 Background 상태에 있으면서, 아무 코드도 실행하지 않는 상태이다.

이 상태에서는 앱은 메모리 상에 올라가 있지만, 아무 일도 하지않기 때문에 기기 배터리 소모가 없다.

또한 많은 App이 실행돼서 메모리 부족현상이 발생하면 메모리에서 해제 되어서 Not Running 상태로 돌아갈 수 있다.


UIKit에서의 App Life Cycle

iOS 13+ 부터는 App 프로젝트에 SceneDelegate라는 파일이 추가되었는데, iOS 13.0+를 기준으로 포스팅하고자 한다.

1. Not Running(AppDelegate)

  • application(_:willFinishLaunchingWithOptions)
  • 앱에 필요한 주요 객체들을 생성하고 앱 실행 준비가 끝나기 직전에 호출되는 함수이다.
  • applicationDidFinishLaunching(_:)
  • 앱 실행을 위한 모든 준비가 끝난 후 사용자에게 보여지기 직전에 호출되는 함수이다.
  • applicationWillTerminate(_:)
  • 앱이 종료되기 직전에 호출된다.

2. In-Active(SceneDelegate)

  • sceneWillEnterForeground(_:)
  • 앱이 backgound나 Not Running 상태에서 Foreground로 들어가기 직전에 호출된다.
  • sceneWillResignActive(_:)
  • 화면에 표시된 App에서 다른 App을 전환할 때 호출되는 함수

3. Active(SceneDelegate)

  • sceneDidBecomeActive(_:)
  • 앱이 비활성화상태에서 활성상태로 진입하고 난 후에 호출되는 함수이다.

4. Background

  • sceneDidEnterBackground(_:)Suspended 상태가 되기전 필요한 작업을 이 구문에 실행시킨다.
  • 앱이 background 상태로 들어갔을 때 호출되는 함수이다.

5. Suspended

따로 호출되는 메서드가 없다.

이것말고도 생명주기에 관한 다양한 함수들이 AppDelegate랑 SceneDelegate에 내장되어 있다.


SwiftUI에서의 App Life Cycle

SwiftUI에서 앱의 생명주기를 다루는 방법에는 2가지가 있는데, 하나는 UIKit과 동일하게 appDelegate를 프로젝트에 추가해서 다루는 방법과 scenePhase라는 환경변수를 통해서 다루는 방법이 있다.

1. AppDelegate

appDelegate로 구현하는 방법은 UIKit과 동일하게 AppDelegate 파일을 먼저 만들어 준 뒤 해당 프로젝트 메인 부분에 환경변수를 통해 적용시켜주면 된다.

-AppDelegate.swift

class MyAppDelegate: NSObject, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        // Record the device token.
    }
}

UIKit에 있는 appDelegate 파일과 동일하다고 생각하고 필요한 함수들을 정의를 한다.

-{MyProject}App.swift

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor private var appDelegate: MyAppDelegate

    var body: some Scene { ... }
}

App의 메인 파일에 @UIApplicationDelegateAdaptor 키워드를 이용해서 내가 만든 AppDelegate 파일을 추가하면 적용이된다.

2개 이상의 AppDelegate를 추가하면 런타임 에러가 발생하므로 주의해야한다.

다른 view파일에서 appDelegate를 가져오고 싶으면 해당 view 파일에 @EnvironmentObject 키워드를 통해 가져올 수 있다.

@EnvironmentObject private var appDelegate: MyAppDelegate

2. ScenePhase

ScenePhase는 앱의 생명주기를 관찰하는 환경변수로 앱의 상태에 따라 active, inactive, backgound 3가지단계로 알려준다.

struct MyScene: Scene {
    @Environment(\\.scenePhase) private var scenePhase
    
    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
        .onChange(of: scenePhase, perform: { value in
            switch value {
            case .active:
                print("active")
            case .inactive:
                print("inactive")
            case .background:
                print("background")
            @unknown default:
                print("error")
            }
        })
    }
}

scenePhase 환경변수를 관찰하고 싶은 View나 Scene이나 App에 추가를 해주고 onChange를 통해 scenePhase의 값이 변화할 때마다 원하는 함수를 호출할 수 있다.

반응형