axiom-core-spotlight-ref

1
1
Source

Use when indexing app content for Spotlight search, using NSUserActivity for prediction/handoff, or choosing between CSSearchableItem and IndexedEntity - covers Core Spotlight framework and NSUserActivity integration for iOS 9+

Install

mkdir -p .claude/skills/axiom-core-spotlight-ref && curl -L -o skill.zip "https://mcp.directory/api/skills/download/6776" && unzip -o skill.zip -d .claude/skills/axiom-core-spotlight-ref && rm skill.zip

Installs to .claude/skills/axiom-core-spotlight-ref

About this skill

Core Spotlight & NSUserActivity Reference

Overview

Comprehensive guide to Core Spotlight framework and NSUserActivity for making app content discoverable in Spotlight search, enabling Siri predictions, and supporting Handoff. Core Spotlight directly indexes app content while NSUserActivity captures user engagement for prediction.

Key distinction Core Spotlight = indexing all app content; NSUserActivity = marking current user activity for prediction/handoff.


When to Use This Skill

Use this skill when:

  • Indexing app content (documents, notes, orders, messages) for Spotlight
  • Using NSUserActivity for Handoff or Siri predictions
  • Choosing between CSSearchableItem, IndexedEntity, and NSUserActivity
  • Implementing activity continuation from Spotlight results
  • Batch indexing for performance
  • Deleting indexed content
  • Debugging Spotlight search not finding app content
  • Integrating NSUserActivity with App Intents (appEntityIdentifier)

Do NOT use this skill for:

  • App Shortcuts implementation (use app-shortcuts-ref)
  • App Intents basics (use app-intents-ref)
  • Overall discoverability strategy (use app-discoverability)

Related Skills

  • app-intents-ref — App Intents framework including IndexedEntity
  • app-discoverability — Strategic guide for making apps discoverable
  • app-shortcuts-ref — App Shortcuts for instant availability

When to Use Each API

Use CaseApproachExample
User viewing specific screenNSUserActivityUser opened order details
Index all app contentCSSearchableItemAll 500 orders searchable
App Intents entity searchIndexedEntity"Find orders where..."
Handoff between devicesNSUserActivityContinue editing note on Mac
Background content indexingCSSearchableItem batchIndex documents on launch

Apple guidance Use NSUserActivity for user-initiated activities (screens currently visible), not as a general indexing mechanism. For comprehensive content indexing, use Core Spotlight's CSSearchableItem.


Core Spotlight (CSSearchableItem)

Creating Searchable Items

import CoreSpotlight
import UniformTypeIdentifiers

func indexOrder(_ order: Order) {
    // 1. Create attribute set with metadata
    let attributes = CSSearchableItemAttributeSet(contentType: .item)
    attributes.title = order.coffeeName
    attributes.contentDescription = "Ordered on \(order.date.formatted())"
    attributes.keywords = ["coffee", "order", order.coffeeName.lowercased()]
    attributes.thumbnailData = order.imageData

    // Optional: Add location
    attributes.latitude = order.location.coordinate.latitude
    attributes.longitude = order.location.coordinate.longitude

    // Optional: Add rating
    attributes.rating = NSNumber(value: order.rating)

    // 2. Create searchable item
    let item = CSSearchableItem(
        uniqueIdentifier: order.id.uuidString,        // Stable ID
        domainIdentifier: "orders",                   // Grouping
        attributeSet: attributes
    )

    // Optional: Set expiration
    item.expirationDate = Date().addingTimeInterval(60 * 60 * 24 * 365)  // 1 year

    // 3. Index the item
    CSSearchableIndex.default().indexSearchableItems([item]) { error in
        if let error = error {
            print("Indexing error: \(error.localizedDescription)")
        }
    }
}

Key Properties

uniqueIdentifier

Purpose Stable, persistent ID unique to this item within your app.

uniqueIdentifier: order.id.uuidString

Requirements:

  • Must be stable (same item = same identifier)
  • Used for updates and deletion
  • Scoped to your app

domainIdentifier

