← ClaudeAtlas

ios-widgetlisted

Build and wire an iOS home-screen widget (WidgetKit) into a React Native app — the App Group snapshot architecture, adding the extension target to project.pbxproj by script, the Swift native module bridge, rendering the widget's image offscreen with Skia, dark mode, freshness, and the build verification traps. Use when the user asks to add, change, or debug a widget, a WidgetKit extension, an App Group, a home-screen widget, or a lock-screen widget; when a widget renders blank, stale, or light-only; or before touching anything under an ios/*Widget/ directory.
ltatarev/skills · ★ 0 · Web & Frontend · score 65
Install: claude install-skill ltatarev/skills
# iOS widgets in a React Native app A widget extension is a **separate process with its own sandbox**. It cannot read the app's container, cannot run JavaScript, and cannot host React Native. Everything it draws has to be either (a) reimplemented in Swift, or (b) handed to it through an App Group. **Do (b).** Reimplementing means two implementations of the same visual kept in sync by hand forever, plus forcing the database into the App Group. Record the choice as an ADR — it is architectural, hard to reverse, and surprising without context. Use `domain-model` for that. ## The shape of it ``` JS native ── ────── <feature>/widget/render.tsx ios/<App>/WidgetBridge.swift drawAsImage(<View/>) → PNG writes App Group + reloadTimelines() ↓ ↓ hooks/useWidgetSync.ts ios/Shared/WidgetStore.swift debounced publish on change ← compiled into BOTH targets → ↓ ↓ utils/widget (adapter) ──────► ios/<App>Widget/<App>Widget.swift NativeModules.WidgetBridge reads it, draws SwiftUI ``` | Piece | Owns | | --- | --- | | Offscreen render (`<feature>/widget/`) | one PNG per appearance, plus the counts/strings | | Publish loop (`hooks/useWidgetSync.ts`) | when to republish | | Adapter (`utils/widget/`) | the **only** place `NativeModules` is touched | | Bridge (`ios/<App>/Wid