-
scene의 operational 상태
@Environment(\.scenePhase) private var scenePhase
- Scene Phases 는 아래와 같은 세가지 종류가 있음.
- foreground & interactive
- active scene 이라고 해서 반드시 최상위 (front-most) 에 있을 필요는 없음. (ex. macOS 윈도우에 현재 포커스가 없는 상태일지라도 active한 상태일 수 있음)
App
또는 **Custom Scene
**에서 active phase라는 것은 active scene 인스턴스가 하나 이상 포함되어 있는 것을 의미
- foreground & should pause its work
- 이벤트를 수신하지 않으며 타이머를 일시 중지하고 불필요한 리소스를 해제(free) 해야 함
- scene이 사용자 인터페이스에서 완전히 숨겨지거나, 사용자가 사용하지 못하는 상황일 수 있음
- macOS에서 scene은
background
단계로 이동하는 동안에만 일시적으로 이 단계를 거침 App
또는 **Custom Scene
**에서 inactive phase라는 것은 active scene 인스턴스가 하나도 없다는 것을 의미
- 현재 visible 하지 않은 상태
background
단계에 있는 scene에서 무언가를 하는 것은 가능한 적어야 함background
단계로 진입하면 앱이 종료될 것으로 예상 할 수 있음. 즉, 종료 전에 발생 가능하므로 이 상태로 전환되는 즉시 정리 작업을 수행 (ex. 열려 있는 파일 및 네트워크 연결을 모두 닫기)- 하지만
background
에서active
단계로 돌아갈 수도 있음
- 앱이 켜진 직후 ->
active
- 앱 스위칭 할 수 있게 올린 상태 ->
inactive
- 아이폰 홈화면으로 나왔을 때 ->
background
- 앱 재진입시 ->
inactive
->active
- scenePhase 값을 해석하는 방법은 값이 어디서 읽히느냐에 따라 다름 (
View
vsApp
vsCustom Scene
)
- View instance 내부에서 phase를 읽으면 뷰가 포함된 씬(scene)의 phase를 얻을 수 있음
struct MyView: View {
@ObservedObject var model: DataModel
@Environment(\\.scenePhase) private var scenePhase
var body: some View {
TimerView()
.onChange(of: scenePhase) { phase in
model.isTimerRunning = (phase == .active)
}
}
}
App
instance 내부에서 phase를 읽으면 앱의 모든 씬(scene)의 phase을 반영하는 집계(aggregate) 값을 얻을 수 있음- active scene이 있으면 앱에서
active
의 값을, active scene이 없으면inactive
의 값을 보냄 - single scene(ex. WindowGroup)에서 생성된 여러 scene 인스턴스가 포함
@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.
}
}
}
}
custom scene
인스턴스 내에서 phase를 읽으면 custom scene을 구성하는 모든 scene의 phase 를 반영하는 집계 값을 유사하게 얻을 수 있음
struct MyScene: Scene {
@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
// MyScene go to the background.
}
}
}
}