Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
- main

env:
DEVELOPER_DIR: /Applications/Xcode_26.4.app/Contents/Developer
DEVELOPER_DIR: /Applications/Xcode_27.0.app/Contents/Developer
FASTLANE_SKIP_UPDATE_CHECK: true
FASTLANE_XCODE_LIST_TIMEOUT: 80
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: 80
Expand Down Expand Up @@ -146,7 +146,7 @@ jobs:
```
test:
runs-on: macos-26
runs-on: xcode-27
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import AppIntents
import CoreSpotlight
import Foundation
import Shared

/// Lets the system ask for a Spotlight refresh instead of waiting for the app's own pass, which only
/// runs when the database changes or the app comes to the foreground.
@available(iOS 27.0, *)
extension HAAppEntityAppIntentEntityQuery: IndexedEntityQuery {
func reindexEntities(
for identifiers: [String],
indexDescription: CSSearchableIndexDescription
) async throws {
try await SpotlightEntityIndexer.shared.reindex(entityIds: identifiers)
}

func reindexAllEntities(indexDescription: CSSearchableIndexDescription) async throws {
await SpotlightEntityIndexer.shared.reindexEverything()
}
}
19 changes: 19 additions & 0 deletions Sources/App/Utilities/Spotlight/SpotlightEntityIndexer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@ final class SpotlightEntityIndexer: ServerObserver {
needsReindexOnForeground = true
}

/// Reindexes the named entities on request from the system, which asks when it notices the index
/// may be stale rather than waiting for the next database change.
@available(iOS 27.0, *)
func reindex(entityIds: [String]) async throws {
let wanted = Set(entityIds)
guard let snapshot = await Task.detached(priority: .utility) { Self.makeSnapshot() }.value else {
return
}
let entities = snapshot.entities.filter { wanted.contains($0.id) }
guard !entities.isEmpty else { return }
try await index.indexAppEntities(entities)
}

/// Rebuilds the whole index on request from the system.
@available(iOS 27.0, *)
func reindexEverything() async {
await reindex(reason: "system asked for a reindex")
}

private func reindexAfterForegroundIfNeeded() {
guard needsReindexOnForeground else { return }
needsReindexOnForeground = false
Expand Down
Loading