🔧 AI Nachrichten Generative AI: This Is How You Can Use ChatGPT Safely(27.08.2026 um 14:51 Uhr)
⚠️ Malware / Trojaner / VirenMajor Cyber Attacks, Data Breaches, Ransomware Attacks in August 2026(01.09.2026 um 08:30 Uhr)
🔧 AI Nachrichten LLM Fallback: What Happens When Your Model Goes Down(01.09.2026 um 01:00 Uhr)
🕵️ SicherheitslückenHackers Breach 5,000 Dropbox Accounts Through Lenovo ID Authentication Flaw(02.09.2026 um 20:09 Uhr)
⚠️ Malware / Trojaner / VirenMeet Manic: The Android Malware With a Sneaky Backup Plan(25.08.2026 um 08:00 Uhr)
🕵️ SicherheitslückenGoogle fixes the sixth actively exploited Chrome zero-day of 2026(04.09.2026 um 10:24 Uhr)
🕵️ SicherheitslückenPostgreSQL Hit by 12-Year-Old Vulnerability Allowing Server Takeover(04.09.2026 um 15:41 Uhr)
🕵️ SicherheitslückenPaperCut Flaws Exploited in Attacks on U.S. and European Schools(05.09.2026 um 20:47 Uhr)
🔧 AI Nachrichten OpenAI Announced $1B in Defensive Tools for Water Utilities(05.09.2026 um 23:14 Uhr)
🔧 AI Nachrichten Generative AI: This Is How You Can Use ChatGPT Safely(27.08.2026 um 14:51 Uhr)
⚠️ Malware / Trojaner / VirenMajor Cyber Attacks, Data Breaches, Ransomware Attacks in August 2026(01.09.2026 um 08:30 Uhr)
🔧 AI Nachrichten LLM Fallback: What Happens When Your Model Goes Down(01.09.2026 um 01:00 Uhr)
🕵️ SicherheitslückenHackers Breach 5,000 Dropbox Accounts Through Lenovo ID Authentication Flaw(02.09.2026 um 20:09 Uhr)
⚠️ Malware / Trojaner / VirenMeet Manic: The Android Malware With a Sneaky Backup Plan(25.08.2026 um 08:00 Uhr)
🕵️ SicherheitslückenGoogle fixes the sixth actively exploited Chrome zero-day of 2026(04.09.2026 um 10:24 Uhr)
🕵️ SicherheitslückenPostgreSQL Hit by 12-Year-Old Vulnerability Allowing Server Takeover(04.09.2026 um 15:41 Uhr)
🕵️ SicherheitslückenPaperCut Flaws Exploited in Attacks on U.S. and European Schools(05.09.2026 um 20:47 Uhr)
🔧 AI Nachrichten OpenAI Announced $1B in Defensive Tools for Water Utilities(05.09.2026 um 23:14 Uhr)

🔧 Programmierung 🕛 kürzlich 6 Min Lesezeit
0

TCA 1.7 @ObservableState + Swift 6 — Tracing the @Reducer Macro Isolation Trap

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

A retrospective of tracing the @Reducer / @ObservableState 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 nonisolated struct.






Starting Point — Deprecation Warnings During New Development



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 WithViewStore pattern, the Issue Navigator lit up with deprecation warnings:




CODE
'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






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



(As I added more views in the same pattern, the deprecation warnings accumulated to 30+.)






Environment




  • Swift 6.0

  • Xcode 26.x (the exact minor version relies on memory and is uncertain)

  • TCA 1.25.5

  • iOS 17+


  • SWIFT_APPROACHABLE_CONCURRENCY = NO (set explicitly on the main target)






Time Axis — Same Trap, Different Detection Points



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



I fixed it with macro-avoidance + nonisolated struct + explicit Reducer pattern → the project's first commit reflects the fix.



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



Same trap, different detection points. In one month, the compiler moved the failure mode from runtime to compile time.






Attempt 1 — @Reducer struct (no nonisolated)






CODE
@Reducer
struct SomeFeature {
@ObservableState
struct State: Equatable { ... }
enum Action: Equatable { ... }
var body: some ReducerOf<Self> {
Reduce { state, action in ... }
}
}






Build result:




