File Metadata Search Programming Guide Contents About File Metadata Queries 4 Who Should Read This Document 4 Organization of This Document 5 See Also 5 Searching iCloud and the Desktop 6 OS X Search Capabilities 6 iOS Search Capabilities 6 Searching File Metadata with NSMetadataQuery 7 Creating a Static File Metadata Search 7 Defining a Search 8 Setting the Query Search 8 Setting the Sort Order 8 Limiting the Search Scope 9 Running the Search 10 Accessing the Returned Results 10 The Completed Static Search 11 Creating a Live Search 13 File Metadata Query Expression Syntax 14 Comparison Syntax 14 Time and Date Variables 16 Displaying the Finder’s Spotlight Search Window 18 Document Revision History 19 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 2 Tables and Listings Searching File Metadata with NSMetadataQuery 7 Table 2-1 Listing 2-1 Supported Search Scopes 9 Static Spotlight search implementation 11 File Metadata Query Expression Syntax 14 Table 3-1 Table 3-2 Table 3-3 Table 3-4 Table 3-5 Comparison operators 14 Value Comparison modifiers 15 Value Comparison modifier examples 15 Using wildcards 16 $time variable expressions 17 Displaying the Finder’s Spotlight Search Window 18 Listing 4-1 Displaying the Finder Search Window 18 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 3 About File Metadata Queries File metadata provides several application programming interfaces that allow it application to search for files based on data that is part of the file or file system. The level of interaction your application requires with the search results will often dictate the API that you chose. The simplest way to provide metadata support in your Mac app is to use the Spotlight search window. Using this API an application can display the standard Spotlight search window, optionally providing a search string. The search results are presented directly to the user and are not available to the application. This is a good choice if your application isn't search oriented, but you want to allow users to search for contextual terms using Spotlight. For applications that need to create queries and interact with the results there are two APIs available. The Metadata framework provides a low-level query API, MDQuery, that allows an application to search for files based on metadata values. MDQuery is completely configurable, allowing you to run synchronous and asynchronous queries and provides fine-grain control of the frequency of results batching. The Cocoa frameworks's NSMetadataQuery class provides a high-level Objective-C interface to the MDQuery API. This class allows you to construct queries using a subset of the NSPredicate classes, and execute the queries asynchronously. The NSMetadataQuery class allows an application to specify the grouping of the results into multiple subcategories. NSMetadataQuery does not support synchronous queries and provides minimal update notifications as data is collected. On OS X NSMetadataQuery supports Cocoa bindings, allowing you to display the results without writing any significant amount of glue code. Note: iOS provides only the Objective-C metadata search interface. The procedural C version is only available on OS X. Who Should Read This Document Spotlight is a fundamental feature of OS X, and all developers should be familiar with its capabilities. Many applications, at a minimum, should offer users the ability to search for selected text using the Spotlight search window. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 4 About File Metadata Queries Organization of This Document Organization of This Document The following articles cover key concepts in understanding how Spotlight can be used to query metadata: ● “Searching File Metadata with NSMetadataQuery ” (page 7) provides a conceptual overview of searching for files using file metadata. ● “Displaying the Finder’s Spotlight Search Window” (page 18) describes how to present the standard Spotlight search window. ● “File Metadata Query Expression Syntax” (page 14) describes the metadata query language. See Also There are other technologies, not fully covered in this document, that are fundamental to integrating metadata into your applications. Refer to these documents for more details: ● Spotlight Overview covers the conceptual details surrounding Spotlight’s metadata usage. ● Spotlight Importer Programming Guide describes the plug-ins that extract metadata from document files. ● File Metadata Attributes Reference describe the metadata attributes provided by Apple. The following sample code is available that shows how to generate Spotlight queries. ● Spotlighter examples shows how to use Spotlight searches. ● PredicateEditorSample shows how to use the rule editor and Spotlight. ● PhotoSearch allows the search of images based on name. It allows multiple searches to run simultaneously. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 5 Searching iCloud and the Desktop The Spotlight search capabilities are available on both iOS v5.0 and OS X. Using these search queries iOS can search iCloud content and OS X can search both iCloud, desktop, and networked files. OS X Search Capabilities Spotlight is ubiquitous on OS X. The Finder uses it to search for allow the user to search for files. Mail uses Spotlight to find messages during the search process, and any application can use Spotlight to search the User’s home directory, the local file system, any attached networked file systems, and iCloud. The OS X Objective-C interface to the Spotlight API includes classes to search (NSMetadataQuery), inspect the file metadata (NSMetadataItem), and the ability to have the NSMetadataQuery return a more complicated set of data using the NSMetadataQueryAttributeValueTuple class. In addition a Core Foundation API exists that correspond to each of the Objective-C classes (in fact the classes are built upon the Core Foundation base. Note: Relying on file metadata is extremely useful. It allows you to retrieve information about a variety of file attributes, for example, video frame size, sound file compression, the Finder comment, the author of the file, and much more without needing to know how to read format of the file. Note that users’ are able to disable Spotlight on a per-volume or folder basis. iOS Search Capabilities iOS allows metadata searches within iCloud to find files corresponding files. It provides only the Objective-C interface to file metadata query, NSMetadataQuery and NSMetadataItem, as well as only supporting the search scope that searches iCloud. Unlike the desktop, the iOS application’s sandbox is not searchable using the metadata classes. In order to search your application’s sandbox, you will need to traverse the files within the sandbox file system recursively using the NSFileManager class. Once matching file or files is found, you can access that file in the manner that you require. You are also able to use the NSMedatataItem class to retrieve metadata for that particular file. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 6 Searching File Metadata with NSMetadataQuery In order for your application to search Spotlight metadata, you must create a query using the NSMetadataQuery class provided by the Foundation framework. Queries can be run in two modes: asynchronous, and asynchronous with live updates. The first simply performs the search on the files that exist at the time of the initial search. The latter continues to search. updating the data as the files that fulfill or no longer fulfill the search parameters update. There are four main steps for executing an asynchronous metadata query: ● Defining and initializing the search. ● Initiating the search. ● Listen for batch notifications. ● Listening for the completion notification. ● Stopping the query. ● Processing results. A live asynchronous Spotlight query allows your application to monitor the specified scope for changes that happen ‘on the fly’. The only significant difference in the code is that rather than stopping the query, you simply suspend the query while processing the results, and then resume the search when processing is completed. Creating a Static File Metadata Search A static Spotlight search is a search that simply runs, returns the results and quits. it is intended as a one-time search that does not monitor changes (which is possible using live searches, discussed in “Creating a Live Search.” 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 7 Searching File Metadata with NSMetadataQuery Creating a Static File Metadata Search Defining a Search The first step in creating a query is defining a search expression that returns the desired results. If you are using MDMetadataQuery to execute the query, create your search expression predicate using the syntax described in “File Metadata Query Expression Syntax” (page 14). You must register a notification to inform you as data batches are returned and when the initial search is complete. You can also optionally register the scope, sorting, and a delegate. To define a search 1. Create an NSMetadataQuery instance. 2. Register to receive the NSMetadataQueryDidUpdateNotification notification which is sent when batches of search content is returned. This notification may not be generated depending on the batch value. 3. Register to receive the NSMetadataQueryDidFinishGatheringNotification notification which is sent when the initial search is completed. Setting the Query Search The search predicate is created using the syntax specified in “File Metadata Query Expression Syntax” (page 14). The fields that can be searched are defined in the File Metadata Attributes Reference . The attributes references lists the available metadata keys and the type of data that you must supply to search that attribute (a string, number, an array of strings, a date, or a Uniform Type Identifier. To create the query ● Create an NSPredicate instance with the appropriate Spotlight query expression. Setting the Sort Order If you are using NSMetadataQuery, you can specify the sort order of the results by providing an array of sort descriptors. The sorting is based on the metadata attribute key of each returned NSMetadataItem object. To set the search order ● Create an NSSortDescriptor with the desired metadata key for sorting, in this case kMDItemDisplayName. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 8 Searching File Metadata with NSMetadataQuery Creating a Static File Metadata Search Limiting the Search Scope 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. The search scopes specify where the metadata query searches for the files. Table 2-1 lists the available scopes. Table 2-1 Supported Search Scopes Scope Constant Supported Description Operating Systems NSMetadataQueryUbiquitousDocumentsScope iOS and OS X Search all files in the Documents directories of the application’s iCloud container directories. NSMetadataQueryUbiquitousDataScope iOS and OS X Search all files not in the Documents directories of the application’s iCloud container directories. NSMetadataQueryNetworkScope OS X Search all user-mounted remote volumes. NSMetadataQueryLocalComputerScope OS X Search all local mounted volumes, including the user home directory. The user’s home directory is searched even if it is a remote volume. NSMetadataQueryUserHomeScope OS X Search the user’s home directory. The search scopes are specified as an array of the scope constants. To specify the search scope ● Send your instance of NSMetadataSearch a setSearchScopes: message, passing an array of the appropriate scopes. This query will search the User’s directory on the computer as well as the iCloud Documents folder. This same search code could be run on iOS by simply removing the unsupported NSMetadataQueryUserHomeScope scope constant. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 9 Searching File Metadata with NSMetadataQuery Creating a Static File Metadata Search Note: It is important to remember that on OS X, 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. Users can also explicitly exclude results from being returned for specific directories and document types by using Spotlight preferences. On iOS only the document types can be removed from the search results using the Spotlight Search option in the Settings application under General -> Spotlight Search. Running the Search 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 using the NSMetadataQueryDidUpdateNotification. In a single query this can be useful for indicating the state of the search progress, while in live searches it becomes more important. The query sends the application a NSMetadataQueryDidFinishGatheringNotification notification when the initial results gathering phase has completed. To run the search, send a startQuery message to your instance of NSMetadataSearch. Accessing the Returned Results Before your application interacts with the returned results, it must first stop the query. 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 by invoking the NSMetadataQuery instance method resultCount. The application then accesses individual result items by their indexed position. Rather than traversing the results (which is intended for use with Cocoa Bindings), it is better to request the result item at desired index using the resultAtIndex: method. The result items are returned as an object instance of type NSMetadataItem. Each object encapsulates the metadata attributes for the file. Your application then retrieves the metadata attributes from these items by passing each instance a valueForAttribute: message with the name of the desired metadata attribute. To access the results 1. Stop the query that is in progress. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 10 Searching File Metadata with NSMetadataQuery Creating a Static File Metadata Search 2. Iterate over the results, performing whatever action is appropriate for your application. 3. Remove the observers for the notifications. This step is optional if you intend to run the query multiple times. However if you intend to use the same setup code, you may wish to remove the observers regardless. The Completed Static Search “Creating a Static File Metadata Search” shows the code required to implement a static search. Listing 2-1 Static Spotlight search implementation // Initialize Search Method - (void)initiateSearch { // Create the metadata query instance. The metadataSearch @property is // declared as retain self.metadataSearch=[[[NSMetadataQuery alloc] init] autorelease]; // Register the notifications for batch and completion updates [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:metadataSearch]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initalGatherComplete:) name:NSMetadataQueryDidFinishGatheringNotification object:metadataSearch]; // Configure the search predicate to find all images using the // public.image UTI NSPredicate *searchPredicate; searchPredicate=[NSPredicate predicateWithFormat:@"kMDItemContentTypeTree == 'public.image'"]; 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 11 Searching File Metadata with NSMetadataQuery Creating a Static File Metadata Search [metadataSearch setPredicate:searchPredicate]; // Set the search scope. In this case it will search the User's home directory // and the iCloud documents area NSArray *searchScopes; searchScopes=[NSArray arrayWithObjects:NSMetadataQueryUserHomeScope, NSMetadataQueryUbiquitousDocumentsScope,nil]; [metadataSearch setSearchScopes:searchScopes]; // Configure the sorting of the results so it will order the results by the // display name NSSortDescriptor *sortKeys=[[[NSSortDescriptor alloc] initWithKey:(id)kMDItemDisplayName ascending:YES] autorelease]; [metadataSearch setSortDescriptors:[NSArray arrayWithObject:sortKeys]]; // Begin the asynchronous query [metadataSearch startQuery]; } // Method invoked when notifications of content batches have been received - (void)queryDidUpdate:sender; { NSLog(@"A data batch has been received"); } // Method invoked when the initial query gathering is completed - (void)initalGatherComplete:sender; { // Stop the query, the single pass is completed. [metadataSearch stopQuery]; 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 12 Searching File Metadata with NSMetadataQuery Creating a Live Search // Process the content. In this case the application simply // iterates over the content, printing the display name key for // each image NSUInteger i=0; for (i=0; i < [metadataSearch resultCount]; i++) { NSMetadataItem *theResult = [metadataSearch resultAtIndex:i]; NSString *displayName = [theResult valueForAttribute:(NSString *)kMDItemDisplayName]; NSLog(@"result at %lu - %@",i,displayName); } // Remove the notifications to clean up after ourselves. // Also release the metadataQuery. // When the Query is removed the query results are also lost. [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:metadataSearch]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:metadataSearch]; self.metadataSearch=nil; } @end Creating a Live Search A live search is configured in a manner virtual to an identical search with only a small number of changes. ● The query must be suspended using disableUpdates before accessing the updated data. ● Data is typically handled in the queryDidUpdate: method in some form. ● The query is then restarted using enableUpdates to continue the search. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 13 File Metadata Query Expression Syntax File metadata queries are constructed using a query language that is a subset of the predicate string format. The metadata search expression syntax allows an application to construct searches ‘on the fly’, allow advanced users to construct their own queries, or your application to store often used queries for easy use. The syntax is relatively straightforward, including comparisons, language agnostic options, and time and date variables. Comparison Syntax The file metadata query expression syntax is a simplified form of filename globbing familiar to shell users. Queries have the following format: attribute == value where attribute is a standard metadata attribute (see “File Metadata Attributes Reference ”) or a custom metadata attribute defined by an importer. For example, to query Spotlight for all the files authored by “Steve” the query would look like the following: kMDItemAuthors ==[c] "Steve" The available comparison operators are listed in Table 3-1. Table 3-1 Comparison operators Operator Description == equal != not equal < less than (available for numeric values and dates only) > greater than (available for numeric values and dates only) <= less than or equal (available for numeric values and dates only) 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 14 File Metadata Query Expression Syntax Comparison Syntax Operator Description >= greater than or equal (available for numeric values and dates only) InRange(attributeName,minValue,maxValue) numeric values within the range of minValue through maxValue in the specified attributeName Characters such as " and ‘ in the value string should be escaped using the \ character. The search value in the example has the modifier “c”. These are modifiers specify how the comparison is made. Table 3-2 describes the available comparison modifiers. Search modifiers should immediately follow the comparison operator and be surrounded by square brackets […]. Table 3-2 Value Comparison modifiers Modifier Description c The comparison is case insensitive. d The comparison is insensitive to diacritical marks. Table 3-3 shows several examples that use the comparison modifiers. Table 3-3 Value Comparison modifier examples Query string Results kMDItemTextContent == "Paris" Matches “Paris” but not “paris”. kMDItemTextContent ==[c] "Paris" Matches “Paris” and “paris”. kMDItemTextContent ==[c] "*Paris*" Matches “Paris”, “paris”, “I love Paris”, and “paris-france.jpg””. kMDItemTextContent == "Frédéric" Matches “Frédéric” but not “Frederic”. kMDItemTextContent ==[d] "Frédéric" Matches “Frédéric” and “Frederic” regardless of the word case. Using the wildcard characters (* and ? ) you can match substrings at the beginning of a string, end of a string, or anywhere within the string. Table 3-4 shows several common usages. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 15 File Metadata Query Expression Syntax Time and Date Variables The * character matches multiple characters whereas the ? wildcard character matches a single character. Table 3-4 Using wildcards Query string Result kMDItemTextContent == "paris*" Matches attribute values that begin with “paris”. For example, matches “paris”, but not “comparison”. kMDItemTextContent == "*paris" Matches attribute values that end with “paris”. kMDItemTextContent == "*paris*" Matches attributes that contain "paris" anywhere within the value. For example, matches “paris” and “comparison”. kMDItemTextContent == "paris" Matches attribute values that are exactly equal to “paris”. Queries can be combined using a C-like syntax for AND (&&) and OR (||). For example, to restrict a query to audio files authored by “Steve” the query would be: kMDItemAuthors ==[c] "Steve" && kMDItemContentType == "public.audio" Parenthesis can be used to further group query matching. For example, to search for audio files authored by “Steve” or “Daniel” the query would be: (kMDItemAuthors ==[c] "Daniel" || kMDItemAuthors[c] == "Steve") && kMDItemContentType == "public.audio" You can expand this search to include video files using the following query: (kMDItemAuthors ==[c] "Daniel" || kMDItemAuthors ==[c] "Steve" ) && (kMDItemContentType == "public.audio" || kMDItemContentType == "public.video") Time and Date Variables You can also create queries that use the date and time as the search value. The date and time value is formatted as a floating-point value that is compatible with CFDate, seconds relative to January 1, 2001. Additionally, the $time variable is provided that can be used to specify values relative to the current time, as shown in Table 3-5. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 16 File Metadata Query Expression Syntax Time and Date Variables Table 3-5 $time variable expressions Time variable Description $time.now The current date and time. $time.today The current date. $time.yesterday Yesterday’s date. $time.this_week(-1) Dates in the previous week. $time.this_week Dates in the current week. $time.this_month Dates in the current month. $time.this_year Dates in the current year. $time.now(NUMBER) The date and time by adding a positive or negative value, in seconds, to the current time. $time.today(NUMBER) The date by adding a positive or negative value, in days, to the current day $time.this_week(NUMBER) Dates by adding a positive or negative value, in weeks, to the current week. $time.this_month(NUMBER) Dates by adding a positive or negative value, in months, to the current month. $time.this_year(NUMBER) Dates by adding a positive or negative value, in years, to the current year. $time.iso(ISO-8601-STR) The date by parsing the specified ISO-8601-STR compliant string. Using the $time variable you can restrict a search to find only files that have been changed in the last week using the following query: ((kMDItemAuthors ==[c] "Daniel" || kMDItemAuthors[c] == "Steve") && (kMDItemContentType == "public.audio" || kMDItemContentType == "public.video")) && (kMDItemFSContentChangeDate == $time.this_week(-1)) Note: The value of the $time variable is set when the query is first executed. It does not update to the current time as the query continues to run. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 17 Displaying the Finder’s Spotlight Search Window Applications can provide users direct interaction with Spotlight by displaying the standard Finder search interface. The NSWorkspace method showSearchResultsForQueryString: provides a simple interface to the Finder search window. This is the programmatic equivalent of the user switching to Finder, creating a new window, and typing the search string into the search field. The code fragment in “Displaying the Finder’s Spotlight Search Window” demonstrates extracting a string value and displaying the search interface. Listing 4-1 Displaying the Finder Search Window resultCode=[[NSWorkspace sharedWorkspace] showSearchResultsForQueryString:[sender stringValue]]; if (resultCode == NO) { // failed to open the panel // present an error to the user } 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 18 Document Revision History This table describes the changes to File Metadata Search Programming Guide . Date Notes 2011-09-28 Added iCloud and iOS information. 2010-04-12 Corrected query wording and updated several query examples. 2009-07-14 Corrected query syntax. 2009-05-27 Replaced HISearchWindowShow() function recommendation with new NSWorkspace showSearchResultsForQueryString: method. 2006-03-08 Added $time.last_week to the query expression table. 2005-08-11 Added usage note about inRange query expression. Corrected minor typos. 2005-04-29 Added conceptual article that describes how to create Spotlight queries. Added usage note about $time to "Query Expression Format." New document that describes how to add Spotlight searching to your applications. 2011-09-28 | Copyright © 2011 Apple Inc. All Rights Reserved. 19 Apple Inc. Copyright © 2011 Apple Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Inc., with the following exceptions: Any person is hereby authorized to store documentation on a single computer for personal use only and to print copies of documentation for personal use provided that the documentation contains Apple’s copyright notice. No licenses, express or implied, are granted with respect to any of the technology described in this document. Apple retains all intellectual property rights associated with the technology described in this document. This document is intended to assist application developers to develop applications only for Apple-labeled computers. Apple Inc. 1 Infinite Loop Cupertino, CA 95014 408-996-1010 Apple, the Apple logo, Cocoa, Finder, Mac, Objective-C, OS X, and Spotlight are trademarks of Apple Inc., registered in the U.S. and other countries. iCloud is a service mark of Apple Inc., registered in the U.S. and other countries. IOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license. Even though Apple has reviewed this document, APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS DOCUMENT, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED “AS IS,” AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS DOCUMENT, even if advised of the possibility of such damages. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty. Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also have other rights which vary from state to state.
© Copyright 2024