Purpose Groups related items for bulk operations.

domainIdentifier: "orders"

Use cases:

  • Delete all items in a domain
  • Organize by type (orders, documents, messages)
  • Batch operations

Pattern:

// Index with domains
item1.domainIdentifier = "orders"
item2.domainIdentifier = "documents"

// Delete entire domain
CSSearchableIndex.default().deleteSearchableItems(
    withDomainIdentifiers: ["orders"]
) { error in }

CSSearchableItemAttributeSet

Metadata describing the searchable content.

let attributes = CSSearchableItemAttributeSet(contentType: .item)

// Required
attributes.title = "Order #1234"
attributes.displayName = "Coffee Order"

// Highly recommended
attributes.contentDescription = "Medium latte with oat milk"
attributes.keywords = ["coffee", "latte", "order"]
attributes.thumbnailData = imageData

// Optional but valuable
attributes.contentCreationDate = Date()
attributes.contentModificationDate = Date()
attributes.rating = NSNumber(value: 5)
attributes.comment = "My favorite order"

Common Attributes

AttributePurposeExample
titlePrimary title"Coffee Order #1234"
displayNameUser-visible name"Morning Latte"
contentDescriptionDescription text"Medium latte with oat milk"
keywordsSearch terms["coffee", "latte"]
thumbnailDataPreview imageJPEG/PNG data
contentCreationDateWhen createdDate()
contentModificationDateLast modifiedDate()
ratingStar ratingNSNumber(value: 5)
latitude / longitudeLocation37.7749, -122.4194

Document-Specific Attributes

// For document types
attributes.contentType = UTType.pdf
attributes.author = "John Doe"
attributes.pageCount = 10
attributes.fileSize = 1024000
attributes.path = "/path/to/document.pdf"

Message-Specific Attributes

// For messages
attributes.recipients = ["[email protected]"]
attributes.recipientNames = ["Jane Doe"]
attributes.authorNames = ["John Doe"]
attributes.subject = "Meeting notes"

Batch Indexing for Performance

❌ DON'T: Index items one at a time

// Bad: 100 index operations
for order in orders {
    CSSearchableIndex.default().indexSearchableItems([order.asSearchableItem()]) { _ in }
}

✅ DO: Batch index operations

// Good: 1 index operation
let items = orders.map { $0.asSearchableItem() }

CSSearchableIndex.default().indexSearchableItems(items) { error in
    if let error = error {
        print("Batch indexing error: \(error)")
    } else {
        print("Indexed \(items.count) items")
    }
}

Recommended batch size 100-500 items per call. For larger sets, split into multiple batches.


Deletion Patterns

Delete by Identifier

let identifiers = ["order-1", "order-2", "order-3"]

CSSearchableIndex.default().deleteSearchableItems(
    withIdentifiers: identifiers
) { error in
    if let error = error {
        print("Deletion error: \(error)")
    }
}

Delete by Domain

// Delete all items in "orders" domain
CSSearchableIndex.default().deleteSearchableItems(
    withDomainIdentifiers: ["orders"]
) { error in }

Delete All

// Nuclear option: delete everything
CSSearchableIndex.default().deleteAllSearchableItems { error in
    if let error = error {
        print("Failed to delete all: \(error)")
    }
}

When to delete:

  • User deletes content
  • Content expires
  • User logs out
  • App reset/reinstall

App Entity Integration (App Intents)

Create from App Entity

import AppIntents

struct OrderEntity: AppEntity, IndexedEntity {
    var id: UUID

    @Property(title: "Coffee", indexingKey: \.title)
    var coffeeName: String

    @Property(title: "Date", indexingKey: \.contentCreationDate)
    var orderDate: Date

    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Order"

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(coffeeName)", subtitle: "Order from \(orderDate.formatted())")
    }
}

// Create searchable item from entity
let order = OrderEntity(id: UUID(), coffeeName: "Latte", orderDate: Date())
let item = CSSearchableItem(appEntity: order)
CSSearchableIndex.default().indexSearchableItems([item])

Associate Entity with Existing Item

