Class

# SpotlightQuery

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## Description

Used to perform Spotlight searches on macOS. It does nothing on other operating systems.

## Properties

<div class="rst-class">

table-centered_columns_3_and_4

</div>

| Name                                      | Type                               | Read-Only | Shared |
|-------------------------------------------|------------------------------------|-----------|--------|
| `Query<spotlightquery.query>`             | `String</api/data_types/string>`   |           |        |
| `Synchronous<spotlightquery.synchronous>` | `Boolean</api/data_types/boolean>` |           |        |

## Methods

<div class="rst-class">

table-centered_column_4

</div>

| Name                                       | Parameters                                       | Returns                                   | Shared |
|--------------------------------------------|--------------------------------------------------|-------------------------------------------|--------|
| `Completed<spotlightquery.completed>`      |                                                  | `Boolean</api/data_types/boolean>`        |        |
| `Constructor<spotlightquery.constructor0>` | defaultQuery As `String</api/data_types/string>` |                                           |        |
| `Count<spotlightquery.count>`              |                                                  | `Integer</api/data_types/integer>`        |        |
| `Handle<spotlightquery.handle>`            |                                                  | `Integer</api/data_types/integer>`        |        |
| `Item<spotlightquery.item>`                | index As `Integer</api/data_types/integer>`      | `SpotlightItem</api/macos/spotlightitem>` |        |
| `Pause<spotlightquery.pause>`              |                                                  |                                           |        |
| `Resume<spotlightquery.resume>`            |                                                  |                                           |        |
| `Run<spotlightquery.run>`                  |                                                  |                                           |        |
| `Stop<spotlightquery.stop>`                |                                                  |                                           |        |

## Events

<div class="rst-class">

table-centered_column_4

</div>

| Name                                        | Parameters                                                                                                                                                                          | Returns |
|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| `Changed<spotlightquery.changed>`           | ItemsAdded() As `SpotlightItem</api/macos/spotlightitem>`, ItemsChanged() As `SpotlightItem</api/macos/spotlightitem>`, ItemsRemoved() As `SpotlightItem</api/macos/spotlightitem>` |         |
| `Completed<spotlightquery.completed_event>` |                                                                                                                                                                                     |         |

## Property descriptions

<div id="spotlightquery.query">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Query

**Query** As `String</api/data_types/string>`

> The query string that will be passed to the Spotlight engine.
>
> You search on the metadata attribute keys provided by Apple using their format. See the notes for the format of the query.
>
> The following asynchronous query uses the search string that the user enters into a `TextField</api/user_interface/desktop/desktoptextfield>` and displays the filename and its absolute path in a `Listbox</api/user_interface/desktop/desktoplistbox>`. It uses a <span class="title-ref">SpotlightQuery</span> control named "Query" that has been added to the window.
>
> First, add the following method "UpdateList" to the window:
>
> ``` xojo
> Sub UpdateList()
>   ListBox1.RemoveAllRows
>   Query.Pause
>
>   For i As Integer = 0 To Query.Count - 1
>     ListBox1.AddRow(Query.Item(i).File.DisplayName)
>     ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = Query.Item(i).File.NativePath
>   Next
>
>   Query.Resume
> End Sub
> ```
>
> In the <span class="title-ref">SpotlightQuery</span>'s `Changed<spotlightquery.changed>` and `Completed<spotlightquery.completed_event>` event handlers, call the UpdateList method.
>
> In a `DesktopButton</api/user_interface/desktop/desktopbutton>`, enter the following code in its `Pressed<desktopbutton.pressed>` event handler.
>
> ``` xojo
> If Not TextField1.Text.IsEmpty Then
>   Query.Query = "kMDItemDisplayName == ""*" + TextField1.Text + "*"""
>   Query.Run
> Else
>   MessageBox("Please enter a file name to search for.")
> End If
>
> Exception e As SpotlightException
>   MessageBox("A Spotlight error occurred.")
> ```

<div id="spotlightquery.synchronous">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Synchronous

**Synchronous** As `Boolean</api/data_types/boolean>`

> If `True</api/language/true>`, the Run method will be synchronous. If it is synchronous, then the events will not fire.
>
> This example enables the Synchronous property.
>
> ``` xojo
> Var query As New SpotlightQuery("kMDItemContentTypeTree == 'public.audio'")
> query.Synchronous = True
> query.Run
>
> For i As Integer = 0 To query.Count - 1
>   ListBox1.AddRow(query.Item(i).File.DisplayName)
>   ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = query.Item(i).File.NativePath
> Next
>
> Exception e As SpotlightException
>   MessageBox("A Spotlight error occurred.")
> ```

## Method descriptions

<div id="spotlightquery.completed">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Completed

**Completed** As `Boolean</api/data_types/boolean>`

> This property is read-only.

