pointfreeco / swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
https://www.pointfree.co/collections/composable-architecture
MIT License
12.3k stars 1.43k forks source link

@Shared publisher extra emissions only on macOS previews #3168

Closed humblehacker closed 3 months ago

humblehacker commented 3 months ago

Description

If I use a publisher on @Shared(.appStorage(...)) to observe one piece of shared state, changes to any other @Shared(.appStorage(...)) properties will cause that publisher to emit again - but only in Previews on macOS (native or Catalyst).

Checklist

Expected behavior

Both the app and the preview should have the same behavior: both fields are incremented by 1 on each tap of the increment button.

Actual behavior

In previews on macOS only, foo is incremented by 1 while bar is incremented by 2.

Steps to reproduce

  1. Clone, build and run the following sample: https://github.com/humblehacker/TCASharedState
  2. Tap the increment button and note both fields increment by 1
  3. Run ContentView preview
  4. Tap the increment button

I also added a test that, unless I'm misunderstanding something, should pass but does not.

The Composable Architecture version information

0.11.1

Destination operating system

macOS 14.5

Xcode version information

Version 15.4 (15F31d)

Swift Compiler version information

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
stephencelis commented 3 months ago

@humblehacker The publisher emits on willSet, so I don't think we're doing anything to trigger such a bug. If I had to imagine this is a preview quirk/bug that should probably be filed with Apple.

Since I don't think this is a bug in the library, and since it is a minor issue that only affects previews, I'm going to convert to a discussion. If anyone figures out a workaround that isn't too invasive, we'd be interested in seeing a PR, though!