Live chat combines sustained message traffic, image-heavy content, and a UI
people expect to scroll smoothly. I build the native app and its release
workflow, including chat, moderation tools, third-party emotes,
accessibility, widgets, Live Activities, and Siri Shortcuts.
I build it with AI coding agents and my own review plugins:
ios-code-review
reviews every pull request that changes code, and
apple-ui-craft
reviews interface and accessibility work.
Engineering decisions
Bounded message storage
Per-channel ring buffers overwrite at capacity in O(1). Observer updates
are batched, and a collection-view engine handles visible chat. Keeping
the latest conversation useful does not require retaining an unbounded
transcript in memory.
Concurrency and rendering
Swift 6 strict concurrency separates network and IRCv3 parsing from
main-actor UI state. That boundary makes ownership explicit and keeps
incoming traffic from turning every parsed message into immediate UI
work.
Shared emote work
The emote pipeline shares in-flight downloads and caps its caches at
48 MB in memory and 200 MB on disk. Widgets read a snapshot the app
writes to a shared App Group, and the app updates Live Activities on
the device, so the extensions never touch the network.
Architecture
How a chat message reaches the screen.
TwitchIRC over TLS
ParsingOff the main actor
Message storeBounded ring buffers
Native chatBatched UI updates
The tradeoff
SwiftUI provides the application structure; the chat surface uses a
collection-view engine where scrolling and reuse need closer control.
Native integration and accessibility remain part of the same product,
including VoiceOver, Dynamic Type, and Reduce Motion.