axiom-core-spotlight-ref

0
0
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 = ["jane@example.com"]
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-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.

91

axiom-getting-started

CharlesWiltgen

Use when first installing Axiom, unsure which skill to use, want an overview of available skills, or need help finding the right skill for your situation — interactive onboarding that recommends skills based on your project and current focus

00

axiom-ui-testing

CharlesWiltgen

Use when writing UI tests, recording interactions, tests have race conditions, timing dependencies, inconsistent pass/fail behavior, or XCTest UI tests are flaky - covers Recording UI Automation (WWDC 2025), condition-based waiting, network conditioning, multi-factor testing, crash debugging, and accessibility-first testing patterns

00

axiom-vision-diag

CharlesWiltgen

subject not detected, hand pose missing landmarks, low confidence observations, Vision performance, coordinate conversion, VisionKit errors, observation nil, text not recognized, barcode not detected, DataScannerViewController not working, document scan issues

00

axiom-now-playing-carplay

CharlesWiltgen

CarPlay Now Playing integration patterns. Use when implementing CarPlay audio controls, CPNowPlayingTemplate customization, or debugging CarPlay-specific issues.

00

axiom-ios-concurrency

CharlesWiltgen

Use when writing ANY code with async, actors, threads, or seeing ANY concurrency error. Covers Swift 6 concurrency, @MainActor, Sendable, data races, async/await patterns, performance optimization.

00

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.

641968

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.

590705

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.

339397

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."

318395

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.

450339

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

304231

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.