Hi, sorry for not providing enough code. I've made quick demo project that compiles and has my described issue:
import UIKit
import ComposableArchitecture
import Combine
final class Lake: Equatable {
init(title: String, id: Int) {
self.title = title
self.id = id
}
let title: String
let id: Int
static func == (lhs: Lake, rhs: Lake) -> Bool {
lhs.id == rhs.id && lhs.title == rhs.title
}
}
struct LakeBookState: Equatable {
var lakes: [Lake] = [Lake(title: "One", id: 1), Lake(title: "Two", id: 2),
Lake(title: "Three", id: 3), Lake(title: "Four", id: 4),
Lake(title: "Five", id: 5), Lake(title: "Six", id: 6), ]
var lakeToOpen: Lake?
}
enum LakeBookAction: Equatable {
case tappedLake(IndexPath)
}
struct LakeBookEnvironment { }
let lakeBookReducer = Reducer<LakeBookState, LakeBookAction, LakeBookEnvironment> { state, action, environment in
state.lakeToOpen = nil
switch action {
case .tappedLake(let indexPath):
state.lakeToOpen = state.lakes[indexPath.row]
return .none
}
}
final class ViewController: UIViewController {
let store: Store<LakeBookState, LakeBookAction>
let viewStore: ViewStore<LakeBookState, LakeBookAction>
var cancellables: Set<AnyCancellable> = []
init(store: Store<LakeBookState, LakeBookAction>) {
self.store = store
// removeDuplicates closure does nothing in my case
self.viewStore = ViewStore(store, removeDuplicates: { _, _ in
return false
})
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private lazy var tableView: UITableView = {
let tv = UITableView()
tv.translatesAutoresizingMaskIntoConstraints = false
tv.dataSource = self
tv.delegate = self
tv.backgroundColor = .white
tv.allowsSelection = true
tv.isUserInteractionEnabled = true
tv.separatorStyle = .singleLine
tv.delaysContentTouches = false
return tv
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
// this should open user selected lake
viewStore.publisher.lakeToOpen
.compactMap { $0 }
.sink { [weak self] lake in
self?.navigationController?.pushViewController(LakeViewViewController(), animated: true)
}
.store(in: &cancellables)
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
UITableViewCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
6
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
60
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// here I am handling cell taps
viewStore.send(.tappedLake(indexPath))
}
}
And SceneDelegate:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let vc = ViewController(store: Store(initialState: LakeBookState(),
reducer: lakeBookReducer,
environment: LakeBookEnvironment()))
let nav = UINavigationController(rootViewController: vc)
UIApplication.shared.windows.first?.rootViewController = nav
UIApplication.shared.windows.first?.makeKeyAndVisible()
self.window = UIWindow(windowScene: windowScene)
self.window?.rootViewController = nav
self.window?.makeKeyAndVisible()
}
(...)
So my issue is that if user taps same cell twice in a row (basically if we call viewStore.send(.tappedLake(indexPath))
for the same Lake) then viewStore.publisher.lakeToOpen
will ignore second event