728x90
Foreground 에 있는 앱은 CPU를 포함한 시스템 리소스에서 우선권을 가진다.
Background 에 있을 경우 가능한 작업을 적게 해야하고, 이상적으로는 아무것도 안하는게 좋다.
앱의 상태가 바뀔 때마다 적절한 delegate 를 가져와야하는데
iOS13 이후로는 UISceneDelegate 객체를 이용한다
UIScene 단위에 대해서 알아보도록 해야겠다.
앱의 하나의 Scene = 하나의 UI인스턴스에 대한 라이프사이클과 상태 변화를 관리한다.
// SceneDelegate.swift
class SceneDelegate: UIResponder, UISceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = YourRootViewController()
self.window = window
window.makeKeyAndVisible()
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Scene이 Active 상태로 들어갈 때
}
func sceneWillResignActive(_ scene: UIScene) {
// Scene이 Inactive 상태로 가기 직전
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Scene이 백그라운드로 갈 때
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Scene이 포그라운드로 돌아올 때
}
func sceneDidDisconnect(_ scene: UIScene) {
// Scene이 시스템에 의해 끊길 때 (메모리 회수 등)
}
}
import SwiftUI
@main
struct MyApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .active:
print("앱이 Active 상태입니다.")
case .inactive:
print("앱이 Inactive 상태입니다.")
case .background:
print("앱이 Background 상태입니다.")
@unknown default:
print("알 수 없는 상태입니다.")
}
}
}
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup { // 여기가 Scene 단위
ContentView() // 여기 ContentView는 View단위
}
}
}
iPadOS나 macOS에서는 하나의 앱에서 여러 개의 Scene을 띄울 수 있다.
(예를 들면, 메일 앱에서 새 메일을 작성할 때 새 창이 뜨는 것 = 새로운 Scene)
SwiftUI에서는 그것도 자연스럽게 WindowGroup 여러 개로 관리할 수 있다.
Scene을 여러 개 만들 때 주의할 점
- 상태 관리: 여러 Scene 간에 데이터를 공유하려면 @EnvironmentObject나 전역 상태 관리 방식이 필요.
- 메모리 관리: Scene의 리소스를 적절히 해제하고 관리.
- UI 동기화: 하나의 Scene에서 데이터 변경 시 다른 Scene의 UI도 자동으로 갱신되도록 해야 함.
- 라이프사이클 관리: 각 Scene의 라이프사이클을 독립적으로 관리하고, Scene이 활성화/비활성화될 때 적절한 작업을 처리 필요.
- 기기 크기와 레이아웃: 각 Scene에 대해 다양한 화면 크기와 레이아웃을 지원해야함.
- 백그라운드 작업: Scene이 백그라운드로 이동할 때, 작업을 처리하고 리소스를 절약하는 방법을 고려해야함.
onAppear, onDisappear 등은 View 단위의 동작 이벤트라는 점
이벤트설명사용 예시
onAppear | 뷰가 화면에 나타날 때 호출됩니다. | Text("Hello, World!") .onAppear { print("뷰가 화면에 나타났습니다.") } |
onDisappear | 뷰가 화면에서 사라질 때 호출됩니다. | Text("Goodbye!") .onDisappear { print("뷰가 화면에서 사라졌습니다.") } |
onChange(of:perform:) | 특정 값이 변경될 때 호출됩니다. | @State private var count = 0 Text("Count: \(count)").onChange(of: count) { print("Count 값이 변경되었습니다.") } |
task | 뷰가 처음 나타날 때 비동기 작업을 시작합니다. | Text("Fetching data...").task { await fetchData() } |
onTapGesture | 사용자가 터치를 했을 때 호출됩니다. | Text("Tap me").onTapGesture { print("Tapped!") } |
onLongPressGesture | 사용자가 롱프레스(길게 누르기)를 했을 때 호출됩니다. | Text("Long press me").onLongPressGesture { print("Long pressed!") } |
simultaneousGesture | 여러 제스처가 동시에 발생할 때 모두 처리합니다. | Text("Simultaneous gesture").simultaneousGesture(TapGesture().onEnded { print("Tapped!") }) |
focusable | 텍스트 필드나 버튼 등 뷰가 포커스를 받을 때 호출됩니다. | TextField("Enter text", text: $text).focusable().onChange(of: focused) { _ in print("포커스를 받았습니다.") } |
onPreferenceChange | 부모 뷰와 자식 뷰 간의 데이터 변경 사항을 처리합니다. | Text("Value: \(value)").onPreferenceChange(MyPreferenceKey.self) { value in self.value = value } |
animation | 상태 변경에 애니메이션 효과를 적용할 때 사용됩니다. | withAnimation { isVisible.toggle() } (애니메이션 효과와 상태 변경) |
728x90
'iOS > Swift' 카테고리의 다른 글
내가 더 이상 헷갈리기 싫어서 적는 Swift의 핵심 구성 요소 (0) | 2025.05.01 |
---|---|
상태를 감지하는 방법 (0) | 2025.04.23 |
SwiftData 모델에 있는 데이터가 빈 값일 수도 있고 아닐 수도 있을 때, 어떻게 처리해야하지? (0) | 2025.04.19 |
SwiftData 에서 여러개의 모델을 가져올 때 어떻게 해야할까? (1) | 2025.04.18 |
View에서 parameter를 선언할때 var, let 선택 기준 (2) | 2025.04.13 |