Token导航 LogoToken导航

Agent Skill · 开发

axiom-core-data-diag(Axiom 核心数据诊断)

用于辅助数据整理、表格处理、CSV/Excel 分析、指标计算和图表准备。它适合让 Agent 清洗字段、汇总数据、发现异常、生成统计口径或把分析结果转成可读说明。使用时需要确认数据来源、字段含义和时间范围,避免把样本数据当全量事实;涉及敏感数据、导出文件或批量写回时,应先确认权限和脱敏边界。

axiom-core-data-diag 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 6,980。

总安装 4,162周安装 170GitHub Stars 868下载 1,346核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:axiom-core-data-diag(Axiom 核心数据诊断)
来源仓库:https://github.com/charleswiltgen/axiom
仓库路径:skills/axiom-core-data-diag
安装命令:
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-core-data-diag
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-core-data-diag

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

诊断 Core Data 线程违规、模式迁移失败与关系查询异常。提供 Unresolvable fault 与并发错误的排查路径。85% 生产环境问题源于误解线程限制与迁移规则。建议使用 Xcode 数据模型验证器预检 schema 变更。

axiom-core-data-diag 属于开发类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/axiom-core-data-diag

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/charleswiltgen/axiom --skill axiom-core-data-d…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

axiom-core-data-diag 怎么安装?

在终端执行 npx skills add https://github.com/charleswiltgen/axiom --skill axiom-core-data-diag。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

axiom-core-data-diag 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

axiom-core-data-diag 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

axiom-core-data-diag 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

axiom-core-data-diag 用的人多吗?

公开数据是累计安装 4,162 次,近一周安装 170 次,下载 1,346 次,GitHub 868 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

axiom-core-data-diag 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
axiom-core-data-diag

Axiom 核心数据诊断 · 本页

4,162868需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Core Data Diagnostics & Migration

Overview

Core Data issues manifest as production crashes from schema mismatches, mysterious concurrency errors, performance degradation under load, and data corruption from unsafe migrations. Core principle 85% of Core Data problems stem from misunderstanding thread-confinement, schema migration requirements, and relationship query patterns—not Core Data defects.

Red Flags — Suspect Core Data Issue

If you see ANY of these, suspect a Core Data misunderstanding, not framework breakage:

  • Crash on production launch: "Unresolvable fault" after schema change
  • Thread-confinement error: "Accessing NSManagedObject on a different thread"
  • App suddenly slow after adding a User→Posts relationship
  • SwiftData app needs complex features; considering mixing Core Data alongside
  • Schema migration works in simulator but crashes on production
  • ❌ FORBIDDEN "Core Data is broken, we need a different database"

- Core Data handles trillions of records in production apps - Schema mismatches and thread errors are always developer code, not framework - Do not rationalize away the issue—diagnose it

Critical distinction Simulator deletes the database on each rebuild, hiding schema mismatch issues. Real devices keep persistent databases and crash immediately on schema mismatch. MANDATORY: Test migrations on real device with real data before shipping.

Mandatory First Steps

ALWAYS run these FIRST (before changing code):

// 1. Identify the crash/issue type
// Screenshot the crash message and note:
//   - "Unresolvable fault" = schema mismatch
//   - "different thread" = thread-confinement
//   - Slow performance = N+1 queries or fetch size issues
//   - Data corruption = unsafe migration
// Record: "Crash type: [exact message]"

// 2. Check if it's schema mismatch
// Compare these:
let coordinator = persistentStoreCoordinator
let model = coordinator.managedObjectModel
let store = coordinator.persistentStores.first

// Get actual store schema version:
do {
    let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(
        ofType: NSSQLiteStoreType,
        at: storeURL,
        options: nil
    )
    print("Store version identifier: \(metadata[NSStoreModelVersionIdentifiersKey] ?? "unknown")")

    // Get app's current model version:
    print("App model version: \(model.versionIdentifiers)")

    // If different = schema mismatch
} catch {
    print("Schema check error: \(error)")
}
// Record: "Store version vs. app model: match or mismatch?"

