跳到主要内容
知仓学习社ZHICANG

preview-data-generator

Generate sample data and a multi-variant #Preview matrix for SwiftUI views — empty/loading/error/loaded states, light/dark, Dynamic Type, locales/RT…

不碰外部(只输出文字)无严重或高危命中rshankras/claude-code-apple-skills

它会碰到什么

扫了多少3 个文本文件,23 KB
它会碰到什么不碰外部(只输出文字)
命中总数0 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Preview Data Generator

Generates two tightly-coupled things for a SwiftUI view:

  1. Sample data tuned for the Xcode canvas — realistic instances plus the visual edge cases that break layouts (empty, one item, huge list, long/overflowing strings, missing images, error and loading states).
  2. A #Preview matrix — the variant blocks you'd otherwise hand-write to prototype and QA a view across light/dark, Dynamic Type, locale/RTL, device sizes, and data states.

This is the design-time counterpart to testing/test-data-factory (which makes fixtures for the test suite). Where a factory already exists, this skill reuses Model.fixture() instead of inventing parallel data.

When This Skill Activates

Use this skill when the user:

  • Wants sample/mock data for Xcode previews ("what do I put in the preview?")
  • Wants to preview a view in multiple states (empty / loading / error / loaded)
  • Is prototyping UI and wants light/dark, Dynamic Type, RTL, or device variants
  • Says "add previews", "preview matrix", "preview this in dark mode + large text"
  • Has a SwiftData @Model and needs an in-memory seeded container for previews
  • Is on Xcode 16 / iOS 18 and wants shared, cached preview data via PreviewModifier

Just need fixtures for unit tests? Use testing/test-data-factory instead.

Want screenshot regression tests? Pair this with testing/snapshot-test-setup — the same data + variant matrix feeds snapshot tests.

Reference Files

Load both before generating:

| File | Purpose |

|------|---------|

| preview-data-patterns.md | Sample-data design, the edge-case catalog, SwiftData in-memory seeding, PreviewModifier (iOS 18), @Previewable, reusing test-data-factory |

| preview-matrix.md | The variant axes, preview traits:, .environment overrides, deployment-target fallbacks (#Preview vs PreviewProvider), data-state previews |

Pre-Generation Checks

Generators are context-aware. Before writing code, detect:

| Check | How | Why it matters |

|-------|-----|----------------|

| Deployment target | Read project/.xcodeproj or Package.swift | iOS 17+ → #Preview macro; iOS 18+ → PreviewModifier + @Previewable; below 17 → PreviewProvider fallback |

| Target view + its models | Read the view file; Grep its init/properties for model types | Determines which types need sample data |

| Existing fixtures | Grep "static func fixture\|extension .*{ static (let\|var) preview" | Reuse Model.fixture() / existing .preview — never duplicate |

| SwiftData | Grep "@Model" on the model types | Use the in-memory .modelContainer(inMemory:) seed pattern, not plain structs |

| View shape | Does it take a model, a ViewModel, or fetch its own data? | Drives whether to inject data, a mock VM, or a seeded container |

| Platform | iOS / macOS / multiplatform | Device variants and some traits differ |

Ask via AskUserQuestion only what you can't infer — e.g. "Which states matter for this view: empty, loading, error, loaded, or all four?"

Generation Process

Step 1: Build the Sample Data

For each model the view needs, generate a Model.preview namespace with the realistic case and the edge cases (see preview-data-patterns.md for the full catalog):

extension Article {
    /// A typical, realistic instance for the canvas.
    static var preview: Article {
        Article(id: UUID(), title: "Designing for the Smallest Screen",
                author: "Mei Chen", body: String(repeating: "Lorem ipsum. ", count: 40),
                imageURL: URL(string: "https://picsum.photos/seed/1/600/400"),
                readMinutes: 6, isBookmarked: false)
    }

    /// Edge cases that expose layout bugs.
    static var previewLongTitle: Article { .preview.with(title: "An Extraordinarily, Almost Unreasonably Long Headline That Wraps") }
    static var previewNoImage: Article   { .preview.with(imageURL: nil) }
    static var previewList: [Article]    { (1...12).map { .preview.with(id: UUID(), title: "Article \($0)") } }
    static var previewEmpty: [Article]   { [] }
}

If Article.fixture() already exists (from test-data-factory), build .preview on top of it rather than re-specifying every field.

Step 2: Build the Preview Matrix

Generate the #Preview blocks for the axes that matter (see preview-matrix.md). Always include data states — that's the UI-prototyping payoff:

#Preview("Loaded")  { ArticleListView(state: .loaded(Article.previewList)) }
#Preview("Empty")   { ArticleListView(state: .empty) }
#Preview("Loading") { ArticleListView(state: .loading) }
#Preview("Error")   { ArticleListView(state: .error("No connection")) }

#Preview("Dark")        { ArticleListView(state: .loaded(Article.previewList)).preferredColorScheme(.dark) }
#Preview("XXL Text")    { ArticleListView(state: .loaded(Article.previewList)).dynamicTypeSize(.accessibility3) }
#Preview("German / RTL", traits: .sizeThatFitsLayout) {
    ArticleDetailView(article: .previewLongTitle).environment(\.locale, .init(identifier: "de"))
}

