Skip to content

Migrate Demo to ExyteChat 3.x and unblock the build on Xcode 27 - #448

Open
nezhyborets wants to merge 2 commits into
mainfrom
444-demo-app-fails-to-build-on-newer-xcode-exytechat-2x-needs-a-3x-migration
Open

nezhyborets wants to merge 2 commits into
mainfrom
444-demo-app-fails-to-build-on-newer-xcode-exytechat-2x-needs-a-3x-migration

Conversation

@nezhyborets

Copy link
Copy Markdown
Collaborator

Summary

Closes #444.

Demo/Demo.xcodeproj was failing to link on Xcode 27 with errors like:

Undefined symbols for architecture arm64:
  "variable initialization expression of ExyteChat.ChatView.(__isShowingMenu ...) : SwiftUI.LazyState<Swift.Bool>", referenced from: ...

Root cause

Two separate issues stacked here:

  1. ExyteChat's ChatView trips a Swift 6.4/Xcode 27 compiler bug. ChatView declares its @State properties in ChatView.swift but its designated initializer in a different file (ChatBuilderParameters.swift). That split-file shape is exactly what swiftlang/swift#91700 describes: the compiler can't link the "variable initialization expression" symbol for a @State property's default value when the initializer lives in another file. This affects ExyteChat 2.x (originally pinned here) and 3.x equally — it isn't a version issue.
  2. Bumping to ExyteChat 3.x (needed regardless, since 2.x is unmaintained relative to current Xcode) surfaces three unrelated, real API breaks in DemoChat.

Changes

  • Bump exyte/Chat from 2.5.7 to 3.3.0 and fix the fallout in DemoChat:
    • Drop .messageUseMarkdown(true) in DetailView.swift / ResponsesChatDetailView.swift — ChatView 3.x always applies markdown attributes to message text now, so the modifier no longer exists.
    • Drop Hashable from ResponsesStore.ConversationTurnExyteChat.Message lost Hashable in 3.x (Equatable only now), and the conformance wasn't used anywhere in DemoChat.
    • Pin exyte/AnchoredPopup to >=1.2.2 explicitly. MediaPicker 3.4.x calls PopupParameters.displayMode(_:), added in AnchoredPopup 1.2.0, but MediaPicker's own manifest still understates its requirement as from: "1.1.3". Without an explicit pin, SwiftPM's resolver can legitimately land on 1.1.3 and fail with "value of type 'PopupParameters' has no member 'displayMode'".
  • Point the Chat dependency at a fork branch, nezhyborets/Chat@macpaw-xcode27-init-fix, which moves ChatView's designated init into the same file as its @State declarations — the workaround the upstream Swift issue describes. This is also open upstream as exyte/Chat#302; once that (or the underlying Apple compiler fix) ships, Package.swift should go back to .package(url: "https://github.com/exyte/Chat.git", from: "3.3.0") (comment left in place noting this).

Test plan

  • xcodebuild -project Demo/Demo.xcodeproj -scheme Demo -destination "generic/platform=iOS Simulator" clean build — succeeds with zero errors (verified as a clean build, not incremental, since an incremental build can mask this specific linker failure by reusing a stale binary)
  • Installed and launched Demo in the iOS Simulator — renders correctly, no crash

Demo/Demo.xcodeproj fails to link on Xcode 27 because ExyteChat's ChatView
declares its @State properties in one file and its designated initializer
in another, which trips a Swift 6.4/Xcode 27 compiler bug
(swiftlang/swift#91700): the linker can't find the "variable initialization
expression" symbol for each @State property's default value.

- Bump exyte/Chat from 2.5.7 to 3.3.0, which required three follow-up fixes:
  - drop .messageUseMarkdown(true): ChatView 3.x always applies markdown
    attributes to message text now, the modifier no longer exists
  - drop Hashable from ResponsesStore.ConversationTurn: ExyteChat.Message
    lost Hashable in 3.x (Equatable only), and the conformance was unused
  - pin exyte/AnchoredPopup to >=1.2.2 explicitly: MediaPicker 3.4.x calls
    PopupParameters.displayMode(_:), added in AnchoredPopup 1.2.0, but
    MediaPicker's manifest still understates its own requirement as
    `from: "1.1.3"`, so SwiftPM could otherwise resolve an incompatible
    1.1.3 and fail to build
- Point Chat at a fork branch (nezhyborets/Chat@macpaw-xcode27-init-fix)
  that moves ChatView's designated init into the same file as its @State
  declarations, working around the Xcode 27 linker bug. Upstreamed as
  exyte/Chat#302. Revert to the tagged release once that lands and a fixed
  Xcode toolchain ships.

Verified with a full clean build (not incremental) and by installing and
launching Demo in the iOS Simulator.

Fixes #444

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Pin the mutable fork dependency to an immutable commit or release tag.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Migrates DemoChat to ExyteChat 3.x, updates incompatible APIs and dependency locks, and applies an Xcode 27 linker workaround.

Changes:

  • Removes obsolete markdown configuration and Hashable conformance.
  • Pins AnchoredPopup and refreshes resolved dependencies.
  • Uses a forked Chat branch containing the compiler workaround.

Review note: Pin the fork to an immutable commit or release tag for reproducibility.

File Description
Demo/​DemoChat/​Sources/​UI/​ResponsesChatDetailView.swift Removes obsolete markdown modifier.
Demo/​DemoChat/​Sources/​UI/​DetailView.swift Removes obsolete markdown modifier.
Demo/​DemoChat/​Sources/​ResponsesStore.swift Removes incompatible Hashable conformance.
Demo/​DemoChat/​Package.swift Updates Chat and AnchoredPopup dependencies.
Demo/​DemoChat/​Package.resolved Refreshes Swift package versions.
Demo/​Demo.xcodeproj/​project.xcworkspace/​xcshareddata/​swiftpm/​Package.resolved Synchronizes Xcode dependency resolution.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Demo/DemoChat/Package.swift Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It relies on a forked dependency and compiler-specific workaround requiring human validation.

Review effort: Lite
Findings: None

Resolved since last review (1)

exyte/Chat#302 merged and shipped in 3.3.3, so the fork branch used as a
stopgap is no longer needed. Point back at the upstream package.

Verified with a full clean build of Demo on Xcode 27.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@nezhyborets

Copy link
Copy Markdown
Collaborator Author

Update: exyte/Chat#302 merged and shipped in 3.3.3, so I switched this PR off the fork branch and back to the upstream package (from: "3.3.3"). Re-verified with a full clean build on Xcode 27 — still succeeds with zero linker errors.

The fork branch (nezhyborets/Chat@macpaw-xcode27-init-fix) is no longer referenced by anything here and can be deleted whenever convenient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Demo app fails to build on newer Xcode: ExyteChat 2.x needs a 3.x migration

2 participants