<div id="spotlightquery.constructor0">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Constructor

**Constructor**(defaultQuery As `String</api/data_types/string>`)

> <div class="note">
>
> <div class="title">
>
> Note
>
> </div>
>
> `Constructors</api/language/constructor>` are special methods called when you create an object with the `New</api/language/new>` keyword and pass in the parameters above.
>
> </div>
>
> Creates a <span class="title-ref">SpotlightQuery</span> object, optionally with the passed *defaultQuery*. If not passed, it defaults to no query.
>
> The following synchronous query populates a `DesktopListBox</api/user_interface/desktop/desktoplistbox>` with the list of audio files on the user's computer and the absolute path to each file. You can put the code in a `DesktopButton</api/user_interface/desktop/desktopbutton>`.
>
> ``` xojo
> Var query As New SpotlightQuery("kMDItemContentTypeTree == 'public.audio'")
> query.Synchronous = True
> query.Run
>
> For i As Integer = 0 To query.Count - 1
>   ListBox1.AddRow(query.Item(i).File.DisplayName)
>   ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = query.Item(i).File.NativePath
> Next
>
> Exception e As SpotlightException
>   MessageBox("A Spotlight error occurred.")
> ```

<div id="spotlightquery.count">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Count

**Count** As `Integer</api/data_types/integer>`

> Gets the number of results of the query.
>
> The following synchronous query populates a `DesktopListBox</api/user_interface/desktop/desktoplistbox>` with the list of audio files on the user's computer and the absolute path to each file. You can put the code in a `DesktopButton</api/user_interface/desktop/desktopbutton>`.
>
> ``` xojo
> Var query As New SpotlightQuery("kMDItemContentTypeTree == 'public.audio'")
> query.Synchronous = True
> query.Run
>
> For i As Integer = 0 To query.Count - 1
>   ListBox1.AddRow(query.Item(i).File.DisplayName)
>   ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = query.Item(i).File.NativePath
> Next
>
> Exception e As SpotlightException
>   MessageBox("A Spotlight error occurred.")
> ```

<div id="spotlightquery.handle">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Handle

**Handle** As `Integer</api/data_types/integer>`

> Returns the handle to the MDQueryRef.
>
> This property is read-only.
>
> This can be used in `Declares</api/language/declare>` to access Spotlight features that are not supported directly by this class. It may not be available until after calling the Run method.

<div id="spotlightquery.item">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Item

**Item**(index As `Integer</api/data_types/integer>`) As `SpotlightItem</api/macos/spotlightitem>`

> Returns the `SpotlightItem</api/macos/spotlightitem>` specified by *index*. *index* is zero-based.
>
> The following synchronous query populates a `DesktopListBox</api/user_interface/desktop/desktoplistbox>` with the list of audio files on the user's computer and the absolute path to each file. You can put the code in a `DesktopButton</api/user_interface/desktop/desktopbutton>`.
>
> ``` xojo
> Var query As New SpotlightQuery("kMDItemContentTypeTree == 'public.audio'")
> query.Synchronous = True
> query.Run
>
> For i As Integer = 0 To query.Count - 1
>   ListBox1.AddRow(query.Item(i).File.DisplayName)
>   ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = query.Item(i).File.NativePath
> Next
>
> Exception e As SpotlightException
>   MessageBox("A Spotlight error occurred.")
> ```

<div id="spotlightquery.pause">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Pause

**Pause**

> Temporarily pauses the query from posting any updates.
>
> This means that the Count and Item functions will not change until you resume the query by calling Resume.

<div id="spotlightquery.resume">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Resume

**Resume**

> Resumes reporting more results after the query has been paused.

<div id="spotlightquery.run">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Run

**Run**

> Runs the query specified by the Query property.
>
> The following synchronous query populates a `DesktopListBox</api/user_interface/desktop/desktoplistbox>` with the list of audio files on the user's computer and the absolute path to each file. You can put the code in a `DesktopButton</api/user_interface/desktop/desktopbutton>`.
>
> ``` xojo
> Var query As New SpotlightQuery("kMDItemContentTypeTree == 'public.audio'")
> query.Synchronous = True
> query.Run
>
> For i As Integer = 0 To query.Count - 1
>   ListBox1.AddRow(query.Item(i).File.DisplayName)
>   ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = query.Item(i).File.NativePath
> Next
>
> Exception e As SpotlightException
>   MessageBox("A Spotlight error occurred.")
> ```

<div id="spotlightquery.stop">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Stop

**Stop**

> Stops the query.

## Event descriptions

<div id="spotlightquery.changed">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Changed

**Changed**(ItemsAdded() As `SpotlightItem</api/macos/spotlightitem>`, ItemsChanged() As `SpotlightItem</api/macos/spotlightitem>`, ItemsRemoved() As `SpotlightItem</api/macos/spotlightitem>`)