Scale the matrix to the request — don't emit 20 previews for a label. A reasonable default per view: the relevant data states + dark mode + one large Dynamic Type + (if the view has text that localizes) one long-language/RTL check.

Step 3: Wire Up Infrastructure (when needed)

  • SwiftData view → generate an in-memory previewContainer seeded with sample models, attached via .modelContainer(previewContainer).
  • Xcode 16 / iOS 18 → offer a PreviewModifier so the seeded container/data is built once and cached across every preview, applied with #Preview(traits: .modifier(SampleData())).
  • View needs @State/@Bindable → use @Previewable so state lives directly in the #Preview body.

Step 4: Place the Code

  • Sample data → Article+Preview.swift (one file per model, in the model's group).
  • Preview blocks → either appended to the view file (Apple's convention) or a sibling ArticleListView+Previews.swift for large matrices. Ask if unsure.
  • Wrap preview-only data in #if DEBUG so it never ships in release builds.

Output Format

After generating, always provide:

  • Files created — full paths (Article+Preview.swift, PreviewSupport.swift, etc.)
  • Integration steps — where the #Preview blocks went, how to open the canvas
  • Deployment-target notes — which API was used and why (#Preview / PreviewModifier / PreviewProvider)
  • Testing instructions — open the canvas, cycle the variants; if pairing with snapshots, how the data feeds snapshot-test-setup

Example Output Summary

✅ Generated previews for ArticleListView (iOS 18 target)

Files created:
  • Article+Preview.swift        — .preview, .previewLongTitle, .previewNoImage, .previewList, .previewEmpty
  • PreviewSupport.swift         — SampleData: PreviewModifier (cached in-memory container)
  • ArticleListView+Previews.swift — 7 #Preview blocks (4 states, dark, XXL text, German)

Integration:
  • Reused Article.fixture() from test-data-factory for base fields
  • Open ArticleListView+Previews.swift → canvas shows all 7 variants

API used: #Preview + PreviewModifier (.modifier) — shared container built once, cached.

When NOT to Use This Skill

  • Fixtures for the test suitetesting/test-data-factory
  • Snapshot/regression image teststesting/snapshot-test-setup (feed it this data)
  • A trivial view with no data → Xcode's autogenerated #Preview {} is enough
  • Locale-only preview helpersgenerators/localization-setup already covers locale preview helpers; reuse them

Cross-Skill Integration

generators/persistence-setup   → defines @Model types
        ↓
testing/test-data-factory      → Model.fixture() for tests
        ↓
generators/preview-data-generator (THIS SKILL)
   • reuses .fixture() for canvas data
   • builds the #Preview state/appearance matrix
        ↓
testing/snapshot-test-setup    → renders the same matrix for regression

Deliverables

  • [ ] Sample data per model: realistic instance + edge cases (empty, long, missing, list)
  • [ ] Existing .fixture()/.preview reused, not duplicated
  • [ ] #Preview matrix covering the view's data states + relevant appearance axes
  • [ ] Correct API for the deployment target (#Preview / PreviewModifier / PreviewProvider)
  • [ ] SwiftData views get a seeded in-memory container
  • [ ] Preview-only code guarded with #if DEBUG
  • [ ] Output summary with files, integration, and testing steps

Generate the data and the variants together. A preview is only as useful as the data in it — and a view is only proven when you've seen it empty, overflowing, in the dark, and at AX5.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。