Post

Replies

Boosts

Views

Activity

Reply to Does Core Spotlight work with document-based apps?
Thank you again for the thoughtful response. This is the high level solution I've ended up with. To recap: This is a SwiftUI document-based app: DocumentGroup backed by SwiftData. A user will typically have only a few of these files. A file will typically have only a few thousand indexed records. Search is required for in-app use only; system-wide search is not. The application maintains a single search index. When the app launches it deletes all items from the search index. This keeps the search index clean in the case of renamed, deleted or seldom used files. A document uses the domainIdentifier search attribute set to its URL to tag all of its searchable items. When a document is opened it deletes all of its searchable items using the domainIdentifier to scope the operation. It then adds all of its searchableItems to the index. The document adds, deletes & updates its searchable items while it is open. When a document's URL changes it updates the domainIdentifier of its searchable items. In-app search queries are always scoped to the domainIdentifier of the file.
Topic: App & System Services SubTopic: General Tags:
2w
Reply to Does Core Spotlight work with document-based apps?
filterQueries is actually being passed over and processed on the daemon side Excellent. The correct answer is to create a CSImportExtension. That extension point hands you the file you're indexing, side stepping the entire issue. Looking at the documentation for CSImportExtension it appears that this is for gathering & updating information about a file, not the items in the file. The extension only gets one CSSearchableItemAttributeSet that is for metadata about the file. An object that provides searchable attributes for file types that the app supports. Even if I wanted to misuse the API just to trigger a full reindex of the file contents, due to sandbox restrictions I don't think it would be possible to open an arbitrary file. The user would have to select the file in an Open dialog. My current solution is: When a document is opened start a Task that gathers all of the uniqueIdentifiers of the searchableItems for this file from the search index (using the contentURL to filter the results). Gather the model identifiers from SwiftData. Compare the 2 sets of identifiers. If the sets are not identical then index/delete the appropriate searchableItems (or reindex the whole file). This isn't the most efficient solution, but the files I'm dealing with likely contain no more than several thousand items. This leaves me with the outstanding question relating to the CSSearchIndexDelegate.reindex* methods. Should the acknowledgementHandler be called when an error is encountered? The documentation says: The delegate … must call the acknowledgement handler after all client state information has been saved, so that the indexer can call this method again in case of a crash. It doesn't describe what to do if the client state couldn't be saved. In my current solution I always call the acknowledgementHandler.
Topic: App & System Services SubTopic: General Tags:
3w
Reply to Does Core Spotlight work with document-based apps?
I think you'll find that including contentURL as part of the initial query makes things significantly faster. Unfortunately CSUserQuery does not allow these types of query strings. CSUserQueryContext.filterQueries appears to be the only way to scope to contentURL. The issue is that Spotlight APIs appear to be App based & not Document based. Imagine that a user has created 2 documents, #1 & #2, but only #1 is currently open. The CSSearchableIndexDelegate.reindex* methods may be called by the system with identifiers from both files, but the app only has access to the DB for the open file. What is the correct way to handle this case? Only update the items for which #1 contains the identifiers? This will leave the indexed items for #2 in an invalid state. Should the acknowledgementHandler be called? Should the acknowledgementHandler be called if an error is encountered by a reindex* method? Swift 6.2, Swift 6 language mode: the reindex* methods call indexSearchableItems which in their callbacks need to invoke the acknowledgementHandler. However the callback is @Sendable but the acknowledgementHandler is not. searchableIndex.indexSearchableItems(items) { error in if let error { … } acknowledgementHandler() } Capture of 'acknowledgementHandler' with non-sendable type '() -> Void' in a '@Sendable' closure
Topic: App & System Services SubTopic: General Tags:
3w