> This event is fired when the <span class="title-ref">SpotlightQuery</span> has either found more items, determined that some no longer match, or both.
>
> When doing the initial gathering, *ItemsAdded()* is not populated for speed reasons since it can be called frequently.

<div id="spotlightquery.completed_event">

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

</div>

<div class="rst-class">

forsearch

</div>

SpotlightQuery.Completed

**Completed**

> Fired when the <span class="title-ref">SpotlightQuery</span> has finished gathering the initial items.
>
> Call the Stop method inside this event if you would not like to know when new documents match the query. If you don't call Stop, the Changed event will fire if items no longer match or new items match the query.

## Notes

Apple provides an overview of [Spotlight](https://developer.apple.com/library/content/documentation/Carbon/Conceptual/MetadataIntro/Concepts/WhatIsSpotlight.html).

Spotlight works by extracting metadata attributes from files on the user's hard disk. By default, this extraction is done in the background by Spotlight *Importers*. When an end-user does a Spotlight search, he is actually doing a search on the attributes that have been extracted via the importers. When you use the <span class="title-ref">SpotlightQuery</span> class, you must specify the attribute or attributes you are searching on using Spotlight keywords and syntax.

In other words, you will need to become familiar with Apple's MDQuery language. Each simple query is in the format of *attribute=Value*, where *attribute* is a Spotlight metadata attribute and *Value* is the target value.

Apple's provides a [list of searchable metadata attributes](https://developer.apple.com/library/content/documentation/CoreServices/Reference/MetadataAttributesRef/MetadataAttrRef.html#//apple_ref/doc/uid/TP40001689).

For example, kMDItemContentType == "*audio*" would find all files that had a content type containing "audio" (case insensitive). The "\*" is the wildcard character. You can combine expressions with "&&" (logical "And") and "\|\|" (logical "Or"). For example, to find a file that was Audio and had a artist of Lifehouse, it would look like this: kMDItemContentTree == 'public.audio' && kMDItemArtist == "Lifehouse".

Apple provides a complete description of the [MDQuery syntax](https://developer.apple.com/library/content/documentation/Carbon/Conceptual/SpotlightQuery/Concepts/Introduction.html).

See also `Uniform Type Identifiers</topics/file_management/understanding_uniform_type_identifiers>` to see how to search files by type.

## Sample code

The following synchronous query populates a `ListBox</api/user_interface/desktop/desktoplistbox>` with the list of audio files on the user's computer and the absolute path to each file. You can put the code in a `Button</api/user_interface/desktop/desktopbutton>`.

``` xojo
Var query As New SpotlightQuery("kMDItemContentTypeTree == 'public.audio'")
query.Synchronous = True
query.Run

For i As Integer = 0 To query.Count - 1
  ListBox1.AddRow(query.Item(i).File.DisplayName)
  ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = query.Item(i).File.NativePath
Next

Exception e As SpotlightException
  MessageBox("A Spotlight error occurred.")
```

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

The following asynchronous query uses the search string that the user enters into a `TextField</api/user_interface/desktop/desktoptextfield>` and displays the filename and its absolute path in a `Listbox</api/user_interface/desktop/desktoplistbox>`. It uses a <span class="title-ref">SpotlightQuery</span> control named "Query" that has been added to the window.

First, add the following method "UpdateList" to the window:

``` xojo
Sub UpdateList()
  ListBox1.RemoveAllRows
  Query.Pause

  For i As Integer = 0 To Query.Count - 1
    ListBox1.AddRow(Query.Item(i).File.DisplayName)
    ListBox1.CellTextAt(ListBox1.LastAddedRowIndex, 1) = Query.Item(i).File.NativePath
  Next

  Query.Resume
End Sub
```

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

In the <span class="title-ref">SpotlightQuery</span>'s `Changed<spotlightquery.changed>` and `Completed<spotlightquery.completed>` event handlers, call the UpdateList method.

In a `DesktopButton</api/user_interface/desktop/desktopbutton>`, enter the following code in its `Pressed<desktopbutton.pressed>` event handler.

``` xojo
If Not TextField1.Text.IsEmpty Then
  Query.Query = "kMDItemDisplayName == ""*" + TextField1.Text + "*"""
  Query.Run
Else
  MessageBox("Please enter a file name to search for.")
End If

Exception e As SpotlightException
  MessageBox("A Spotlight error occurred.")
```

## Compatibility

|                       |                       |
|-----------------------|-----------------------|
| **Project Types**     | Console, Desktop, Web |
| **Operating Systems** | macOS                 |

<div class="seealso">

`Object</api/data_types/additional_types/object>` parent class; `SpotlightException</api/exceptions/spotlightexception>`, `SpotlightItem</api/macos/spotlightitem>` classes.

</div>
