[WWDC19] Data Flow Through SwiftUI

김민준·2022년 6월 9일
0

SwiftUI

목록 보기
1/1

Data Flow의 원리

  • 뷰에서 데이터를 읽으면 해당 뷰에 대한 종속성이 발생하게 됩니다.
    다시 말해, 데이터가 변경될 때마다 변경된 값을 반영하기 위해 해당 뷰를 다시 그려야 합니다.
  • 뷰 계층에서 읽은 모든 데이터마다 source of truth를 가지는데, source of truth는 뷰 계층 내 또는 외부(의 모델)에 있을 수 있습니다.
  • 그러나 반드시 서로 일치해야 하는 하나의 데이터에 대해 여러 개의 source of truth가 존재하고, 이 중 하나라도 값이 바뀐다면, 나머 source of truth에 대해서도 모두 동일하게 관리를 해주어야 일치시켜야 합니다. 이는 매우 번거롭고 어려운 일입니다.
  • 이처럼 중복으로 인해 발생하는 비정합성 등의 문제를 해결하려면 하나의 데이터에는 "단 하나의" source of truth만을 가지고 있는 것이 필요합니다.
  • SwiftUI의 Data Flow는 앱의 데이터에 대한 Single Source Of Truth(SSOT)를 유지하는데 도움을 주는 다양한 기능들을 제공하여 위에서 언급한 문제를 해결하게 됩니다.

@State

  • 프로퍼티를 @State 프로퍼티 래퍼로 감싸면, SwiftUI는 해당 프로퍼티가 언제 변경되는지 알 수 있습니다.
  • @State 프로퍼티 래퍼로 감싼 프로퍼티를 private로 접근 제어하면, 해당 뷰만이 그 프로퍼티를 소유하고 관리하게 할 수 있습니다.
  • @State 프로퍼티 래퍼로 감싼 프로퍼티가 변경되면, SwiftUI는 런타임에 해당 뷰와 그 자식 뷰들을 모두 재계산합니다.
  • 모든 변경 사항은 항상 뷰 계층을 따라 전파됩니다.
  • SwiftUI는 뷰를 비교하여 변경된 것만 다시 렌더링하기 때문에, 매우 효율적으로 뷰들의 변화를 반영할 수 있습니다.

@Binding

  • @Binding 프로퍼티 래퍼를 통해 프로퍼티를 직접 소유하지 않고도 해당 프로퍼티의 source of truth에 대한 명시적인 의존성을 정의할 수 있습니다.
  • Toggle, TextField, Slider와 같은 primitives view들은 binding을 필요로 합니다.
  • binding으로 프로퍼티를 "직접 소유하지 않고 참조"하여 읽거나 쓸 수 있습니다. 이를 통해 별도로 source of truth를 또 만들지 않고 하나만 유지할 수 있습니다.

Publisher(External Changes)

  • 뷰 계층 내부가 아닌 외부의 source로부터 이벤트를 받는 경우에는 Combine의 Publisher를 활용하게 됩니다.

ObservableObject(External Data)

  • 데이터가 뷰 외부에 있을 때, SwiftUI는 해당 데이터의 변경에 어떻게 반응할 것인지에 대해 알아야 합니다.
  • 먼저, 뷰 외부의 데이터가 ObservableObject 프로토콜을 준수하도록 함으로써, 데이터가 변경될 때마다 발생하는 objectWillChange 프로퍼티를 통해 액세스할 수 있는 Publisher가 있어야 합니다.
  • 이후에 모델을 @ObservedObject 프로퍼티 래퍼로 감싸고, ObservedObject를 뷰의 이니셜라이저에 전달하면 됩니다.
  • SwiftUI에서의 뷰는 value type(struct)이지만, reference type(class)을 사용할 때마다 @ObservedObject 프로퍼티 래퍼를 사용해야 합니다. 이렇게 하면 SwiftUI는 데이터가 언제 변경되는지 알고 뷰 계층을 최신 상태로 유지할 수 있습니다.

Environment

  • .environment modifier 덕분에 ObservableObject를 환경에 추가할 수 있습니다.
  • @EnvironemntObject 프로퍼티 래퍼를 사용하면 이러한 환경 객체들에 대한 종속성을 만들 수 있습니다.

Object Binding vs Environment

  • @Binding으로 전체 앱을 빌드할 수는 있지만, 뷰에서 뷰로 모델을 전달하는 것은 번거로울 수 있습니다.
  • EnvironmentObject는 계층 주변에 데이터를 간접적으로 전달하기에 편리합니다. 각 뷰에 객체를 직접 전달할 필요가 없어지기 때문입니다.

@State vs @ObservedObject

  • @State은 로컬 뷰, value type, 관리되는 데이터에 적합합니다.
  • @State는 SwiftUI에 의해 할당되고, 생성되고 관리됩니다.
  • @State는 value type입니다.
  • @ObservedObject는 데이터베이스와 같은 SwiftUI의 외부 데이터를 나타내기 위한 것입니다.
  • @ObservedObject는 우리가 직접 관리하는 storage이며,
    이미 가지고 있는 모델에 적합합니다.
  • @ObservedObject는 SwiftUI가 아니라 우리가 직접 관리합니다.
  • @ObservedObject는 reference type입니다.
profile
trial and error

0개의 댓글