Claude Code Plugins

Community-maintained marketplace

Feedback

cloudkit-debugging

@nadavital/Cauldron
0
0

CloudKit sync and sharing debugging specialist. Use when encountering CloudKit sync issues, schema problems, sharing bugs, or CKRecord errors.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name cloudkit-debugging
description CloudKit sync and sharing debugging specialist. Use when encountering CloudKit sync issues, schema problems, sharing bugs, or CKRecord errors.
allowed-tools Read, Grep, Glob, Bash(git:*)

CloudKit Debugging Skill

This skill activates when you're working with CloudKit sync, sharing, schema, or CKRecord operations.

When This Skill Activates

Trigger this skill when the conversation involves:

  • CloudKit sync failures or conflicts
  • CKShare and sharing issues
  • CloudKit schema or record type problems
  • Change token management
  • Zone operations
  • Public/private database issues
  • CloudKit quota or performance issues
  • CKRecord field mapping errors

CloudKit Context for Cauldron

Container Setup

  • Container ID: iCloud.Nadav.Cauldron
  • Zones: Custom zones per feature (recipes, collections, connections)
  • Databases: Private (user data) + Public (shared recipes)

Key Files to Check

  • Cauldron/Core/Services/CloudKitService.swift - Main CloudKit operations (2,266 LOC)
  • Cauldron/Core/Services/RecipeSyncService.swift - Recipe synchronization
  • Cauldron/Core/Persistence/*Repository.swift - SwiftData ↔ CloudKit mapping
  • Cauldron/Core/Services/ImageManager.swift - CKAsset handling

Common Cauldron CloudKit Patterns

  • SwiftData models map to CD_* record types
  • Actors for thread-safe CloudKit operations
  • Manual sync triggers (no automatic background sync)
  • CKAssets for images (recipes, profiles, collections)
  • CloudKit sharing for collaborative collections

Debugging Process

1. Identify the Issue Category

Sync Issues:

  • Records not syncing
  • Conflicts and overwrites
  • Change tokens not working
  • Deleted items reappearing

Sharing Issues:

  • Share creation fails
  • Participants can't access shared data
  • Permission errors
  • Share acceptance problems

Schema Issues:

  • Record type mismatches
  • Missing fields
  • Type conversion errors
  • Index problems

Performance Issues:

  • Slow queries
  • Quota exceeded
  • Batch operation failures
  • Network timeout

2. Read Relevant Code

Always start by reading:

  1. The CloudKit service implementation
  2. The repository for the affected record type
  3. Recent git changes related to CloudKit
git log --oneline --grep="CloudKit\|sync\|share" -20

3. Check for Common Issues

Change Token Problems:

// Look for: Are change tokens being saved?
// Look for: Is fetchChanges using the right token?
// Look for: Are tokens reset when needed?

Record Type Mismatches:

// SwiftData model: Recipe
// CloudKit record type: CD_Recipe
// Check: Do field names match?
// Check: Are types compatible (String, Int, Date, Data)?

Zone Configuration:

// Check: Is the custom zone created before use?
// Check: Are operations using the correct zone?
// Check: Is the zone subscription active?

Share Record Handling:

// Check: Is CKShare created with correct rootRecord?
// Check: Are participants added properly?
// Check: Is share record saved to public database?

4. Diagnostic Questions to Answer

Ask yourself:

  • ✓ Is this happening in development, production, or both?
  • ✓ Is it affecting all users or just some?
  • ✓ What CloudKit database (private/public/shared)?
  • ✓ What record types are involved?
  • ✓ Are there any CloudKit errors in console logs?
  • ✓ When did this start happening? (git blame)

5. Common CloudKit Errors & Solutions

CKError.serverRecordChanged

  • Cause: Conflict - record modified elsewhere
  • Solution: Implement conflict resolution, use change tags

CKError.zoneNotFound

  • Cause: Custom zone not created or deleted
  • Solution: Create zone before operations, handle zone deletion

CKError.unknownItem

  • Cause: Record doesn't exist
  • Solution: Check record existence before fetch/delete

CKError.partialFailure

  • Cause: Batch operation partially failed
  • Solution: Parse itemResults, retry failed items

CKError.quotaExceeded

  • Cause: User's iCloud quota full
  • Solution: Alert user, implement cleanup strategy

CKError.networkFailure/networkUnavailable

  • Cause: No internet or CloudKit unavailable
  • Solution: Queue operations, retry with backoff

6. Investigation Checklist

For sync issues:

□ Check change token persistence
□ Verify fetchChanges logic
□ Look for race conditions (actor isolation)
□ Check deleted item tracking (tombstones)
□ Verify record save order (dependencies)
□ Check predicate safety

For sharing issues:

□ Verify CKShare creation
□ Check rootRecord reference
□ Confirm public database save
□ Verify participant permissions
□ Check share URL generation
□ Test share acceptance flow

For schema issues:

□ Compare SwiftData model to CloudKit record type
□ Verify field name mappings
□ Check data type compatibility
□ Confirm required fields exist
□ Validate index configuration

CloudKit Best Practices for Cauldron

Record Operations

// ✅ DO: Use actors for thread safety
actor CloudKitService {
    func save(_ record: CKRecord) async throws { }
}

// ✅ DO: Batch operations when possible
let operation = CKModifyRecordsOperation(recordsToSave: records)

// ✅ DO: Handle partial failures
if case .partialFailure(let error) = ckError.code {
    // Process error.userInfo[CKPartialErrorsByItemIDKey]
}

// ❌ DON'T: Make CloudKit calls on main thread
// ❌ DON'T: Ignore CKError.serverRecordChanged
// ❌ DON'T: Save without checking quota first

Change Tracking

// ✅ DO: Persist change tokens
UserDefaults.standard.set(changeToken, forKey: "zoneChangeToken")

// ✅ DO: Handle moreComing flag
if changesResponse.moreComing {
    await fetchChanges(from: changesResponse.changeToken)
}

// ❌ DON'T: Forget to update token after successful fetch
// ❌ DON'T: Use same token across different zones

Sharing

// ✅ DO: Set share permissions explicitly
share[CKShare.SystemFieldKey.title] = "Recipe Collection"
share.publicPermission = .readOnly

// ✅ DO: Save share and root record atomically
let operation = CKModifyRecordsOperation(
    recordsToSave: [rootRecord, share]
)

// ❌ DON'T: Modify shared records without permission check
// ❌ DON'T: Share records across different zones

Debugging Tools

Console Logging

Add CloudKit debug logging:

// In CloudKitService
#if DEBUG
print("☁️ CloudKit: Fetching \(recordType) from \(database)")
#endif

CloudKit Dashboard

Check at: https://icloud.developer.apple.com/dashboard

  • Verify schema matches code
  • Check record counts
  • View recent operations
  • Monitor quota usage

Xcode Console Filters

Use these console filters:

  • CloudKit - All CloudKit operations
  • CKError - CloudKit errors only
  • CD_Recipe - Specific record type operations

Output Format

When providing CloudKit debugging help:

  1. Identify the Issue - State what CloudKit problem you found
  2. Show Relevant Code - Reference specific files and lines
  3. Explain Root Cause - Why is this happening?
  4. Provide Solution - Code fix with explanation
  5. Prevent Recurrence - Best practice to avoid this in future

Example:

🔍 **Issue Found:** CloudKit sync conflict in RecipeSyncService.swift:145

**Root Cause:** The service doesn't handle CKError.serverRecordChanged,
causing sync to fail when the recipe was modified on another device.

**Solution:** Implement conflict resolution using change tags...

**Prevention:** Always handle serverRecordChanged errors with merge strategy.

Remember

CloudKit debugging is systematic:

  1. Read the error carefully
  2. Check the code path
  3. Verify CloudKit schema
  4. Test incrementally
  5. Use CloudKit Dashboard to validate

You have deep knowledge of Cauldron's CloudKit architecture - use it to solve problems quickly and thoroughly.