// 3. Check thread-confinement for concurrency errors
// For any NSManagedObject access:
print("Main thread? \(Thread.isMainThread)")
print("Context concurrency type: \(context.concurrencyType.rawValue)")
print("Accessing from: \(Thread.current)")
// Record: "Thread mismatch? Yes/no"

// 4. Profile relationship access for N+1 problems
// In Xcode, run with arguments:
// -com.apple.CoreData.SQLDebug 1
// Check Console for SQL queries:
//   SELECT * FROM USERS;  (1 query)
//   SELECT * FROM POSTS WHERE user_id = 1;  (1 query per user = N+1!)
// Record: "N+1 found? Yes/no, how many extra queries"

// 5. Check SwiftData vs. Core Data confusion
if #available(iOS 17.0, *) {
    // If using SwiftData @Model + Core Data simultaneously:
    // Error: "Store is locked" or "EXC_BAD_ACCESS"
    // = trying to access same database from both layers
    print("Using both SwiftData and Core Data on same store?")
}
// Record: "Mixing SwiftData + Core Data? Yes/no"
What this tells you
  • Schema mismatch → Proceed to Pattern 1 (lightweight migration decision)
  • Thread-confinement error → Proceed to Pattern 2 (async/await concurrency)
  • N+1 queries → Proceed to Pattern 3 (relationship prefetching)
  • SwiftData + Core Data conflict → Proceed to Pattern 4 (bridging)
  • Slow after migration → Proceed to Pattern 5 (testing safety)
MANDATORY INTERPRETATION

Before changing ANY code, identify ONE of these:

  1. If crash is "Unresolvable fault" AND store/model versions differ → Schema mismatch (not user error)
  2. If crash mentions "different thread" AND you're using DispatchQueue → Thread-confinement (not thread-safe design)
  3. If performance degrades with relationship access → N+1 queries (check SQL log)
  4. If SwiftData and Core Data code exist together → Conflicting data layers (architectural issue)
  5. If migration test passes but production fails → Edge case in real data (testing gap)
If diagnostics are contradictory or unclear
  • STOP. Do NOT proceed to patterns yet
  • Add print statements to every NSManagedObject access (thread check)
  • Add -com.apple.CoreData.SQLDebug 1 and count SQL queries
  • Establish baseline: what's actually happening vs. what you assumed

Decision Tree

Core Data problem suspected?
├─ Crash: "Unresolvable fault"?
│  └─ YES → Schema mismatch (store ≠ app model)
│     ├─ Add new required field? → Pattern 1a (lightweight migration)
│     ├─ Remove field, rename, or change type? → Pattern 1b (heavy migration)
│     └─ Don't know how to fix? → Pattern 1c (testing safety)
│
├─ Crash: "different thread"?
│  └─ YES → Thread-confinement violated
│     ├─ Using DispatchQueue for background work? → Pattern 2a (async context)
│     ├─ Mixing Core Data with async/await? → Pattern 2b (structured concurrency)
│     └─ SwiftUI @FetchRequest causing issues? → Pattern 2c (@FetchRequest safety)
│
├─ Performance: App became slow?
│  └─ YES → Likely N+1 queries
│     ├─ Accessing user.posts in loop? → Pattern 3a (prefetching)
│     ├─ Large result set? → Pattern 3b (batch sizing)
│     └─ Just added relationships? → Pattern 3c (relationship tuning)
│
├─ Using both SwiftData and Core Data?
│  └─ YES → Data layer conflict
│     ├─ Need Core Data features SwiftData lacks? → Pattern 4a (drop to Core Data)
│     ├─ Already committed to SwiftData? → Pattern 4b (stay in SwiftData)
│     └─ Unsure which to use? → Pattern 4c (decision framework)
│
└─ Migration works locally but crashes in production?
   └─ YES → Testing gap
      ├─ Didn't test with real data? → Pattern 5a (production testing)
      ├─ Schema change affects large dataset? → Pattern 5b (migration safety)
      └─ Need verification before shipping? → Pattern 5c (pre-deployment checklist)

Common Patterns

