<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Morgan</title>
    <description>The latest articles on DEV Community by Morgan (@morganios).</description>
    <link>https://dev.to/morganios</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3923485%2F95988b16-b1f0-460c-8647-41a1e22b2784.jpg</url>
      <title>DEV Community: Morgan</title>
      <link>https://dev.to/morganios</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/morganios"/>
    <language>en</language>
    <item>
      <title>TCA 1.7 @ObservableState + Swift 6 — Tracing the @Reducer Macro Isolation Trap</title>
      <dc:creator>Morgan</dc:creator>
      <pubDate>Sun, 10 May 2026 15:44:25 +0000</pubDate>
      <link>https://dev.to/morganios/tca-17-observablestate-swift-6-tracing-the-reducer-macro-isolation-trap-3eh0</link>
      <guid>https://dev.to/morganios/tca-17-observablestate-swift-6-tracing-the-reducer-macro-isolation-trap-3eh0</guid>
      <description>&lt;p&gt;A retrospective of tracing the &lt;code&gt;@Reducer&lt;/code&gt; / &lt;code&gt;@ObservableState&lt;/code&gt; macro isolation trap in 5 attempts during new development of a personal iOS app on TCA 1.25.5. Under Swift 6 strict concurrency + module-default isolation inference, the macros auto-generate conformances that are forced to be main-actor-isolated, breaking compatibility with &lt;code&gt;nonisolated struct&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting Point — Deprecation Warnings During New Development
&lt;/h2&gt;

&lt;p&gt;I started building a personal app on TCA 1.25.5 from scratch. As soon as I wrote the first entry screen (an API key input form) using the &lt;code&gt;WithViewStore&lt;/code&gt; pattern, the Issue Navigator lit up with deprecation warnings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'WithViewStore' is deprecated: Use '@ObservableState' instead.
'init(_:observe:content:file:line:)' is deprecated: Use '@ObservableState' instead.
'ViewStoreOf' is deprecated: Use '@ObservableState' instead.

See the following migration guide:
https://swiftpackageindex.com/pointfreeco/swift-composable-architecture/main/documentation/composablearchitecture/migrationguides/migratingto17#using-observablestate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;WithViewStore&lt;/code&gt; is deprecated in TCA 1.7+, so even brand-new code triggers the warnings immediately. I followed the official migration guide to apply the &lt;code&gt;@ObservableState&lt;/code&gt; macro pattern.&lt;/p&gt;

