In order for your application to search Spotlight metadata, you must create a query using one of the available Spotlight APIs. The Core Services framework provides MDQuery
, a Core Foundation–style opaque type, while the Foundation framework provides NSMetadataQuery
, an Objective-C class. Regardless of the API you choose, the concepts are the same.
The first step in creating a query is defining a search expression that returns the desired results. If you are using MDQuery
to execute the query, create your search expression as a CFString
using the syntax described in “Query Expression Syntax.” If you are using NSMetadataQuery
, create an NSPredicate
object that defines the search expression.
Once you have defined your search expression, you configure the query itself. All of the following steps are optional.
You can specify an array of metadata attributes called the value list attributes. The query collects the values of these attributes into uniqued lists that can be used to summarize the results of the search.
How you specify the sort order of the results depends on which query API you are using. MDQuery
allows you to provide an array of metadata attribute names that are used as the primary sort key, the secondary sort key, and so on. This is a simple value comparison. If you require a more advanced sorting capability, you can specify a sort comparator function as a callback. If you are using NSMetadataQuery
, you specify the sort order of the results by providing an array of sort descriptors.
An application limits where search results are collected from by specifying a search scope. The search scope is provided to the query as an array of predefined location constants, URLs, and directory paths. The predefined location constants provide convenient values for restricting a query to the user's home directory, locally mounted volumes and the user's home directory, or remote mounted volumes.
Note: It is important to remember that, while file-system metadata is available on all volumes, other metadata attributes are not. CDs, DVDs, disk images and System directories are not indexed by Spotlight. A user can also explicitly exclude results from being returned for specified locations by using Spotlight preferences.
Once you have created and configured a query object, you can execute the query itself. When running, a query typically has two phases: an initial results gathering phase and a live-update phase.
During the initial results gathering phase, the existing Spotlight system store is searched for files that match the search expression. The query sends notifications as the results are returned in batches. The query sends the application a notification when the initial results gathering phase has completed.
If the query has been configured to provide live-updates, your application receives notifications as the results of the query change in response to files having been changed on disk.
Before your application interacts with the returned results, it must first temporarily disable updates of the results. You can disable updates during the initial gathering phase of a search or during the live-update phase.
An application determines the number of results that have been returned, and then can access individual result items by their indexed position in the results. The result items are returned as an object instance that encapsulates the attributes for the file. By default MDQuery
returns MDItem
instances, and NSMetadataQuery
returns NSMetadataItem
instances. Your application can then retrieve the values of the metadata attributes from these objects.
You can also retrieve the value of a specific metadata attribute at an index in the results if the attribute was specified as a value list attribute, is a sorting key, or is used as a grouping attribute.
When your application has finished accessing the results, it should reenable updates.
You can provide callback functions to override the results returned by a query.
You can implement a callback that allows you to examine the attribute name and value that is to be returned to the query and provide an alternate value. This is useful, for example, if your application needs to provide a localized representation of certain returned values.
You can also provide a callback that returns an entirely different class of object to encapsulate the individual result items (rather than the default MDQuery
or NSMetadataItem
instances). This allows you to replace the generic instances with classes that implement custom functionality. These custom objects are returned when your application asks the query for a result at a specific index. The objects returned by your callback are not used by the query mechanism, so there is no requirement that your custom objects implement any specific protocols.
Last updated: 2010-04-12