본문 바로가기

Application/iOS

[iOS] 상태 관리

SwiftUI에서는 SSOT를 기반으로 상태를 관리한다. SSOT는 Single Source Of Truth로 데이터의 값을 결정하는 곳이 단 하나의 위치 에서만 존재 해야한다는 이론이다. 이를 통해 데이터의 일관성을 준수한다. 아래에서는 구체적인 방법들에 대해서 정리하였다. 

 

1. @State와 @Binding 

  • @State 속성 래퍼는 뷰 내에서 변경 가능한 상태를 나타낸다. 변경 가능한 상태를 사용하면 뷰에서 해당 상태가 변경될 때마다 자동으로 다시 렌더링된다.
  • @Binding 속성 래퍼는 다른 뷰의 @State 속성과 바인딩되어, 두 뷰 간에 데이터를 공유하고 동기화하는 데 사용된다.
import SwiftUI

struct ContentView: View {
    @State private var isToggled = false

    var body: some View {
        VStack {
            Text("Toggle Binding Example")
                .font(.headline)

            Toggle("Toggle", isOn: $isToggled)
                .padding()
            
            Subview(isToggled: $isToggled)
        }
    }
}

struct Subview: View {
    @Binding var isToggled: Bool

    var body: some View {
        Text("Toggle is \(isToggled ? "On" : "Off") in Subview")
    }
}

 

SubviewisToggled라는 @Binding 속성을 받아와서 메인 뷰와 하위 뷰 사이에 데이터를 공유한다. @Binding을 사용하면 메인 뷰에서 상태를 변경하면 하위 뷰에서도 변경사항이 반영된다.

 

2. @ObservedObject 와 @Published

  • ObservableObject 프로토콜을 준수한 객체 내에서 @Published 속성을 사용하여 변경 사항을 알릴 수 있다.
import SwiftUI
import Combine

// ObservableObject 프로토콜을 준수하는 클래스를 만듭니다.
class UserData: ObservableObject {
    // @Published 속성을 사용하여 변경 사항을 알릴 속성을 선언합니다.
    @Published var username: String = "Guest"
    @Published var age: Int = 0
}

struct ContentView: View {
    // 사용자 정보를 관리하는 ObservableObject 객체를 생성합니다.
    @ObservedObject var userData = UserData()

    var body: some View {
        VStack {
            Text("User Information")
                .font(.headline)
            
            TextField("Username", text: $userData.username)
                .padding()
            
            Stepper(value: $userData.age, in: 0...100) {
                Text("Age: \(userData.age)")
            }
            .padding()
            
            Text("Hello, \(userData.username)! You are \(userData.age) years old.")
        }
    }
}

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

 

UserData 클래스는 ObservableObject를 준수하며, @Published 속성을 사용하여 usernameage를 변경할 때마다 변경 사항을 알린다. ContentView에서 @ObservedObject로 userData 객체를 관찰하고 있으므로, 사용자가 텍스트 필드나 스테퍼를 통해 값을 변경하면 뷰가 자동으로 다시 그려져서 변경 사항을 반영한다.

 

3. 환경 객체 

환경 객체는 SwiftUI 앱에서 전역 상태를 공유하는 데 사용된다. 주로 앱의 상태나 설정과 관련된 데이터를 공유하는 데 유용하다. 

import SwiftUI

class UserData: ObservableObject {
    @Published var username: String = "Guest"
}

struct ContentView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        VStack {
            Text("User Information")
                .font(.headline)
            
            TextField("Username", text: $userData.username)
                .padding()
            
            Text("Hello, \(userData.username)!")
        }
    }
}

@main
struct MyApp: App {
    @StateObject var userData = UserData()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(userData)
        }
    }
}

 

ContentView 에서 @EnvironmentObject 로 userData를 사용하여 해당 객체의 username 속성을 뷰에서 읽고 변경할 수 있다. 이처럼 @EnvironmentObject 는 주로 전역 상태 또는 설정과 관련된 데이터를 공유하는 데 사용된다. 

'Application > iOS' 카테고리의 다른 글

[iOS] AfterGPT 출시와 생각  (0) 2024.04.15
[iOS] iOS App Template 분석  (0) 2024.01.08
[iOS] iOS를 선택한 이유  (1) 2024.01.02