&lt;p&gt;(As I added more views in the same pattern, the deprecation warnings accumulated to 30+.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Swift 6.0&lt;/li&gt;
&lt;li&gt;Xcode 26.x (the exact minor version relies on memory and is uncertain)&lt;/li&gt;
&lt;li&gt;TCA 1.25.5&lt;/li&gt;
&lt;li&gt;iOS 17+&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SWIFT_APPROACHABLE_CONCURRENCY = NO&lt;/code&gt; (set explicitly on the main target)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Time Axis — Same Trap, Different Detection Points
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;2026-04-12&lt;/strong&gt; — While writing the first entry screen (API key input form), I applied &lt;code&gt;@ObservableState&lt;/code&gt; + &lt;code&gt;@Reducer&lt;/code&gt; macros. &lt;strong&gt;The build passed, but the simulator hit a runtime stack overflow on launch.&lt;/strong&gt; The macro-applied code at this point was never committed (it was in-progress development; no traces in git).&lt;/p&gt;

&lt;p&gt;I fixed it with macro-avoidance + nonisolated struct + explicit Reducer pattern → the project's first commit reflects the fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2026-05-11 (today, about a month later)&lt;/strong&gt; — Trying to reproduce the same pattern. &lt;strong&gt;The build itself fails this time.&lt;/strong&gt; The compiler now validates the isolation of macro-generated conformances at compile time.&lt;/p&gt;

&lt;p&gt;Same trap, different detection points. In one month, the compiler moved the failure mode from runtime to compile time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 1 — &lt;code&gt;@Reducer struct&lt;/code&gt; (no &lt;code&gt;nonisolated&lt;/code&gt;)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Reducer&lt;/span&gt;
&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;@ObservableState&lt;/span&gt;
    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="kt"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;ReducerOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;Reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;SomeView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;swift&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;both&lt;/span&gt;
  &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="kd"&gt;actor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;isolated&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="kd"&gt;nonisolated&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;globalStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="o"&gt;^&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ The View runs in &lt;code&gt;@MainActor&lt;/code&gt; context (SwiftUI default). At Store init, the default argument is main-actor-isolated, while the macro-applied struct is inferred as nonisolated under &lt;code&gt;SWIFT_APPROACHABLE_CONCURRENCY = NO&lt;/code&gt;. &lt;strong&gt;They collide.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 2 — &lt;code&gt;@Reducer nonisolated struct&lt;/code&gt; + &lt;code&gt;@ObservableState&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Reducer&lt;/span&gt;
&lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;@ObservableState&lt;/span&gt;
    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@__swiftmacro_&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;_State_role_ObservationTracked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;swift&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="kd"&gt;actor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;isolated&lt;/span&gt; &lt;span class="n"&gt;conformance&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
         &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;Observable&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ The error originates from the macro-expanded file (&lt;code&gt;@__swiftmacro_*&lt;/code&gt;). &lt;strong&gt;The &lt;code&gt;@ObservableState&lt;/code&gt; macro auto-generates an &lt;code&gt;Observable&lt;/code&gt; conformance that is main-actor-isolated.&lt;/strong&gt; The struct is marked &lt;code&gt;nonisolated&lt;/code&gt;, but the conformance is main-actor-isolated → collision.&lt;/p&gt;

&lt;p&gt;A macro-expanded file is generated for every State property → multiple errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 3 — Removing &lt;code&gt;@ObservableState&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;What if we keep &lt;code&gt;@Reducer&lt;/code&gt; but drop &lt;code&gt;@ObservableState&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@Reducer&lt;/span&gt;
&lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;// @ObservableState removed&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@__swiftmacro_&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;_Action_CasePathable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;swift&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="kd"&gt;actor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;isolated&lt;/span&gt; &lt;span class="n"&gt;conformance&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Action&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
         &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;CasePathable&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;cannot&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ &lt;strong&gt;The &lt;code&gt;@Reducer&lt;/code&gt; macro also auto-generates a &lt;code&gt;CasePathable&lt;/code&gt; conformance for Action that is main-actor-isolated.&lt;/strong&gt; Removing only &lt;code&gt;@ObservableState&lt;/code&gt; doesn't solve it.&lt;/p&gt;

&lt;p&gt;All macro-generated conformances are main-actor-isolated. Macro usage itself is incompatible with nonisolated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 4 — Removing &lt;code&gt;@Reducer&lt;/code&gt; (no &lt;code&gt;: Reducer&lt;/code&gt;)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// : Reducer not declared&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;ReducerOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;SomeView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;swift&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt;
  &lt;span class="n"&gt;conform&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="kt"&gt;Reducer&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Without the &lt;code&gt;@Reducer&lt;/code&gt; macro, the auto-added &lt;code&gt;Reducer&lt;/code&gt; protocol conformance disappears. You need to declare &lt;code&gt;: Reducer&lt;/code&gt; explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolution — Avoid Macros Entirely
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Reducer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="kt"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;ReducerOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;Reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ &lt;strong&gt;Avoid macros entirely + &lt;code&gt;nonisolated struct&lt;/code&gt; + explicit &lt;code&gt;: Reducer&lt;/code&gt; conformance + &lt;code&gt;var body&lt;/code&gt;.&lt;/strong&gt; Build passes; unit and integration tests pass.&lt;/p&gt;

&lt;p&gt;A direct &lt;code&gt;func reduce&lt;/code&gt; is also equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Reducer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="nv"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;inout&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Effect&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both patterns work. My project standardized on &lt;code&gt;var body + Reduce&lt;/code&gt; for consistency across all reducers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side Discovery — &lt;code&gt;SWIFT_APPROACHABLE_CONCURRENCY = NO&lt;/code&gt; Doesn't Save You
&lt;/h2&gt;

&lt;p&gt;The hypothesis I held going in:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Setting &lt;code&gt;SWIFT_APPROACHABLE_CONCURRENCY = NO&lt;/code&gt; switches the default inference back to nonisolated → macro-auto conformances also become nonisolated → no collision."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Verification — partially correct.&lt;/strong&gt; The module-default isolation inference does fall back to nonisolated, but &lt;strong&gt;TCA macros (&lt;code&gt;@Reducer&lt;/code&gt; / &lt;code&gt;@ObservableState&lt;/code&gt;) generate main-actor-isolated conformances regardless of &lt;code&gt;SWIFT_APPROACHABLE_CONCURRENCY&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project already has &lt;code&gt;SWIFT_APPROACHABLE_CONCURRENCY = NO&lt;/code&gt; set explicitly on the main target. Applying macros still triggers the same isolation collisions. → The macros themselves seem to enforce main-actor isolation for SwiftUI integration purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side Discovery — Macros Bind Feature and View as a Pair
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feature macro + View macro&lt;/td&gt;
&lt;td&gt;Isolation collisions (verified in attempts 1–3, workaround unknown)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature macro + View &lt;code&gt;WithViewStore&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;(Deprecation warnings remain)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feature macro-avoidance + View &lt;code&gt;@Bindable&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Compiler type-check timeout&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature macro-avoidance + View &lt;code&gt;WithViewStore&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅ Current pick (deprecation warnings only)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Trying a macro-avoiding Feature with a macro-assuming View:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Feature: macro-avoidance&lt;/span&gt;
&lt;span class="kd"&gt;nonisolated&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Reducer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// View: assumes macros&lt;/span&gt;
&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SomeView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;@Bindable&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;StoreOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;SomeFeature&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;Form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API Key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sending&lt;/span&gt;&lt;span class="p"&gt;(\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apiKeyChanged&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The compiler is unable to type-check this expression in reasonable time;
try breaking up the expression into distinct sub-expressions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ Without &lt;code&gt;@ObservableState&lt;/code&gt;, &lt;code&gt;$store.apiKey.sending(...)&lt;/code&gt; can't infer the keypath. The compiler keeps trying to resolve types and times out. &lt;strong&gt;Macros bind Feature and View as a pair. Partial application doesn't work.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The TCA 1.7+ official migration guide explains the SwiftUI integration path well, but it doesn't address &lt;strong&gt;the incompatibility between Swift 6 strict concurrency and macro-generated isolation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Macro usage vs avoidance — pick one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All macros&lt;/strong&gt; — TCA 1.7+ modern style. But within my verified scope, there's no known workaround for the Swift 6 isolation conflict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All macro avoidance&lt;/strong&gt; — Accept the &lt;code&gt;WithViewStore&lt;/code&gt; deprecation warnings + nonisolated struct + explicit Reducer protocol conformance. No build/runtime/test impact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This app went with the latter. Accept 30+ warnings, avoid macros.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same Trap, Different Detection Points — Meta
&lt;/h2&gt;

&lt;p&gt;The most striking meta point — &lt;strong&gt;in about one month, the compiler moved the failure point&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2026-04-12&lt;/strong&gt;: Build passed → runtime stack overflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2026-05-11&lt;/strong&gt;: Caught at compile time (conformance isolation validation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same pattern, same environment (assumed), but different detection points. A trace of an Xcode minor update or environment change. On my current Xcode 26.2 / Swift 6.0, &lt;strong&gt;getting caught at compile time is the new normal&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
    </item>
  </channel>
</rss>
