NSMetadataQuery不会返回任何数据

时间:2016-08-01 11:47:41

标签: swift xcode macos cocoa 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)")

    }

    }

}

正如您所看到的,我打印了metaQuery的结果数量,它回答为0。

我尝试更改一些内容,例如NSMetadataQueryIndexedLocalComputerScope而不是NSMetadataQueryUbiquitousDataScope或谓词的格式,但这两种方式都无法正常工作。

知道为什么吗?

1 个答案:

答案 0 :(得分: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