Reputation: 125
I try to list all of my file on my Mac for an app that I made. I use NSMetadataQuery but it's not working.
Here is the code:
import Cocoa
class ViewController: NSViewController
{
let metadataQuery = NSMetadataQuery()
@IBOutlet weak var searchTextField: NSTextField!
@IBOutlet weak var labelML: NSTextField!
@IBAction func searchClick(sender: AnyObject)
{
labelML.stringValue = "Hello \(searchTextField.stringValue)!"
startQuery()
handleMetadataQueryFinished(metadataQuery)
}
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func startQuery()
{
print("Starting the query now...")
metadataQuery.searchScopes = [NSMetadataQueryUbiquitousDataScope]
let predicate = NSPredicate(format: "%K ==[cd] '*'", NSMetadataItemFSNameKey)
metadataQuery.predicate = predicate
if metadataQuery.startQuery(){
print("Successfully started the query.")
} else {
print("Failed to start the query.")
}
}
func handleMetadataQueryFinished(sender: NSMetadataQuery)
{
print("Search finished");
metadataQuery.disableUpdates()
metadataQuery.stopQuery()
print("Number of results \(metadataQuery.resultCount)")
for item in metadataQuery.results as! [NSMetadataItem]
{
let itemName = item.valueForAttribute(NSMetadataItemFSNameKey)
as! String
let itemUrl = item.valueForAttribute(NSMetadataItemURLKey)
as! NSURL
let itemSize = item.valueForAttribute(NSMetadataItemFSSizeKey)
as! Int
print("Item name = \(itemName)")
print("Item url = \(itemUrl)")
print("Item size = \(itemSize)")
}
}
}
As you can see, I print the number of results of the metaQuery and it answers 0.
I've try to change some things like NSMetadataQueryIndexedLocalComputerScope instead of NSMetadataQueryUbiquitousDataScope or the format of the predicate but either way it's not working.
Any idea why?
Upvotes: 1
Views: 1111
Reputation: 3310
You should register an observer for NSMetadataQueryDidFinishGatheringNotification
and wait till its called. The search takes a little while. And did starting the query return true
?
Here is some Objective-C style example from my code:
#import "CloudUtils.h"
@interface CloudUtils ()
@property(nonatomic, strong) NSMetadataQuery *query;
@end
@implementation CloudUtils
static CloudUtils *singleton;
+ (CloudUtils *) sharedInstance
{
if (singleton == nil) {
singleton = [[CloudUtils alloc] init];
}
return singleton;
}
+ (void) updateCloudDrive
{
NSLog(@"in updateCloudDrive");
CloudUtils *utils = [CloudUtils sharedInstance];
// Wichtig: Das Query muss STRONG gebunden sein... sonst ist das zu früh wieder weg!
utils.query = [[NSMetadataQuery alloc] init];
utils.query.searchScopes = [NSArray arrayWithObjects:NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope,nil];
utils.query.predicate = [NSPredicate predicateWithFormat:@"%K like[cd] %@", NSMetadataItemFSNameKey, @"*"];
[[NSNotificationCenter defaultCenter] addObserver:utils
selector:@selector(queryDidFinishGathering:)
name:NSMetadataQueryDidFinishGatheringNotification
object:utils.query];
[[NSNotificationCenter defaultCenter] addObserver:utils
selector:@selector(queryDidUpdate:)
name:NSMetadataQueryDidUpdateNotification
object:utils.query];
dispatch_async(dispatch_get_main_queue(), ^{
// Das scheitert, falls schon ein solches Query läuft... was aber nicht schlimm ist.
[utils.query startQuery];
});
}
// Diese Methode kommt ins Spiel, wenn es zu viele Ergebnisse auf einmal sind...
// Dann werden einige davon schon gemeldet, bevor das Query ganz fertig ist...
- (void) queryDidUpdate: (NSNotification *) notification
{
NSLog(@"in queryDidUpdate:");
NSMetadataQuery *query = [notification object];
[query disableUpdates];
NSError *error = nil;
for (NSMetadataItem *item in [query results]) {
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
NSLog(@"starting download of %@", url);
[[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:url error:&error];
}
[query enableUpdates];
}
- (void) queryDidFinishGathering: (NSNotification *) notification
{
NSLog(@"in queryDidFinishGathering:");
NSMetadataQuery *query = [notification object];
[query disableUpdates];
[query stopQuery];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:query];
NSError *error = nil;
for (NSMetadataItem *item in [query results]) {
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
NSLog(@"starting download of %@", url);
[[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:url error:&error];
}
}
@end
Upvotes: 3