Generates data export/import infrastructure for JSON, CSV, PDF formats with GDPR data portability, share sheet integration, and file import. Use when user wants data export functionality, CSV/JSON/PDF export, GDPR compliance data portability, import from files, or share sheet for data.
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill data-export
Generate production data export and import infrastructure -- JSON export via Codable, CSV generation with proper escaping, PDF report rendering with UIGraphicsPDFRenderer, GDPR-compliant full data export, file import with UTType-based picker, and share sheet integration. No third-party dependencies.
Use this skill when the user:
Search for existing export code:
Glob: **/*Export*.swift, **/*Import*.swift, **/*CSV*.swift, **/*PDF*.swift
Grep: "UIGraphicsPDFRenderer" or "CSVExport" or "UIActivityViewController" or "ShareLink" or "fileExporter"
If existing export code found:
Search for data models that need exporting:
Grep: "@Model" or "NSManagedObject" or "struct.*Codable" or "class.*Codable"
Identify the models to build export conformances for.
Ask user via AskUserQuestion:
Read templates.md for production Swift code.
Generate these files:
DataExportManager.swift -- Central export coordinator with format routingDataExportable.swift -- Protocol for models that support exportBased on configuration:
CSVExporter.swift -- If CSV format selectedPDFExporter.swift -- If PDF format selectedIf import capability selected:
DataImporter.swift -- File picker and format parserCheck project structure:
Sources/ exists -> Sources/DataExport/App/ exists -> App/DataExport/DataExport/After generation, provide:
DataExport/
├── DataExportable.swift # Protocol for exportable models
├── DataExportManager.swift # Central export coordinator
├── CSVExporter.swift # CSV generation (optional)
├── PDFExporter.swift # PDF rendering (optional)
└── DataImporter.swift # File import (optional)
Make a model exportable:
struct Expense: Codable, DataExportable {
let id: UUID
let title: String
let amount: Double
let date: Date
let category: String
// DataExportable conformance
static var csvHeaders: [String] {
["ID", "Title", "Amount", "Date", "Category"]
}
var csvRow: [String] {
[id.uuidString, title, String(format: "%.2f", amount),
ISO8601DateFormatter().string(from: date), category]
}
var pdfDescription: String {
"\(title) - $\(String(format: "%.2f", amount)) (\(category))"
}
}
Export from a view:
struct ExpenseListView: View {
let expenses: [Expense]
@State private var exportURL: URL?
@State private var showShareSheet = false
var body: some View {
List(expenses) { expense in
ExpenseRow(expense: expense)
}
.toolbar {
Menu {
Button("Export as JSON") {
Task { await exportAs(.json) }
}
Button("Export as CSV") {
Task { await exportAs(.csv) }
}
Button("Export as PDF") {
Task { await exportAs(.pdf) }
}
} label: {
Label("Export", systemImage: "square.and.arrow.up")
}
}
.sheet(isPresented: $showShareSheet) {
if let exportURL {
ShareSheet(activityItems: [exportURL])
}
}
}
private func exportAs(_ format: DataExportManager.ExportFormat) async {
do {
exportURL = try await DataExportManager.shared.export(
expenses, format: format, filename: "expenses"
)
showShareSheet = true
} catch {
// Handle error
}
}
}
SwiftUI ShareLink (iOS 16+):
if let url = exportURL {
ShareLink(item: url) {
Label("Share Export", systemImage: "square.and.arrow.up")
}
}
Import from file picker:
struct ImportView: View {
@State private var showFilePicker = false
@State private var importedItems: [Expense] = []
var body: some View {
Button("Import Data") { showFilePicker = true }
.fileImporter(
isPresented: $showFilePicker,
allowedContentTypes: DataImporter.supportedTypes
) { result in
Task {
let url = try result.get()
importedItems = try await DataImporter.importFile(
from: url, as: Expense.self
)
}
}
}
}
For full GDPR compliance, export ALL user data:
func exportAllUserData() async throws -> URL {
let allData = GDPRExportData(
profile: try await fetchUserProfile(),
expenses: try await fetchAllExpenses(),
settings: try await fetchUserSettings(),
exportDate: Date(),
appVersion: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0"
)
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
encoder.dateEncodingStrategy = .iso8601
let data = try encoder.encode(allData)
let url = FileManager.default.temporaryDirectory
.appendingPathComponent("user-data-export.json")
try data.write(to: url)
return url
}
@Test
func jsonExportRoundTrip() async throws {
let expenses = [
Expense(id: UUID(), title: "Coffee", amount: 4.50,
date: Date(), category: "Food")
]
let url = try await DataExportManager.shared.export(
expenses, format: .json, filename: "test"
)
let data = try Data(contentsOf: url)
let decoded = try JSONDecoder().decode([Expense].self, from: data)
#expect(decoded.count == 1)
#expect(decoded.first?.title == "Coffee")
}
@Test
func csvExportFormatsCorrectly() {
let expenses = [
Expense(id: UUID(), title: "Coffee, Large", amount: 4.50,
date: Date(), category: "Food")
]
let csv = CSVExporter.generate(
from: expenses,
headers: Expense.csvHeaders,
rowMapper: { $0.csvRow }
)
#expect(csv.contains("\"Coffee, Large\"")) // Commas escaped with quotes
#expect(csv.hasPrefix("ID,Title,Amount,Date,Category"))
}
@Test
func importParsesCSV() async throws {
let csvContent = "ID,Title,Amount\n1,Coffee,4.50\n2,Lunch,12.00"
let url = FileManager.default.temporaryDirectory.appendingPathComponent("test.csv")
try csvContent.write(to: url, atomically: true, encoding: .utf8)
let rows = try CSVExporter.parse(from: url)
#expect(rows.count == 2)
#expect(rows.first?["Title"] == "Coffee")
}
Always export to a temporary directory, then present via share sheet:
let url = FileManager.default.temporaryDirectory
.appendingPathComponent("export.\(format.fileExtension)")
try data.write(to: url)
// Present via UIActivityViewController or ShareLink
For GDPR Article 20 compliance, export must include:
Wrap fields containing commas, quotes, or newlines in double quotes; escape internal quotes by doubling them.
Delete large export files after sharing completes rather than relying on the system's periodic cleanup.
UIGraphicsPDFRenderer must be used on the main thread if it references UIKit views. For data-only PDF generation (text, lines, rectangles), it is safe to render on a background thread.
For exporting thousands of records, stream the output instead of building the entire string/data in memory. Write CSV line-by-line to a file handle. For JSON, use JSONSerialization with streams.
Use ShareLink for the simple case; use UIActivityViewController when you need excluded activities, completion handlers, or custom activities.
.fileImporter URLs are security-scoped: call url.startAccessingSecurityScopedResource() before reading, url.stopAccessingSecurityScopedResource() after.
generators/settings-screen -- Settings screen with export buttongenerators/account-deletion -- Account deletion includes data export optionGenerate architecture documentation using C4 model Mermaid diagrams. Use when asked to create architecture diagrams, document system architecture, visualize software structure, create C4 diagrams, or generate context/container/component/deployment diagrams. Triggers include "architecture diagram", "C4 diagram", "system context", "container diagram", "component diagram", "deployment diagram", "document architecture", "visualize architecture".
Expert C4 Container-level documentation specialist. Synthesizes Component-level documentation into Container-level architecture, mapping components to deployment units, documenting container interfaces as APIs, and creating container diagrams. Use when synthesizing components into deployment containers and documenting system deployment architecture.
When the user wants to create or update a README.md file for a project. Also use when the user says 'write readme,' 'create readme,' 'document this project,' 'project documentation,' or asks for help with README.md. This skill creates absurdly thorough documentation covering local setup, architecture, and deployment.
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
Plans and executes safe Convex schema and data migrations using the widen-migrate-narrow workflow and the @convex-dev/migrations component. Use this skill when a deployment fails schema validation, existing documents need backfilling, fields need adding or removing or changing type, tables need splitting or merging, or a zero-downtime migration strategy is needed. Also use when the user mentions breaking schema changes, multi-deploy rollouts, or data transformations on existing Convex tables.
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
Azure AI Document Intelligence SDK for .NET. Extract text, tables, and structured data from documents using prebuilt and custom models.
Build image analysis applications with Azure AI Vision SDK for Java. Use when implementing image captioning, OCR text extraction, object detection, tagging, or smart cropping.
Take rshankras/data-export from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.