[SwiftUI] LifeCycle

2024. 10. 14. 13:57·Dev/SwiftUI

 

 

 

 

UIKit과 SwiftUI는 생명주기가 다르다. SwiftUI로 뷰를 그리고 로직을 작성하다 보면 viewDidLoad처럼 onAppear를 사용하다가 기대한 대로 동작하지 않는 경험을 한 적이 있다. 검색해 보니 UIKit과 달라진 생명주기 델리게이트와 연관이 있었기에, 두 프레임워크 중 SwiftUI의 생명주기 API를 정리해 본다.

 

전반적인 iOS 앱 생명주기에 대한 내용은 아래 포스트에 정리한 바 있다.

 

https://calliek.tistory.com/28

 

[UIKit] 앱의 생명주기

✔︎ 생명주기 (Life Cycle) 생명주기란, 앱이 최초로 실행되는 시점부터 종료되는 시점까지의 상태를 의미한다.그렇다면 이런 앱의 상태가 무엇인가 하면, "the current state of your app determines what it ca

calliek.tistory.com

 

 


 

 

 

 

1. 생명주기

생명주기는 앱이 최초로 실행되는 시점부터 종료되는 시점까지의 상태를 의미한다. SwiftUI에서 앱의 생명주기는 ScenePhase의 onChange로 관리하며, 뷰의 생명주기는 onAppear와 onDisappear로 관리한다.

 

 

2. 앱 생명주기: ScenePhase

화면이 포그라운드 상태(사용자에게 보이는 상태)이지만, 앱 작업은 일시 중지된 상태를 의미한다. 예를 들어, 제어 센터나 알림 센터가 나타났을 때와 같은 상태다.

 

inactive

화면이 포그라운드 상태(사용자에게 보이는 상태)이지만, 앱 작업은 일시 중지된 상태를 의미한다. 예를 들어, 제어 센터나 알림 센터가 나타났을 때와 같은 상태다.

 

 

active

앱이 포그라운드 상태에서 사용자에게 완전히 보이며 상호작용이 가능한 상태를 의미한다. 앱이 활발하게 실행 중인 상태다.

 

background

앱 화면이 사용자에게 보이지 않는 상태를 의미한다. 앱이 백그라운드에서 실행 중이거나 종료된 상태에 가깝다.

 

 

2.1. ScenePhase 사용 예시

공식 문서에서는 앱의 생명주기를 다음과 같이 예시를 들어 설명한다.

 

사용예시

@main
struct MyApp: App {
    @Environment(\.scenePhase) private var scenePhase


    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
        .onChange(of: scenePhase) { phase in
            if phase == .background {
                // Perform cleanup when all scenes within
                // MyApp go to the background.
            }
        }
    }
}

 

UIKit에서는 ApplicationDelegate의 applicationDidBecomeActive 등으로 앱의 생명주기를 관리하지만, SwiftUI에서는 @main과 @Environment를 활용하여 앱의 생명주기를 관리한다.

 

참고: SwiftUI 기반의 뷰를 UIKit 프로젝트에서 사용하고 있다면, scenePhase가 아닌 ApplicationDelegate API를 NotificationCenter를 통해 사용하는 것이 올바른 방법이다.

 

@main은 앱의 진입점(entry point) 역할을 하여 초기화 및 앱의 첫 진입 화면을 알린다. 그리고 Scene의 상태를 @Environment로 추적하여 onChange 클로저 내에서 앱 상태에 따른 액션을 실행한다.

 

 

@main
struct TestApp: App {
  @Environment(\.scenePhase) var scenePhase
  
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
    .onChange(of: scenePhase) { phase in
      switch phase {
      case .active:
        print("-- active")
      case .inactive:
        print("-- inactive")
      case .background:
        print("-- background")
      @unknown default:
        print("-- scenePhase issue")
      }
    }
  }
}

 

위 코드처럼 각각의 상태 값에 따라 다른 액션을 적용할 수 있으며, @main 속성 때문에 해당 scenePhase는 앱 전체의 생명주기에 적용된다. 각 뷰에 따라 ScenePhase를 사용하려면 @main 속성을 사용하지 않은 뷰에 적용하면 된다.

 

 

 

struct TestView: View {
  @Environment(\.scenePhase) var phase
  
  var body: some View {
    Text("test")
      .onChange(of: scenePhase) { phase in
        switch phase {
        case .active:
          print("-- active")
        case .inactive:
          print("-- inactive")
        case .background:
          print("-- background")
        @unknown default:
          print("-- scenePhase issue")
        }
      }
  }
}

 

