View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Todos los videos
  • Información

Más videos

  • Información
  • Código
  • Showcase app data in Spotlight

    Discover how Core Data can surface data from your app in Spotlight with as little as two lines of code. Learn how to make that data discoverable in Spotlight search and to customize how it is presented to people on device. Lastly, we'll show you how to implement full-text search within your app, driven completely with the data indexed by Spotlight.

    Recursos

    • Showcase App Data in Spotlight
      • Video HD
      • Video SD

    Videos relacionados

    WWDC21

    • Bring Core Data concurrency to Swift and SwiftUI
  • Buscar este video…
    • 2:40 - Creating a NSCoreDataCoreSpotlightDelegate

      let spotlightDelegate = NSCoreDataCoreSpotlightDelegate(forStoreWith: description,
                                                              coordinator: coordinator)
      spotlightDelegate.startSpotlightIndexing()
    • 5:24 - Adding a NSCoreDataCoreSpotlightDelegate to a CoreDataStack

      import Foundation
      import CoreData
      
      class CoreDataStack {
          private (set) var spotlightIndexer: TagsSpotlightDelegate?
          
          lazy var persistentContainer: NSPersistentContainer = {
              let container = NSPersistentContainer(name: "Tags")
      
              guard let description = container.persistentStoreDescriptions.first else {
                  fatalError("###\(#function): Failed to retrieve a persistent store description.")
              }
      
              description.type = NSSQLiteStoreType
              description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
              description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
                      
              container.loadPersistentStores(completionHandler: { (_, error) in
                  guard let error = error as NSError? else { return }
                  fatalError("###\(#function): Failed to load persistent stores:\(error)")
              })
              
              spotlightIndexer = TagsSpotlightDelegate(forStoreWith: description,
                                                       coordinator: container.persistentStoreCoordinator)
      
              container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
              
              container.viewContext.automaticallyMergesChangesFromParent = true
              do {
                  try container.viewContext.setQueryGenerationFrom(.current)
              } catch {
                  fatalError("###\(#function): Failed to pin viewContext to the current generation:\(error)")
              }
              
              return container
          }()
      }
    • 6:24 - Creating TagsSpotlightDelegate

      class TagsSpotlightDelegate: NSCoreDataCoreSpotlightDelegate {
          override func domainIdentifier() -> String {
              return "com.example.apple-samplecode.tags"
          }
      
          override func indexName() -> String? {
              return "tags-index"
          }
        
          override func attributeSet(for object: NSManagedObject) -> CSSearchableItemAttributeSet? {
              if let photo = object as? Photo {
                  let attributeSet = CSSearchableItemAttributeSet(contentType: .image)
                  attributeSet.identifier = photo.uniqueName
                  attributeSet.displayName = photo.userSpecifiedName
                  attributeSet.thumbnailData = photo.thumbnail?.data
                  for case let tag as Tag in photo.tags ?? [] {
                      if let name = tag.name {
                          if attributeSet.keywords != nil {
                              attributeSet.keywords?.append(name)
                          } else {
                              attributeSet.keywords = [name]
                          }
                      }
                  }
                  return attributeSet
              } else if let object as? Tag {
                  let attributeSet = CSSearchableItemAttributeSet(contentType: .text)
                  attributeSet.displayName = tag.name
                  return attributeSet
              }
              return nil
          }
      }
    • 9:51 - Customizing PhotosViewController with Spotlight delegate functionality

      class PhotosViewController: UICollectionViewController {
          @IBOutlet var generateDefaultPhotosItem: UIBarButtonItem!
          @IBOutlet var deleteSpotlightIndexItem: UIBarButtonItem!
          @IBOutlet var startStopIndexingItem: UIBarButtonItem!
          
          private var isTagging = false
          private var spotlightFoundItems = [CSSearchableItem]()
          private static let defaultSectionNumber = 0
          private var searchQuery: CSSearchQuery?
          var spotlightUpdateObserver: NSObjectProtocol?
      
          private lazy var spotlightIndexer: TagsSpotlightDelegate = {
              let appDelegate = UIApplication.shared.delegate as? AppDelegate
              return appDelegate!.coreDataStack.spotlightIndexer!
          }()
        
          override func viewDidLoad() {
              super.viewDidLoad()
              
              // ...
      
              toggleSpotlightIndexing(enabled: true)
          }
        
          @IBAction func deleteSpotlightIndex(_ sender: Any) {
              toggleSpotlightIndexing(enabled: false)
      
              spotlightIndexer.deleteSpotlightIndex(completionHandler: { (error) in
                  if let err = error {
                      print("Encountered error while deleting Spotlight index data, \(err.localizedDescription)")
                  } else {
                      print("Finished deleting Spotlight index data.")
                  }
              })
          }
      
          @IBAction func toggleSpotlightIndexingEnabled(_ sender: Any) {
              if spotlightIndexer.isIndexingEnabled == true {
                  toggleSpotlightIndexing(enabled: false)
              } else {
                  toggleSpotlightIndexing(enabled: true)
              }
          }
      
          private func toggleSpotlightIndexing(enabled: Bool) {
              if enabled {
                  spotlightIndexer.startSpotlightIndexing()
                  startStopIndexingItem.image = UIImage(systemName: "pause")
              } else {
                  spotlightIndexer.stopSpotlightIndexing()
                  startStopIndexingItem.image = UIImage(systemName: "play")
              }
      
              let center = NotificationCenter.default
              if spotlightIndexer.isIndexingEnabled && spotlightUpdateObserver == nil {
                  let queue = OperationQueue.main
                  spotlightUpdateObserver = center.addObserver(forName: NSCoreDataCoreSpotlightDelegate.indexDidUpdateNotification,
                                                               object: nil,
                                                               queue: queue) { (notification) in
                      let userInfo = notification.userInfo
                      let storeID = userInfo?[NSStoreUUIDKey] as? String
                      let token = userInfo?[NSPersistentHistoryTokenKey] as? NSPersistentHistoryToken
                      if let storeID = storeID, let token = token {
                          print("Store with identifier \(storeID) has completed ",
                                "indexing and has processed history token up through \(String(describing: token)).")
                      }
                  }
              } else {
                  if spotlightUpdateObserver == nil {
                      return
                  }
                  center.removeObserver(spotlightUpdateObserver as Any)
              }
          }
      }
    • 13:13 - Adding full-text search to PhotosViewController

      extension PhotosViewController: UISearchResultsUpdating {
          func updateSearchResults(for searchController: UISearchController) {
              guard let userInput = searchController.searchBar.text, !userInput.isEmpty else {
                  dataProvider.performFetch(predicate: nil)
                  reloadCollectionView()
                  return
              }
              
              let escapedString = userInput.replacingOccurrences(of: "\\", with: "\\\\").replacingOccurrences(of: "\"", with: "\\\"")
              let queryString = "(keywords == \"" + escapedString + "*\"cwdt)"
              
              searchQuery = CSSearchQuery(queryString: queryString, attributes: ["displayName", "keywords"])
      
              // Set a handler for results. This will be a called 0 or more times.
              searchQuery?.foundItemsHandler = { items in
                  DispatchQueue.main.async {
                      self.spotlightFoundItems += items
                  }
              }
              
              // Set a completion handler. This will be called once.
              searchQuery?.completionHandler = { error in
                  guard error == nil else {
                      print("CSSearchQuery completed with error: \(error!).")
                      return
                  }
      
                  DispatchQueue.main.async {
                      self.dataProvider.performFetch(searchableItems: self.spotlightFoundItems)
                      self.reloadCollectionView()
                      self.spotlightFoundItems.removeAll()
                  }
              }
      
              // Start the query.
              searchQuery?.start()
          }
      }

Developer Footer

  • Videos
  • WWDC21
  • Showcase app data in Spotlight
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines