Thread
#multiplatform
    Stefan Oltmann

    Stefan Oltmann

    1 year ago
    I get an error "EXC_BAD_ACCESS" when I try to call "onReceive":
    struct ContentView: View {
      @EnvironmentObject var store: ObservablePhotoStore
      var body: some View {
        VStack {
          Button("Show details") {
            store.dispatch(PhotoAction.Refresh())
          }
        }
        onReceive(store.$state) { value in
          print("test")
        }
      }
    }
    This is the observerved object:
    class ObservablePhotoStore: ObservableObject {
       
      @Published public var state: PhotoState = PhotoState(progress: false, photos: [], selectedPhoto: nil, testString: "never updated")
      @Published public var sideEffect: PhotoSideEffect?
       
      let store: PhotoStore
       
      var stateWatcher : Closeable?
      var sideEffectWatcher : Closeable?
    
      init(store: PhotoStore) {
         
        self.store = store
         
        stateWatcher = self.store.watchState().watch { [weak self] state in
          self?.state = state
        }
         
        sideEffectWatcher = self.store.watchSideEffect().watch { [weak self] state in
          self?.sideEffect = state
        }
      }
       
      public func dispatch(_ action: PhotoAction) {
        store.dispatch(action: action)
      }
       
      deinit {
        stateWatcher?.close()
        sideEffectWatcher?.close()
      }
    }
    @main
    class MyPhotoApp: App {
       
      let photoRepository: PhotoRepositoryImpl
      let store: ObservablePhotoStore
       
      required init() {
        photoRepository = PhotoRepositoryImpl()
        store = ObservablePhotoStore(store: PhotoStore(photoRepository: photoRepository))
      }
       
      var body: some Scene {
        WindowGroup {
          ContentView().environmentObject(store)
        }
      }
    }
    I'm new to SwitUI and I try to learn from https://github.com/Kotlin/kmm-production-sample how to receive changes in StateFlow to update my Swift UI. I'm looking for a simple way to do that and that sample project is already very complex.
    Eventually my goal is to throw my "store.state.photos" Array into a SwiftUI List that should be re-rendered if the contents change.
    Stephen Gazzard

    Stephen Gazzard

    1 year ago
    What is
    PhotoState
    ?
    Stefan Oltmann

    Stefan Oltmann

    1 year ago
    data class PhotoState(
        val progress: Boolean,
        val photos: List<Photo>,
        val selectedPhoto: Photo? = null,
        val testString: String
    ) : State
    interface State
    interface Action
    interface Effect
    
    interface Store<STATE : State, ACTION : Action, EFFECT : Effect> {
    
        fun observeState(): StateFlow<STATE>
    
        fun observeSideEffect(): Flow<EFFECT>
    
        fun dispatch(action: ACTION)
    
    }
    In the original code from @Kathrin Petrova this seems to work somehow, but not for me. I'm puzzled.