Pattern Selection Rules (MANDATORY)

Apply ONE pattern at a time, starting with diagnostics
  1. Always start with Mandatory First Steps — Identify the actual problem
  2. Run decision tree — Narrow to specific pattern
  3. Apply ONE pattern — Don't combine patterns
  4. Test on real device — Simulator hides issues
  5. Verify with migration test — Before deploying
FORBIDDEN
  • ❌ Changing code without diagnostics
  • ❌ Skipping real device testing
  • ❌ Using simulator success as proof of migration safety
  • ❌ Mixing multiple migration patterns
  • ❌ Deploying migrations without pre-deployment verification

Pattern 1a: Lightweight Migration (Simple Schema Changes)

PRINCIPLE Core Data can automatically migrate simple schemas (additive changes) without data loss if done correctly.

✅ SAFE Lightweight Migrations
  • Adding new optional field: @NSManaged var nickname: String?
  • Adding new required field WITH default: Create attribute with default value
  • Renaming entity or attribute: Use mapping model with automatic mapping
  • Removing unused field: Just delete from model (data stays on disk, ignored)
❌ WRONG (Crashes production)
// BAD: Adding required field without migration
@NSManaged var userID: String  // Required, no default

// BAD: Assuming simulator = production
// Works in simulator (deletes DB), crashes on real device

// BAD: Modifying field type
@NSManaged var createdAt: Date  // Was String, now Date
// Core Data can't automatically convert
✅ CORRECT (Safe lightweight migration)
// 1. In Xcode: Editor → Add Model Version
// Creates new .xcdatamodel version file

// 2. In new version, add required field WITH default:
@NSManaged var userID: String = UUID().uuidString

// 3. Mark as current model version:
// File Inspector → Versioned Core Data Model
// Check "Current Model Version"

// 4. Test:
// Simulate old version: delete app, copy old database, run with new code
// Real app loads → migration succeeded

// 5. Deploy when confident
When this works
  • Adding optional fields (always safe)
  • Adding required fields WITH default values
  • Removing fields
  • Renaming entities/attributes with mapping model