CODE
SomeView.swift:13: error: default argument cannot be both
main actor-isolated and nonisolated
@State private var globalStore = Store(
^






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






Attempt 2 — @Reducer nonisolated struct + @ObservableState






CODE
@Reducer
nonisolated struct SomeFeature {
@ObservableState
struct State: Equatable { ... }
...
}






Build result:




CODE
@__swiftmacro_*_State_role_ObservationTracked.swift:7:32:
error: main actor-isolated conformance of 'SomeFeature.State'
to 'Observable' cannot be used in nonisolated context






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



A macro-expanded file is generated for every State property → multiple errors.






Attempt 3 — Removing @ObservableState



What if we keep @Reducer but drop @ObservableState?




CODE
@Reducer
nonisolated struct SomeFeature {
struct State: Equatable { ... } // @ObservableState removed
...
}






Build result:




CODE
@__swiftmacro_*_Action_CasePathable.swift:3:17:
error: main actor-isolated conformance of 'SomeFeature.Action'
to 'CasePathable' cannot be used in nonisolated context






The @Reducer macro also auto-generates a CasePathable conformance for Action that is main-actor-isolated. Removing only @ObservableState doesn't solve it.



All macro-generated conformances are main-actor-isolated. Macro usage itself is incompatible with nonisolated.






Attempt 4 — Removing @Reducer (no : Reducer)






CODE
nonisolated struct SomeFeature {  // : Reducer not declared
var body: some ReducerOf<Self> { ... }
}






Build result:




CODE
SomeView.swift: error: argument type 'SomeFeature' does not
conform to expected type 'Reducer'






→ Without the @Reducer macro, the auto-added Reducer protocol conformance disappears. You need to declare : Reducer explicitly.






Resolution — Avoid Macros Entirely






CODE
nonisolated struct SomeFeature: Reducer {
struct State: Equatable { ... }
enum Action: Equatable { ... }
var body: some ReducerOf<Self> {
Reduce { state, action in ... }
}
}






Avoid macros entirely + nonisolated struct + explicit : Reducer conformance + var body. Build passes; unit and integration tests pass.



A direct func reduce is also equivalent:




CODE
nonisolated struct SomeFeature: Reducer {
func reduce(into state: inout State, action: Action) -> Effect<Action> {
switch action { ... }
}
}






Both patterns work. My project standardized on var body + Reduce for consistency across all reducers.






Side Discovery — SWIFT_APPROACHABLE_CONCURRENCY = NO Doesn't Save You



The hypothesis I held going in:




"Setting SWIFT_APPROACHABLE_CONCURRENCY = NO switches the default inference back to nonisolated → macro-auto conformances also become nonisolated → no collision."




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



This project already has SWIFT_APPROACHABLE_CONCURRENCY = NO 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.






Side Discovery — Macros Bind Feature and View as a Pair




























Scenario Result
Feature macro + View macro Isolation collisions (verified in attempts 1–3, workaround unknown)
Feature macro + View WithViewStore
(Deprecation warnings remain)
Feature macro-avoidance + View @Bindable Compiler type-check timeout
Feature macro-avoidance + View WithViewStore
✅ Current pick (deprecation warnings only)


Trying a macro-avoiding Feature with a macro-assuming View:




CODE
// Feature: macro-avoidance
nonisolated struct SomeFeature: Reducer {
struct State: Equatable {
var apiKey: String = ""
...
}
...
}

// View: assumes macros
struct SomeView: View {
@Bindable var store: StoreOf<SomeFeature>

var body: some View {
Form {
TextField("API Key", text: $store.apiKey.sending(\.apiKeyChanged))
}
}
}






Build result:




CODE
The compiler is unable to type-check this expression in reasonable time;
try breaking up the expression into distinct sub-expressions






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






Conclusion



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



Macro usage vs avoidance — pick one:





  • All macros — TCA 1.7+ modern style. But within my verified scope, there's no known workaround for the Swift 6 isolation conflict.


  • All macro avoidance — Accept the WithViewStore deprecation warnings + nonisolated struct + explicit Reducer protocol conformance. No build/runtime/test impact.



This app went with the latter. Accept 30+ warnings, avoid macros.






Same Trap, Different Detection Points — Meta



The most striking meta point — in about one month, the compiler moved the failure point.





  • 2026-04-12: Build passed → runtime stack overflow


  • 2026-05-11: Caught at compile time (conformance isolation validation)



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, getting caught at compile time is the new normal.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 40%
🟡 In Evaluierung 32%
🟢 Keine Auswirkung 13%
Spannende Innovation 15%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Generative AI: This Is How You Can Use ChatGPT Safely
1 Quelle
Major Cyber Attacks, Data Breaches, Ransomware Attacks in August 2026
1 Quelle
LLM Fallback: What Happens When Your Model Goes Down
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten TCA 1.7 @ObservableState + Swift 6 — Tracing the @Reducer Macro Isolation Trap

Thematisch verwandte Begriffe: ObservableState, Swift, Tracing, Reducer · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...