The following test fails on iOS 14 but passes in iOS 13:
func testCombineBug() {
class Store {
var cancellable: AnyCancellable?
@Published var count: Int
init(count: Int = 0) { self.count = count }
func scope() -> AnyPublisher<Store, Never> {
self.$count.map { count in
let child = Store(count: count)
child.cancellable = self.$count.sink { [weak child] count in
child?.count = count
}
return child
}
.eraseToAnyPublisher()
}
}
let parentStore = Store()
var outputs: [Int] = []
parentStore.scope()
.sink { childStore in
childStore.$count
.sink { outputs.append($0) }
.store(in: &self.cancellables)
}
.store(in: &self.cancellables)
XCTAssertEqual(outputs, [0])
parentStore.count = 1
XCTAssertEqual(outputs, [0, 1])
parentStore.count = 2
XCTAssertEqual(outputs, [0, 1, 2])
}If I swap out the @Published property for a CurrentValueSubject the test will pass again.
To reproduce open the sample project I have attached and run tests for iOS.
This may seem like a strange way to structure some publishers, but it’s important for our library that uses this style in order to drive UIKit navigation from state changes: https://github.com/pointfreeco/swift-composable-architecture/blob/c9c1a9a50040408c436e496bac35007add327186/Sources/ComposableArchitecture/Store.swift#L85-L123