NSMetadataQuery не возвращает никаких данных

Я пытаюсь перечислить все свои файлы на своем Mac для приложения, которое я сделал. Я использую NSMetadataQuery, но он не работает.

Вот код:

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)")

    }

    }

}

Как видите, я печатаю количество результатов метазапроса, и он отвечает 0.

Я пытался изменить некоторые вещи, такие как NSMetadataQueryIndexedLocalComputerScope вместо NSMetadataQueryUbiquitousDataScope или формат предиката, но в любом случае это не работает.

Есть идеи, почему?


person N..    schedule 01.08.2016    source источник


Ответы (1)


Вы должны зарегистрировать наблюдателя для NSMetadataQueryDidFinishGatheringNotification и дождаться его вызова. Поиск занимает немного времени. И вернул ли запуск запроса true?

Вот пример стиля Objective-C из моего кода:

#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
person Daniel Bleisteiner    schedule 11.08.2016