안녕하세요, GraceKim입니다! 🍎

이번에는 4차시로 State Management에 대하여 정리해보고자 합니다.

State management

Making classes observable

클래스를 관찰 가능하게 만들기

일반적으로 클래스의 속성이 변경되면 SwiftUI는 해당 변경 사항을 감지할 수 없는데, ObservableObject 프로토콜을 채택하면 @Published 속성 래퍼를 사용하여 특정 속성을 관찰하게끔 만들면, 해당 속성이 변경될 때마다 SwiftUI에게 알리고 UI를 업데이트할 수 있게끔 합니다.

예를 들어,

import SwiftUI

class MyViewModel: ObservableObject {
    @Published var name: String = "Gracekim"
    @Published var age: Int = 22
}

이제 MyViewModel 클래스의 인스턴스를 사용하는 SwiftUI 뷰에서 @ObservedObject 속성 래퍼를 사용하면 해당 뷰는 MyViewModel의 변경사항을 감지하고 자동으로 업데이트됩니다.

struct MyView: View {
    @ObservedObject var viewModel = MyViewModel()

    var body: some View {
        VStack {
            Text("Name: \(viewModel.name)")
            Text("Age: \(viewModel.age)")
        }
    }
}

이렇게 하면 viewModel의 name, age 속성의 변경을 실시간으로 감지합니다.

객체 변경 모니터링

ObservedObject, StateObject, 또는 EnvironmentObject 중 하나를 속성 선언에 추가하여 SwiftUI가 객체를 모니터링할 수 있습니다.

ObservedObject

struct ChildView: View {
   @ObservedObject var timer: ScrumTimer
   // ...
}
  • 사용 목적: 현재 뷰 내에서만 사용되는 객체를 관찰 가능하게 만듭니다.
  • 사용 위치: 뷰의 속성으로 선언됩니다.
  • 생명 주기 관리: 뷰가 처음 생성될 때 생성되고, 뷰가 소멸할 때 함께 소멸됩니다.

StateObject

struct MeetingView: View {
   @StateObject var scrumTimer = ScrumTimer()
   var body: some View {
      VStack {
         ChildView(timer: scrumTimer)
      }
   }
   // ...
}
  • 사용 목적: 부모 뷰에서 생성된 객체를 자식 뷰에서 사용하고 관찰 가능하게 만듭니다.
  • 사용 위치: 뷰의 속성으로 선언됩니다.
  • 생명 주기 관리: 뷰가 처음 생성될 때 생성되고, 뷰가 소멸할 때 함께 소멸됩니다.

EnvironmentObject

struct ParentView: View {
   @StateObject var scrumTimer = ScrumTimer()
   var body: some View {
      VStack {
         ChildView()
            .environmentObject(scrumTimer)
      }
   }
   // ...
}


struct ChildView: View {
    var body: some View {
        GrandchildView()
    }
}
struct GrandchildView: View {
   @EnvironmentObject var timer: ScrumTimer
   // ...
}
  • 사용 목적: 뷰 계층 구조 전체에서 공유되는 객체를 관찰 가능하게 만듭니다.
  • 사용 위치: 최상위 뷰에서 environmentObject 뷰 수정자를 사용하여 환경에 객체를 추가한 후, 하위 뷰에서 @EnvironmentObject로 해당 객체를 사용합니다.
  • 생명 주기 관리: 최상위 뷰에서 생성되고, 앱이 실행되는 동안 계속 유지됩니다.

Responding to events

Scene과 앱 구조



  • 앱은 App 프로토콜을 준수하는 구조체로 정의됩니다.
  • @main 속성으로 앱의 진입점을 정의합니다.
  • 앱의 본문에서는 하나 이상의 Scene 프로토콜을 준수하는 scene을 추가합니다.
  • Scene은 앱이 제시하는 뷰 계층의 컨테이너이며, iOS 및 watchOS에서는 하나의 Scene이지만 macOS 및 iPadOS에서는 여러 Scene을 표시할 수 있습니다.

Scene의 생명 주기와 전환

  • Scene은 Active, Inactive, Background 세 가지 상태를 가집니다.
  • 활성 상태에서는 사용자와 상호 작용이 가능하고, 비활성 상태에서는 시스템이 상호 작용을 비활성화합니다.
  • 백그라운드 상태에서는 앱은 실행 중이지만 화면에 표시되지 않습니다.
  • scenePhase 환경 값을 통해 Scene의 현재 상태를 확인할 수 있습니다.

이벤트와 State

SwiftUI는 선언적 프로그래밍 방식을 채택합니다.

  • 어떻게(HOW)보다 무엇(What)을 나타내야 하는지를 프로그래밍적으로 표현하는 것이 선언적 프로그래밍입니다.

이부분에 대해서는 추후 블로그에 따로 정리해볼 예정입니다.

명령형 패턴은 프로그램 상태 변경에 대한 응답으로 뷰를 변이시키는 것을 필요로 하지만 SwiftUI에서는 뷰가 나타날 때마다 사용자 인터페이스가 어떻게 나타나야 하는지를 명시합니다.
실행 중에 시스템은 상태와 사용자 인터페이스를 동기화하여 상태 변경이 발생할 때마다 관련 부분을 업데이트합니다.

뷰의 생명주기

다음은 SwiftUI에서 생명주기 이벤트에 응답하는 modifiers입니다.

  • onAppear(perform:)는 뷰가 화면에 나타날 때마다 실행되는 작업을 트리거합니다.
  • onDisappear(perform:)는 뷰가 화면에서 사라질 때 실행되는 작업을 트리거합니다.
  • task(priority:_:)는 뷰가 화면에 나타나기 전에 비동기로 실행되는 작업을 트리거합니다.

보기가 나타나거나 사라질 때 앱의 상태를 변경하는 작업을 수행할 수 있습니다. 사용자가 시작한 이벤트와 마찬가지로 SwiftUI는 뷰 계층 구조를 관리하고 업데이트된 상태를 반영하도록 사용자 인터페이스를 업데이트하여 상태를 변경합니다.

profile
T자형 개발자가 되고 싶은 GraceKim입니다 / 구름톤 유니브 Leader

0개의 댓글

Powered by GraphCDN, the GraphQL CDN