[SwiftUI] LifeCycle

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

 

 

 

 

UIKit과 SwiftUI는 생명주기가 다르다.

SwiftUI로 뷰를 그리고 로직을 짜다보면 viewDidLoad처럼 onAppear를 사용하다가 기대한 대로 동작하지 않았던 경험이 있었다. 검색해보니 UIKit과 달라진 생명주기 delegate와 연관이 있었어서, 두 프레임워크 중 swiftUI의 생명 주기 api를 정리해보기로 했다.

 

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

 

https://calliek.tistory.com/28

 

[UIKit] 앱의 생명주기

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

calliek.tistory.com

 

 

 

 

 

 

 

생명주기

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

 

 

 

 

 

ScenePhase

- An indication of a scene’s operational state.

 

ScenePhase는 운영 중인 Scene(앱)의 상태를 관리한다.

ScenePhase에선 3가지의 상태값으로 관리를 하는데, inactive, active, background다.

 

 

inactive

- The scene is in the foreground but should pause its work.

: 화면이 포그라운드 상태(화면이 보이는 상태)이지만 앱 작업은 일어나지 않는 상태일때 사용한다. 쉽게 말하면 아래 이미지와 같은 상태다.

 

 

active

- The scene is in the foreground and interactive.

: 앱이 유저에 의해 실행중인 상태일 때 사용한다.

 

background

- The scene isn’t currently visible in the UI.
: 앱 화면이 보이지 않는 상태를 의미한다.

 

 

 

사용예시

@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를 활용하여 앱의 생명 주기를 관리하고 있다.

 

(따라서, 생명주기 동작 방식이 엄연히 다르기 때문에 UIKit 기반으로 SwiftUI의 뷰를 활용하고 있다면, scenePhase가 아닌 ApplicationDelegate api를 notificationCenter로 사용해야한다.)

 

@main은 entry point 같은 역활을 하여 초기화 및 앱의 첫 진입화면을 알려주고, 씬의 상태를 @Envrionment로 추적하여 앱의 상태를 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는 앱 전체 생명주기에 적용된다. 각 뷰에 따라 사용하려면 @main 속성을 사용하지않은 view에 사용하면 된다.

 

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를 추적하면, 해당 뷰의 상태에 따라 뷰에만 생명주기를 적용시킬 수 있다.

 

 

 

 


 

 

 

 

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

 

 

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

 

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

 

 

 

onAppear

- Adds an action to perform before this view appears.

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

 

 

onDisappear

- Adds an action to perform after this view disappears.

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

 

 

 

 

 

 

 

+

 

 

 

이 포스트에서 정리하지 않았지만, SwiftUI에서 Task와 onChange... 특히 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  (6) 2024.10.07
[SwiftUI] Navigation 1  (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 1
  • [SwiftUI] scrollTargetLayout과 ScrollTargetBehavior
  • [SwiftUI] Property Wrapper 총정리
Callie_
Callie_
  • Callie_
    CalliOS
    Callie_
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 🍎 APPLE
      • 🍎 Dev
        • Swift
        • UIKit
        • SwiftUI
        • Issue
        • 구현
      • 🍎 Design
        • HIG
      • ⚙️ CS
      • 💡 알고리즘
        • 프로그래머스
        • 백준
      • 🏟️ 직관로그 (출시앱)
        • 업데이트
      • 🌱 SeSAC iOS 3기
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    ios
    생명주기
    Entry Point
    Enum
    IBOutlet
    CustomView
    TapGestureRecognizer
    Snapshot
    cornerradius
    네트워크통신
    apply
    SwiftUI
    화면전환
    TableViewCell
    .fullScreen
    .OverFullScreen
    SeSAC
    Info탭
    IBAction
    Swift
    CocoaTouchFramework
    addTarget
    stroyboard
    diffable
    DidEndOnExit
    clipsToBound
    modalPresentStyle
    DiffableDataSource
    assets
    layer.shadow
  • 최근 댓글

  • 최근 글

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

티스토리툴바