0

In the below code, 25th line, searchPredicate, not able to set the correct query. Even if correct, not able to get back suitable metadata in the method 'initialGatherComplete:' which is invoked by the notification. The metadata fetched should be sorted according to the string in the _searchField. Please tell me where did I go wrong.

// 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;
    NSString *searchString = [NSString stringWithFormat:@"*%@*",[_searchField stringValue]];

     //Problem is here. Not able to send correct query. Even if correct, not able to get the metadata back sorted according to the search string.
    searchPredicate=[NSPredicate predicateWithFormat:@"(kMDItemContentTypeTree == 'public.image' || kMDItemContentTypeTree == 'public.audio' || kMDItemContentTypeTree == 'public.movie') && kMDItemDisplayName == %@",searchString];

    [_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:[kSMMediaSearchPath stringByExpandingTildeInPath],NSMetadataQueryNetworkScope,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];

      // 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;
}
Soorya
  • 39
  • 5

1 Answers1

0

For starters, use 'like' instead of '==' for string comparisons. More generally, please read Predicate Format String Syntax for a complete description of how to write a predicate format string.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Before I put the question here, I'd already tried with the link you've given. Couldn't succeed. That made me to ask it here. – Soorya Dec 30 '11 at 10:51
  • 1
    Even worse @Caleb, it appears that you haven't read the Predicate Programming Guide either, or you would know that "There is no special relationship between Spotlight and NSPredicate other than that NSMetadataQuery is the Cocoa interface to Spotlight, and it uses NSPredicate in its API. The Spotlight query string syntax is similar to, but different from, the NSPredicate query string syntax." https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pSpotlightComparison.html#//apple_ref/doc/uid/TP40002370-SW1 – Elise van Looij Dec 28 '13 at 19:15
  • @ElisevanLooij What are you talking about? I merely pointed out a problem with the OP's predicate and pointed to the reference material that explains correct formation. I never said anything about a special relationship. Perhaps you're reading too much into my answer? Please explain your comment. – Caleb Dec 29 '13 at 16:16
  • @Caleb I struggle with an issue similar to Soorya's and your answer is read the manual, which is not nice but can be useful. However, when you then link to the wrong part of the manual, potentially sending someone off on the wrong track for hours or days, then frankly it's better not to answer at all. NSMetadataQuery uses a different syntax from NSPredicate and, for starters, doesn't recognize the 'like' operator. – Elise van Looij Jan 02 '14 at 11:44