let attributes = CSSearchableItemAttributeSet(contentType: .item)
attributes.title = "Order #1234"

let item = CSSearchableItem(
    uniqueIdentifier: "order-1234",
    domainIdentifier: "orders",
    attributeSet: attributes
)

// Associate with App Intent entity
item.associateAppEntity(orderEntity, priority: .default)

Benefits:

  • Automatic "Find" actions in Shortcuts
  • Spotlight search returns entities directly
  • App Intents integration

NSUserActivity

Overview

NSUserActivity captures user engagement for:

  • Handoff — Continue activity on another device
  • Spotlight search — Index currently viewed content
  • Siri predictions — Suggest returning to this screen
  • Quick Note — Link notes to app content

Platform support iOS 8.0+, iPadOS 8.0+, macOS 10.10+, tvOS 9.0+, watchOS 2.0+, axiom-visionOS 1.0+


Eligibility Properties

let activity = NSUserActivity(activityType: "com.app.viewOrder")

// Enable Spotlight search
activity.isEligibleForSearch = true

// Enable Siri predictions
activity.isEligibleForPrediction = true

// Enable Handoff to other devices
activity.isEligibleForHandoff = true

// Contribute URL to global search (public content only)
activity.isEligibleForPublicIndexing = false

Privacy note Only set isEligibleForPublicIndexing = true for publicly accessible content (e.g., blog posts with public URLs).


Basic Pattern

func viewOrder(_ order: Order) {
    // 1. Create activity
    let activity = NSUserActivity(activityType: "com.coffeeapp.viewOrder")
    activity.title = order.coffeeName

    // 2. Set eligibility
    activity.isEligibleForSearch = true
    activity.isEligibleForPrediction = true

    // 3. Provide identifier for updates/deletion
    activity.persistentIdentifier = order.i

---

*Content truncated.*

axiom-swiftui-nav-diag

CharlesWiltgen

Use when debugging navigation not responding, unexpected pops, deep links showing wrong screen, state lost on tab switch or background, crashes in navigationDestination, or any SwiftUI navigation failure - systematic diagnostics with production crisis defense

54

axiom-swiftui-26-ref

CharlesWiltgen

Use when implementing iOS 26 SwiftUI features - covers Liquid Glass design system, performance improvements, @Animatable macro, 3D spatial layout, scene bridging, WebView/WebPage, AttributedString rich text editing, drag and drop enhancements, and visionOS integration for iOS 26+

33

axiom-extensions-widgets-ref

CharlesWiltgen

Use when implementing widgets, Live Activities, Control Center controls, or app extensions - comprehensive API reference for WidgetKit, ActivityKit, App Groups, and extension lifecycle for iOS 14+

13

axiom-ios-build

CharlesWiltgen

Use when ANY iOS build fails, test crashes, Xcode misbehaves, or environment issue occurs before debugging code. Covers build failures, compilation errors, dependency conflicts, simulator problems, environment-first diagnostics.

253

axiom-camera-capture-ref

CharlesWiltgen

Reference — AVCaptureSession, AVCapturePhotoSettings, AVCapturePhotoOutput, RotationCoordinator, photoQualityPrioritization, deferred processing, AVCaptureMovieFileOutput, session presets, capture device APIs

42

coreml

CharlesWiltgen

Use when deploying custom ML models on-device, converting PyTorch models, compressing models, implementing LLM inference, or optimizing CoreML performance. Covers model conversion, compression, stateful models, KV-cache, multi-function models, MLTensor.

42

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

1,6881,430

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

1,2721,337

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

1,5471,153

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

1,359809

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

1,269732

pdf-to-markdown

aliceisjustplaying

Convert entire PDF documents to clean, structured Markdown for full context loading. Use this skill when the user wants to extract ALL text from a PDF into context (not grep/search), when discussing or analyzing PDF content in full, when the user mentions "load the whole PDF", "bring the PDF into context", "read the entire PDF", or when partial extraction/grepping would miss important context. This is the preferred method for PDF text extraction over page-by-page or grep approaches.

1,498687