SwiftUI and Clean Architecture

I have a question regarding SwiftUI (possibly with Clean architecture issue). I made a small test project with CleanSwift (Interactor/Worker/Presenter/View basically) and my view never updates. On Appear, I call the interactor, which calls the worker (network stuff), the photos are retrieved, passed along to the presenter who call the View's delegate method displayPhotos Here is the code

protocol PhotoListDisplayLogic {
  func displayPhotos(viewModel: PhotoList.FetchPhotots.ViewModel)
}

struct PhotoListView: View {
  let interactor: PhotoListBusinessLogic
  @State var photos: [PhotoContainer] = []
   
  init(interactor: PhotoListBusinessLogic) {
    self.interactor = interactor
  }
   
  var body: some View {
    VStack {
      if photos.isEmpty {
        ProgressView("Chargement...")
      } else {
        List(photos) { photo in
          PhotoListRow(photo: photo)
        }
      }
    }
    .onAppear{
      interactor.fetchPhotos(request: PhotoList.FetchPhotots.Request())
    }
  }
}

extension PhotoListView: PhotoListDisplayLogic {
  func displayPhotos(viewModel: PhotoList.FetchPhotots.ViewModel) {
    self.photos = viewModel.photos
  }
}

Weirdest thing : when I assign viewModel.photos to my @State var, it never updates the @State value (I have 30 photos in viewModel.photos and self.photos.count is always empty). I read here and there that the update to the @State var must be done inside the body (which is quite a limitation). Can someone spot what's wrong with this code, I guess I'm missing the elephant in the room here :D Thanks!

Answered by MahAlleinir in 746646022

Still have to figure out why, but I found a solution. If I wrap my photos in an ObservableObject as a Published var, and use @ObservedObject in my View, then it gets updated. I just don't get why to have to add an additional layer and why the @State if not enough :-/

How is PhotoContainer defined ?

Does it an ObservableObject, with a Published property like:

class PhotoContainer: ObservableObject {
    @Published var photoName =   ""
}
Accepted Answer

Still have to figure out why, but I found a solution. If I wrap my photos in an ObservableObject as a Published var, and use @ObservedObject in my View, then it gets updated. I just don't get why to have to add an additional layer and why the @State if not enough :-/

I'm pretty sure that if you put a return in your fetchPhotos method that populates the photos variable, the @State will suffice. Turns out you're not populating your variable, or at least you can't see that in your code above. Regarding the use of an extra layer, I suggest you take a look at this post on why to insulate in different layers, even if it seems redundant.

SwiftUI and Clean Architecture
 
 
Q