user1302387
user1302387

Reputation: 358

How to use Combine in SwiftUI views without ObservableObject?

I am trying to keep my publishers that would normally live in an ObservableObject viewModel in the view itself. How is it possible to use combine within the Init of the view struct? The key here is not to use ObservableObject, or @StateObject, or a viewModel at all. For instance this doesn't work below.

struct ContentView: View {
  
  @State private var boolOne = false
  @State private var boolTwo = false
  @State private var boolsBoth = false
  
  private var cancellables = Set<AnyCancellable>()
  
  init() {
  // dummy publisher that doesn't nothing, not the point of the question
    Publishers.CombineLatest($boolOne, $boolTwo)
      .receive(on: RunLoop.main)
      .map { boolOne, boolTwo -> Bool in
        return true
      }
      .removeDuplicates()
      .sink(receiveValue: { value in
        boolsBoth = value
      })
  }
  
  var body: some View {
    VStack {
      Text("Hello, world!")
    }
    .padding()
  }
}

I get an error "Generic struct 'CombineLatest' requires that 'Binding' conform to 'Publisher'" on line 20 here. I know this can be done, but I haven't done it, and mostly all tutorials online use a viewModel pattern as an ObservableObject. Do I have to create an AnyPublisher var somewhere first or use eraseToAnyPublisher somewhere?

Upvotes: 2

Views: 451

Answers (1)

malhal
malhal

Reputation: 30746

As Jessy commented this idea of "view model" in SwiftUI is made up nonsense. Just learn the View struct, it does this already. Eg

MyView(bool1, bool2)

MyView's body will be called if bool1 or bool2 is different from last time.

Upvotes: 0

Related Questions