When this FAILS (don't try lightweight)
  • Changing field type (String → Int)
  • Making optional field required (data has nulls, can't convert)
  • Complex relationship changes
  • Custom data transformations needed

Time cost 5-10 minutes for lightweight migration setup


Pattern 1b: Heavy Migration (Complex Schema Changes)

PRINCIPLE When lightweight migration won't work, use NSEntityMigrationPolicy for custom transformation logic.

Use when
  • Changing field types (String → Date)
  • Making optional required (need to populate existing nulls)
  • Complex relationship restructuring
  • Custom data transformations (e.g., split "firstName lastName" into separate fields)
Example: Convert String dates to Date objects
// 1. Create mapping model
// File → New → Mapping Model
// Source: old version, Destination: new version

// 2. Create custom migration policy
class DateMigrationPolicy: NSEntityMigrationPolicy {
    override func createDestinationInstances(
        forSource sInstance: NSManagedObject,
        in mapping: NSEntityMapping,
        manager: NSMigrationManager
    ) throws {
        let destination = NSEntityDescription.insertNewObject(
            forEntityName: mapping.destinationEntityName ?? "",
            into: manager.destinationContext
        )

        for key in sInstance.entity.attributesByName.keys {
            destination.setValue(sInstance.value(forKey: key), forKey: key)
        }

        // Custom transformation: String → Date
        if let dateString = sInstance.value(forKey: "createdAt") as? String,
           let date = ISO8601DateFormatter().date(from: dateString) {
            destination.setValue(date, forKey: "createdAt")
        } else {
            destination.setValue(Date(), forKey: "createdAt")
        }

        manager.associate(source: sInstance, withDestinationInstance: destination, for: mapping)
    }
}

// 3. In mapping model Inspector:
// Set Custom Policy Class: DateMigrationPolicy

// 4. Test extensively with real data before shipping
Critical safety rules
  • ALWAYS backup database before testing migration
  • Test migration on COPY of production data
  • Verify data integrity after migration (spot checks)
  • Create rollback plan if migration fails

Time cost 30-60 minutes per migration + testing


Pattern 2a: Async Context for Background Fetching

PRINCIPLE Core Data objects are thread-confined. Fetch on background thread, convert to lightweight representations for main thread.

❌ WRONG (Thread-confinement crash)
DispatchQueue.global().async {
    let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    let results = try! context.fetch(request)

    DispatchQueue.main.async {
        self.objects = results  // ❌ CRASH: objects faulted on background thread
    }
}
✅ CORRECT (Use private queue context for background work)
// Create background context
let backgroundContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
backgroundContext.parent = viewContext

// Fetch on background thread
backgroundContext.perform {
    do {
        let results = try backgroundContext.fetch(userRequest)

        // Convert to lightweight representation BEFORE main thread
        let userIDs = results.map { $0.id }  // Just the IDs, not full objects

        DispatchQueue.main.async {
            // On main thread, fetch full objects from main context
            let mainResults = try self.viewContext.fetch(request)
            self.objects = mainResults
        }
    } catch {
        print("Fetch error: \(error)")
    }
}
Why this works
  • Background context fetches on background thread (safe)
  • Converts heavy objects to lightweight values (safe to pass to main)
  • Main context fetches on main thread (safe)
  • No thread-confined objects crossing thread boundaries

Time cost 10 minutes to restructure


Pattern 2b: Structured Concurrency (async/await with Core Data)

PRINCIPLE Use NSPersistentContainer or NSManagedObjectContext async methods for Swift Concurrency compatibility.

✅ CORRECT (iOS 13+ async APIs)
// iOS 13+: Use async perform
let users = try await viewContext.perform {
    try viewContext.fetch(userRequest)
}
// Executes fetch on correct thread, returns to caller

// iOS 17+: Use Swift Concurrency async/await directly
let users = try await container.mainContext.fetch(userRequest)

// For background work:
let backgroundUsers = try await backgroundContext.perform {
    try backgroundContext.fetch(userRequest)
}
// Fetch happens on background queue, thread-safe
❌ WRONG (Mixing Swift Concurrency with DispatchQueue)
async {
    DispatchQueue.global().async {
        try context.fetch(request)  // ❌ Wrong thread!
    }
}

Time cost 5 minutes to convert from DispatchQueue to async/await


Pattern 3a: Relationship Prefetching (Prevent N+1)

PRINCIPLE Tell Core Data to fetch relationships eagerly instead of lazy-loading on access.

❌ WRONG (N+1 query pattern)
let users = try context.fetch(userRequest)

for user in users {
    let posts = user.posts  // ❌ Triggers fetch for EACH user!
    // 1 fetch for users + N fetches for relationships = N+1 total
}
✅ CORRECT (Prefetch relationships)
var request = NSFetchRequest<User>(entityName: "User")

// Tell Core Data to fetch relationships eagerly
request.relationshipKeyPathsForPrefetching = ["posts", "comments"]
// Now relationships are fetched in a single query per relationship

let users = try context.fetch(request)

for user in users {
    let posts = user.posts  // ✅ INSTANT: Already fetched
    // Total: 1 fetch for users + 1 fetch for all posts = 2 queries
}
Other optimization patterns
// Batch size: fetch in chunks for large result sets
request.fetchBatchSize = 100

// Faulting behavior: convert faults to lightweight snapshots
request.returnsObjectsAsFaults = false  // Keep objects in memory
// Use carefully—can cause memory pressure with large results

// Distinct: remove duplicates from relationship fetches
request.returnsDistinctResults = true

Time cost 2-5 minutes to add prefetching


Pattern 3b: Fetch Batch Sizing

PRINCIPLE For large result sets, fetch in batches to manage memory.

Example: Scrolling through 100,000 users
var request = NSFetchRequest<User>(entityName: "User")
request.fetchBatchSize = 100  // Fetch 100 at a time

// Set sort descriptor for stable pagination
request.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]

let results = try context.fetch(request)
// Memory footprint: ~100 users at a time, not all 100,000

for user in results {
    // Accessing user 0-99: in memory
    // Accessing user 100: batch refetch (user 100-199)
    // Auto-pagination, minimal memory usage
}

Time cost 3 minutes to tune batch size


Pattern 4a: Core Data Features SwiftData Doesn't Have

Scenario You chose SwiftData, but need features it lacks.

SwiftData lacks
  • Complex migrations (auto-migration only)
  • Custom validation (before save)
  • Relationship delete rules (cascade, deny, nullify)
  • Direct SQL queries
  • Advanced prefetching
  • Faulting control
When to drop to Core Data from SwiftData
  • Need custom migrations
  • Need validation logic
  • Need complex relationship rules
  • Need raw SQL for performance
  • Need fault tolerance patterns
✅ CORRECT (Hybrid approach when necessary)
// Keep SwiftData for simple entities
@Model final class Note {
    var id: String
    var title: String
}

// Drop to Core Data for complex operations
let backgroundContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
backgroundContext.parent = container.viewContext

// Fetch with Core Data, convert to SwiftData models
let results = try backgroundContext.perform {
    try backgroundContext.fetch(coreDataRequest)
}

CRITICAL Do NOT access the same entity from both SwiftData and Core Data simultaneously. One or the other, not both.

Time cost 30-60 minutes to create bridging layer


Pattern 4b: Stay in SwiftData (Recommended for New Projects)

Scenario You're in SwiftData and wondering if you need Core Data.

SwiftData provides 80% of Core Data functionality for modern apps
  • Type-safe models (@Model)
  • Reactive queries (@Query)
  • CloudKit sync (built-in)
  • Automatic migrations (for simple changes)
  • Proper async/await integration
When SwiftData is sufficient
  • Simple schemas (users, notes, todos)
  • Minimal relationship complexity
  • CloudKit sync needed
  • iOS 17+ requirement acceptable
  • No legacy Core Data code to maintain
Decision: Stay in SwiftData if you can answer YES to 3+ of these
  • ✅ iOS 17+ only (no iOS 16 support needed)
  • ✅ Simple relationships (1-to-many, not many-to-many)
  • ✅ Standard migrations (add fields, remove fields)
  • ✅ CloudKit sync beneficial
  • ✅ Type safety important
Decision: Drop to Core Data if
  • ❌ Need iOS 16 support (SwiftData iOS 17+ only)
  • ❌ Complex relationship rules (cascade rules, constraints)
  • ❌ Custom migrations required
  • ❌ Raw SQL needed for performance
  • ❌ Already have Core Data codebase

Time cost 0 minutes (decision only)


Pattern 5a: Safe Production Testing Before Migration

PRINCIPLE Never deploy a migration without testing against real data.

MANDATORY Pre-Deployment Checklist
// Step 1: Export production database
// From running app in simulator or real device:
// ~/Library/Developer/CoreData/[AppName]/
// Copy entire [AppName].sqlite database

// Step 2: Create migration test
@Test func testProductionDataMigration() throws {
    // Copy production database to test location
    let testDB = tempDirectory.appendingPathComponent("test.sqlite")
    try FileManager.default.copyItem(from: prodDatabase, to: testDB)

    // Attempt migration
    var config = ModelConfiguration(url: testDB, isStoredInMemory: false)
    let container = try ModelContainer(for: User.self, configurations: [config])

    // Verify data integrity
    let context = container.mainContext
    let allUsers = try context.fetch(FetchDescriptor<User>())

    // Spot checks: verify specific records migrated correctly
    guard let user1 = allUsers.first(where: { $0.id == "test-id-1" }) else {
        throw MigrationError.missingUser
    }

    // Check derived data is correct
    XCTAssertEqual(user1.name, "Expected Name")
    XCTAssertNotNil(user1.createdAt)

    // Check relationships
    XCTAssertEqual(user1.posts.count, expectedPostCount)
}

// Step 3: Run test against real production data
// Pass ✓ before shipping
Safety rules
  • ❌ NEVER test migrations with simulator (simulator deletes DB)
  • ✅ ALWAYS test with copy of real production data
  • ✅ ALWAYS verify spot checks (specific records)
  • ✅ ALWAYS check relationships loaded correctly
  • ✅ ALWAYS have rollback plan documented

Time cost 15-30 minutes to create migration test


Pattern 5c: Pre-Deployment Verification Checklist

MANDATORY before shipping ANY Core Data change
  • Did you create a new.xcdatamodel version? (Not just editing the existing one)
  • Does the new version have a mapping model if needed?
  • Did you test migration with real production data? (Not simulator)
  • Did you verify 5+ specific records migrated correctly?
  • Did you check relationships loaded?
  • Did you test on real device (oldest supported)?
  • Does app launch without crashing? (Fresh install)
  • Does app launch with old data? (Migration path)
  • Is rollback plan documented? (In case production fails)
If you answer NO to any item
  • ❌ DO NOT SHIP
  • Go back, fix the issue, re-test
  • One "NO" = data loss risk

Time cost 5 minutes checklist


Quick Reference Table

IssueCheckFix
"Unresolvable fault" crashDo store/model versions match?Create.xcdatamodel version + mapping model
"Different thread" crashIs fetch happening on main thread?Use private queue context for background work
App became slowAre relationships being prefetched?Add relationshipKeyPathsForPrefetching
N+1 query performanceCheck -com.apple.CoreData.SQLDebug 1 logsAdd prefetching or convert to lightweight representation
SwiftData needs Core Data featuresDo you need custom migrations?Use Core Data NSEntityMigrationPolicy
Not sure about SwiftData vs. Core DataDo you need iOS 16 support?Use Core Data for iOS 16, SwiftData for iOS 17+
Migration test works, production failsDid you test with real data?Create migration test with production database copy

When You're Stuck After 30 Minutes

If you've spent >30 minutes and the Core Data issue persists:

STOP. You either
  1. Skipped mandatory diagnostics (most common)
  2. Misidentified the actual problem
  3. Applied wrong pattern for your symptom
  4. Haven't tested on real device/real data
  5. Have edge case requiring custom NSEntityMigrationPolicy
MANDATORY checklist before claiming "skill didn't work"
  • I ran all Mandatory First Steps diagnostics
  • I identified the problem type (schema, concurrency, performance, bridging, testing)
  • I checked Core Data SQL debug logs (-com.apple.CoreData.SQLDebug 1)
  • I tested on real device with real data (not simulator)
  • I applied the FIRST matching pattern from Decision Tree
  • I created a migration test if schema changed
  • I verified at least 3 specific records migrated correctly
  • I have a rollback plan documented
If ALL boxes are checked and still broken
  • You need custom NSEntityMigrationPolicy (not covered by basic patterns)
  • Time cost: 60-90 minutes for complex migration
  • Ask: "What data transformation is actually needed?" and implement custom policy
Time cost transparency
  • Pattern 1 (lightweight migration): 5-10 minutes
  • Pattern 1 (heavy migration with custom policy): 60-90 minutes
  • Pattern 2 (concurrency): 5-10 minutes
  • Pattern 3 (prefetching): 2-5 minutes
  • Pattern 4 (bridging): 30-60 minutes
  • Pattern 5 (testing): 15-30 minutes

Common Mistakes

❌ Testing migration in simulator only

  • Simulator deletes database on rebuild, hiding schema mismatches
  • Fix: ALWAYS test on real device or with production database copy

❌ Assuming default values protect against data loss

  • Default values only work for new records, not existing data
  • Fix: Use NSEntityMigrationPolicy for existing data

❌ Accessing Core Data objects across threads without conversion

  • Objects are thread-confined, can't cross thread boundaries
  • Fix: Convert to lightweight representations before passing to other threads

❌ Not realizing relationship access = database query

  • user.posts triggers a fetch for EACH user (N+1)
  • Fix: Use relationshipKeyPathsForPrefetching or extract IDs first

❌ Mixing SwiftData and Core Data on same store

  • Both layers can't access the same database simultaneously
  • Fix: Choose one layer, or use hybrid approach with separate entities

❌ Deploying migrations without pre-deployment testing

  • Edge cases in production data cause crashes
  • Fix: MANDATORY migration test with real production data

❌ Rationalizing: "I'll just delete the data"

  • ❌ FORBIDDEN: Users won't appreciate losing their data
  • Users uninstall and leave bad reviews
  • Fix: Invest in safe migration testing

Production Crisis Pressure: Defending Safe Migration Patterns

The Problem

Under production crisis pressure, you'll face requests to:

  • "Users are crashing - just delete the database and start fresh"
  • "Migration is taking too long - skip the testing and ship it"
  • "We can't wait 2 days for proper migration - hack it together"
  • "Schema mismatch? Just force-create a new store"

These sound like pragmatic crisis responses. But they cause data loss and permanent user trust damage. Your job: defend using data safety principles and customer impact, not fear of pressure.

Red Flags — PM/Manager Requests That Cause Data Loss

If you hear ANY of these during a production crisis, STOP and reference this skill:

  • ❌ "Delete the persistent store and start fresh" – Users lose ALL their data permanently
  • ❌ "Force lightweight migration without testing" – High risk of data corruption in production
  • ❌ "Skip migration and create new store" – Abandons existing user data
  • ❌ "We'll fix data issues after launch" – Impossible to recover lost/corrupted data
  • ❌ "Just ship it, we can handle support tickets" – Data loss creates permanent user churn
  • ❌ "Test on simulator is enough" – Simulator deletes database on rebuild, hides schema mismatches

How to Push Back Professionally

Step 1: Quantify the Customer Impact
"I want to resolve this crash ASAP, but let me show you what deleting the store means:

Current situation:
- 10,000 active users with data
- Average 50 items per user (500,000 total records)
- Users have 1 week to 2 years of accumulated data

If we delete the store:
- 10,000 users lose ALL their data on next app launch
- Uninstall rate: 60-80% (industry standard after data loss)
- App Store reviews: Expect 1-star reviews citing data loss
- Recovery: Impossible - data is gone permanently

Safe alternative:
- Test migration on real device with production data copy (2-4 hours)
- Deploy migration that preserves user data
- Uninstall rate: <5% (standard update churn)"
Step 2: Demonstrate the Risk

Show the PM/manager what happens:

  1. Copy production database from device backup
  2. Run proposed "quick fix" (delete store)
  3. Show: All user data gone permanently
  4. Show alternative: Safe migration preserving data
  5. Time comparison: 30 min hack vs. 2-4 hour safe migration
Reference
  • "Users don't forgive data loss" (App Store review patterns)
  • Migration testing on real device prevents 95% of production crashes
  • Schema mismatch crashes affect 100% of existing users
Step 3: Offer Compromise
"I can get us through this crisis while protecting user data:

#### Fast track (4 hours total)
1. Copy production database from TestFlight user (30 min)
2. Write and test migration on real device copy (2 hours)
3. Submit build with tested migration (30 min)
4. Monitor first 100 updates for crashes (1 hour)

#### Fallback if migration fails
- Have "delete store" build ready as Plan B
- Only deploy if migration shows 100% failure rate
- Communicate data loss to users proactively

This approach:
- Tries safe path first (protects user data)
- Has emergency fallback (if migration impossible)
- Honest timeline (4 hours vs. "just delete it" 30 min)"
Step 4: Document the Decision

If overruled (PM insists on deleting store):

Slack message to PM + team:

"Production crisis: Schema mismatch causing crashes for existing users.

PM decision: Delete persistent store to resolve immediately.

Impact assessment:
- 10,000 users lose ALL data permanently on next app launch
- Expected uninstall rate: 60-80% based on data loss patterns
- App Store review damage: High risk of 1-star reviews
- Customer support: Expect high volume of data loss complaints
- Recovery: Impossible - deleted data cannot be recovered

Alternative proposed (4-hour safe migration) was declined due to urgency.

I'm flagging this decision proactively so we can:
1. Prepare support team for data loss complaints
2. Draft App Store response to expected negative reviews
3. Consider user communication about data loss before launch"
Why this works
  • You're not questioning their judgment under pressure
  • You're quantifying user impact (business consequences)
  • You're offering a solution with honest timeline
  • You're providing fallback option (not blocking progress)
  • You're documenting the decision (protects you post-launch)

Real-World Example: Production Crash (500K Active Users)

Scenario
  • Production app crashing for 100% of users after update
  • Error: "The model used to open the store is incompatible with the one used to create the store"
  • CTO says: "Delete the database and ship hotfix in 2 hours"
  • 500,000 active users with average 6 months of data each
What to do
// ❌ WRONG - Deletes all user data (CTO's request)
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
let storeURL = /* persistent store URL */
try? FileManager.default.removeItem(at: storeURL) // 500K users lose data
try! coordinator.addPersistentStore(ofType: NSSQLiteStoreType,
                                    configurationName: nil,
                                    at: storeURL,
                                    options: nil)

// ✅ CORRECT - Safe lightweight migration (4-hour timeline)
let options = [
    NSMigratePersistentStoresAutomaticallyOption: true,
    NSInferMappingModelAutomaticallyOption: true
]

do {
    try coordinator.addPersistentStore(ofType: NSSQLiteStoreType,
                                       configurationName: nil,
                                       at: storeURL,
                                       options: options)
    // Migration succeeded - user data preserved
} catch {
    // Migration failed — NOW consider deleting with user communication
    print("Migration error: \(error)")
}
In the meeting, show
  1. Schema version mismatch causing crash
  2. Lightweight migration can fix automatically
  3. Testing on production database copy (2 hours)
  4. Time comparison: 2 hours (safe) vs. immediate (data loss)

Time estimate 4 hours total (2 hours migration testing, 2 hours build/deploy)

Result
  • Honest timeline manages expectations
  • Safe migration preserves 500K users' data
  • Uninstall rate: 3% (standard update churn)
  • App Store reviews: No data loss complaints
Alternative if migration truly impossible
  • Document why migration failed
  • Communicate data loss to users proactively
  • Provide export feature in next version

When to Accept Data Loss (Even If You Disagree)

Sometimes data loss is the only option. Accept if:

  • Migration is genuinely impossible (tried on production data copy)
  • PM/CTO understand 60-80% expected uninstall rate
  • Team commits to user communication about data loss
  • You've documented technical reasons migration failed
Document in Slack
"Production crisis: Migration failed on production data copy after 4-hour testing.

Technical details:
- Attempted lightweight migration: Failed with [error]
- Attempted heavy migration with mapping model: Failed with [error]
- Root cause: [specific schema incompatibility]

Data loss decision:
- No safe migration path exists
- PM approved delete persistent store approach
- Expected impact: 60-80% uninstall rate (500K → 100-200K users)

Mitigation plan:
- Add data export feature before next schema change
- Communicate data loss to users via in-app message
- Prepare support team for complaints
- Monitor uninstall rates post-launch"

This protects you and shows you exhausted safe options first.


Real-World Impact

Before Core Data debugging 3-8 hours per issue

  • Crashes in production (schema mismatch)
  • Performance gradually degrades (N+1 queries)
  • Thread errors in background operations
  • Data corruption from unsafe migrations
  • Customer trust damaged

After 30 minutes to 2 hours with systematic diagnosis

  • Identify problem type with diagnostics (5 min)
  • Apply correct pattern (5-10 min)
  • Test on real device (varies)
  • Deploy with confidence

Key insight Core Data has well-established patterns for every common issue. The problem is developers don't know which pattern applies to their symptom.


Last Updated: 2025-11-30 Status: TDD-tested with pressure scenarios Framework: Core Data (Foundation framework) Complements: SwiftData skill (understanding relationship to Core Data)

平台分布

Claude Code

30.73%
按下载量换算414

OpenCode

21.47%
按下载量换算289

Codex

19.27%
按下载量换算259

Antigravity

13.1%
按下载量换算176

Cursor

7.01%
按下载量换算94

Gemini CLI

3.61%
按下载量换算49

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills