[iOS] SwiftUI와 Combine (2)

2025. 1. 28. 12:36iOS

반응형

SwiftUI는 Combine 없이도 충분히 사용할 수 있으며, 애플이 제공하는 기본 상태 관리 메커니즘(@State, @Binding, @Environment, @StateObject, @ObservedObject 등)을 활용해 간단한 데이터 흐름과 UI 갱신을 처리할 수 있습니다. 하지만 이 경우 SwiftUI 자체의 상태 관리 기능만 사용하게 되며, 복잡한 비동기 작업이나 여러 데이터 스트림을 다루는 데는 한계가 있을 수 있습니다.


1. SwiftUI의 상태 관리 메커니즘

SwiftUI는 다음과 같은 상태 관리 도구를 제공하며, 이들만으로도 단순한 앱에서는 충분히 동작합니다.

(1) @State

  • 역할: 뷰 내부에서 간단한 상태를 관리.
  • 특징: 뷰가 상태의 변화를 감지하고 자동으로 UI를 갱신.
struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button("Increment") {
                count += 1
            }
        }
    }
}
  • @State는 뷰 내부에 국한된 상태를 관리하므로, 상태가 다른 뷰에 공유되지 않습니다.

(2) @Binding

  • 역할: 부모 뷰의 상태를 자식 뷰에서 바인딩하여 읽고 수정.
  • 특징: 데이터가 공유되며 부모와 자식 뷰 간 동기화 가능.
struct ParentView: View {
    @State private var isOn = false

    var body: some View {
        ToggleView(isOn: $isOn)
    }
}

struct ToggleView: View {
    @Binding var isOn: Bool

    var body: some View {
        Toggle("Toggle Switch", isOn: $isOn)
    }
}
  • @Binding을 통해 자식 뷰가 부모 뷰의 상태를 직접 수정할 수 있습니다.

(3) @StateObject & @ObservedObject

  • 역할: ObservableObject를 사용해 더 복잡한 상태를 관리하고, 상태를 여러 뷰에서 공유.
  • 차이점:
    • @StateObject: 뷰에서 소유권을 가지며, 객체의 생명 주기를 관리.
    • @ObservedObject: 뷰에서 소유권 없이 외부에서 전달된 객체를 관찰.
class CounterModel: ObservableObject {
    @Published var count = 0
}

struct CounterView: View {
    @StateObject private var model = CounterModel()

    var body: some View {
        VStack {
            Text("Count: \(model.count)")
            Button("Increment") {
                model.count += 1
            }
        }
    }
}
 
 
  • @Published 속성을 통해 Combine 없이도 SwiftUI가 상태 변화를 감지하고 UI를 갱신합니다.

(4) @Environment & @EnvironmentObject

  • 역할: 글로벌 상태를 관리하거나 부모 뷰에서 자식 뷰로 상태를 전달할 때 사용.
  • 특징: SwiftUI의 뷰 계층구조를 따라 상태를 자동으로 전달.
class Theme: ObservableObject {
    @Published var color = Color.blue
}

struct ParentView: View {
    @StateObject private var theme = Theme()

    var body: some View {
        ChildView()
            .environmentObject(theme)
    }
}

struct ChildView: View {
    @EnvironmentObject var theme: Theme

    var body: some View {
        Rectangle()
            .fill(theme.color)
            .frame(width: 100, height: 100)
    }
}
  • @EnvironmentObject를 사용하면 부모-자식 관계를 명시적으로 전달하지 않아도 상태를 사용할 수 있습니다.

2. Combine 없이 처리 가능한 상황

Combine 없이도 SwiftUI의 상태 관리 도구만으로 대부분의 일반적인 앱의 요구 사항을 처리할 수 있습니다. 몇 가지 사례를 살펴보겠습니다.

(1) 사용자 입력 및 기본 상태 관리

  • 단순한 버튼 클릭, 텍스트 입력, 토글 등은 SwiftUI의 상태 관리 도구로 충분히 처리 가능합니다.

(2) 단일 뷰의 상태 변화

  • UI와 연결된 간단한 상태 변화(@State)는 Combine 없이도 자동으로 UI가 갱신됩니다.

(3) 부모-자식 간 상태 공유

  • @Binding을 사용하면 부모와 자식 간 상태를 쉽게 동기화할 수 있습니다.

(4) 전역 상태 관리

  • @EnvironmentObject를 사용하면 앱의 전역 상태를 관리할 수 있습니다.

3. Combine 없이 SwiftUI가 어려운 상황

SwiftUI만으로 처리하기 힘든 경우 Combine이 필요할 수 있습니다. 예를 들면:

(1) 비동기 작업

  • 네트워크 요청, 타이머, 파일 다운로드 등 비동기 작업은 SwiftUI 자체로는 처리하기 어렵습니다.

(2) 복잡한 데이터 변환 및 흐름

  • 여러 데이터 소스에서 데이터를 결합하거나 필터링할 때 SwiftUI 상태 관리만으로는 비효율적일 수 있습니다.

(3) 외부 이벤트 처리

  • 타사 API나 시스템 이벤트를 구독해야 하는 경우 Combine을 활용해야 합니다.

4. 결론

Combine 없이도 SwiftUI는 기본적인 상태 관리 및 UI 갱신 작업을 충분히 수행할 수 있습니다. 하지만 SwiftUI의 상태 관리 도구는 비교적 간단한 애플리케이션에 적합하며, 복잡한 비동기 작업이나 데이터 흐름 관리가 필요한 경우 Combine과의 조합이 필수적입니다.

Combine 없이 SwiftUI를 사용하는 것은 가능하지만, 더 복잡한 요구 사항이 있는 경우 Combine을 활용하면 더 간결하고 효율적으로 애플리케이션을 개발할 수 있습니다.

반응형

'iOS' 카테고리의 다른 글

[iOS] HTTPCookieStorage와 WKHTTPCookieStore 차이  (0) 2025.01.30
[iOS] 웹뷰(WebView)기반 앱 개발 시 주의할 점  (2) 2025.01.30
[iOS] SwiftUI와 Combine  (0) 2025.01.28
[iOS] SwiftUI와 MVVM  (0) 2025.01.27
SOLID 원칙  (1) 2025.01.26