위처럼 뷰로 선언된 구조체에 @Environment로 scenePhase를 추적하면, 해당 뷰의 상태에 따라 해당 뷰에만 생명주기를 적용할 수 있다.

 

 

 

3. 뷰 생명주기: onAppear와 onDisappear

뷰의 생명주기는 appearing → updating → disappearing 단계를 거친다. 각각 뷰 초기화 및 렌더링, 상태 변경 발생 시 뷰 반영, 뷰 계층에서 뷰 제거의 역할을 수행한다.

 

출처: https://www.vadimbulavin.com/swiftui-view-lifecycle/

 

 

이 역할 중 onAppear와 onDisappear가 뷰 생명주기의 핵심이다. SwiftUI에서 뷰 생명주기는 이 두 메서드밖에 없다. 두 메서드 모두 부모 뷰 다음에 자식 뷰가 호출되는 Top-Down 순서를 따른다.

 

 

onAppear

뷰가 화면에 렌더링되기 전 onAppear 클로저 내의 액션이 호출된다.
 

onDisappear

뷰가 화면에서 사라진 후 onDisappear 클로저 내의 액션이 실행된다.

 

 

4. Task와 onChange

포스트에서는 자세히 다루지 않았지만, SwiftUI에서 Task와 onChange (특히 Task)는 뷰 생명주기에 밀접하게 포함되어 있다. 문서를 확인했을 때 Task는 뷰의 시점에 따라 비동기 작업을 처리해주는 역할을 하는 것으로 보인다.

 

 

 


 

 

References

 

https://developer.apple.com/documentation/swiftui/scenephase

 

ScenePhase | Apple Developer Documentation

An indication of a scene’s operational state.

developer.apple.com

 

https://developer.apple.com/documentation/swiftui/scenephase

 

ScenePhase | Apple Developer Documentation

An indication of a scene’s operational state.

developer.apple.com

 

 

https://developer.apple.com/documentation/SwiftUI/View/onAppear(perform:)

 

onAppear(perform:) | Apple Developer Documentation

Adds an action to perform before this view appears.

developer.apple.com

 

https://developer.apple.com/documentation/swiftui/view/ondisappear(perform:)

 

onDisappear(perform:) | Apple Developer Documentation

Adds an action to perform after this view disappears.

developer.apple.com


https://www.vadimbulavin.com/swiftui-view-lifecycle/

 

SwiftUI View Lifecycle

Learn the three phases of SwiftUI view lifecycle: Appearing, Updating and Disappearing.

www.vadimbulavin.com

 

저작자표시 (새창열림)

'Dev > SwiftUI' 카테고리의 다른 글

[SwiftUI] ObservableObject, ObservedObject, Published  (5) 2024.10.07
[SwiftUI] Navigation  (0) 2024.09.24
[SwiftUI] scrollTargetLayout과 ScrollTargetBehavior  (0) 2024.08.16
[SwiftUI] Property Wrapper 총정리  (0) 2024.07.26
[SwiftUI] Frame  (0) 2024.07.22
'Dev/SwiftUI' 카테고리의 다른 글
  • [SwiftUI] ObservableObject, ObservedObject, Published
  • [SwiftUI] Navigation
  • [SwiftUI] scrollTargetLayout과 ScrollTargetBehavior
  • [SwiftUI] Property Wrapper 총정리
Callie_
Callie_
  • Callie_
    CalliOS
    Callie_
  • 전체
    오늘
    어제
    • 분류 전체보기
      • APPLE
      • Dev
        • Swift
        • UIKit
        • SwiftUI
        • Issue
        • 구현
      • Design
        • HIG
      • CS
      • 직관로그 (출시앱)
        • 업데이트
      • 🌱 SeSAC iOS 3기
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Enum
    TapGestureRecognizer
    cs
    SwiftUI
    생명주기
    stroyboard
    Entry Point
    .OverFullScreen
    DidEndOnExit
    layer.shadow
    keyboard
    addTarget
    Swift
    후기
    Info탭
    네트워크통신
    cornerradius
    .fullScreen
    clipsToBound
    화면전환
    IBAction
    Button
    tag
    modalPresentStyle
    TableViewCell
    SeSAC
    ios
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Callie_
[SwiftUI] LifeCycle
상단으로

티스토리툴바