【问题标题】:Problems handling NSMetadataQueryDidUpdateNotification non-UIDocument based iCloud files处理基于 NSMetadataQueryDidUpdateNotification 非 UIDocument 的 iCloud 文件的问题
【发布时间】:2012-12-12 07:48:38
【问题描述】:

当我试图解决这个问题时,我已经很头疼了:在我当前的应用程序中,我使用 iCloud 来存储我的文档 - 但我不能使用基于 UIDocument 的数据存储。所以我的方法是遵循 WWDC 2012 文章 237(高级 iCloud 文档存储)并将我的文档视为鞋盒应用程序。

当我建立一个 NSMetadataQuery 来监视 iCloud 文档文件夹中的更改以注意文件更改时,就会出现真正的问题。我已经设置了我的查询,从 NSMetadataQueryDidFinishGatheringNotification 的观察者开始,当它触发时,我为查询启用更新并为 NSMetadataQueryDidUpdateNotification 设置了一个观察者。后者仅对一个文件更改有效,我没有找到如何让它重复触发以对相同或其他文件进行后续更改。以下是一些代码部分:

- (void)startMonitoringDocumentsFolder: (id)sender
{
    if (self.queryDocs != nil)
        return;

    NSLog(@"startMonitoringDocumentsFolder:");

    self.queryDocs = [[NSMetadataQuery alloc] init];
    [queryDocs setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];

    NSPredicate*    pred = [NSPredicate predicateWithFormat:@"%K like '*.nwa' or %K like '*.NWA'", NSMetadataItemFSNameKey, NSMetadataItemFSNameKey];

    [self.queryDocs setPredicate:pred];

    NSNotificationCenter*   center    = [NSNotificationCenter defaultCenter];
    NSOperationQueue*       mainQueue = [NSOperationQueue mainQueue];

    // I'm using the blocks version because I'm planning to setup observers for the same tracking name...
    self.observeGatherDocs = [center addObserverForName: NSMetadataQueryDidFinishGatheringNotification
                                                 object: self.queryDocs
                                                  queue: mainQueue
                                             usingBlock: ^(NSNotification* note)
    {
        [self queryDidFinishGathering:note];
    }];
    [self.queryDocs startQuery];
}

- (void)queryDidFinishGathering:(NSNotification *)notification
{
    NSLog(@"queryDidFinishGathering:");
    NSMetadataQuery*    query = [notification object];

    if (query == queryDocs)
    {
        NSLog(@"--> for queryDocs");
        NSNotificationCenter*   center    = [NSNotificationCenter defaultCenter];
        NSOperationQueue*       mainQueue = [NSOperationQueue mainQueue];

        [center removeObserver: observeGatherDocs];
        self.observeGatherDocs = nil;
        self.observeUpdateDocs = [center addObserverForName: NSMetadataQueryDidUpdateNotification
                                                     object: query
                                                      queue: mainQueue
                                                 usingBlock: ^(NSNotification* note)
        {
            [self queryDidUpdateDocumentsFolder:note];
        }];

        [query enableUpdates];
    }
}

- (void)queryDidUpdateDocumentsFolder:(NSNotification *)notification
{
    NSLog(@"queryDidUpdateDocumentsFolder:");
    NSMetadataQuery*    query = [notification object];

    [query disableUpdates];

    for (NSMetadataItem* item in [query results])
    {
        // find and handle file changes here w/out any command calls to the query itself
        ...
    }

    if (self.needDownload)
        [self triggerDownloadThread];

    // ---- BEGIN code part added to solve the problem ---- //
    // re-create the observer
    NSNotificationCenter*   center    = [NSNotificationCenter defaultCenter];
    NSOperationQueue*       mainQueue = [NSOperationQueue mainQueue];

    [center removeObserver: observeUpdateDocs];
    self.observeUpdateDocs = [center addObserverForName: NSMetadataQueryDidUpdateNotification
                                                 object: query
                                                  queue: mainQueue
                                             usingBlock: ^(NSNotification* note)
    {
        [self queryDidUpdateDocumentsFolder:note];
    }];
    // ---- END code part added to solve the problem ---- //

    [query enableUpdates];
    // that's all with the query, am I missing something?
}

非常感谢这里的任何建议。

它的真正作用:

  1. 当我直接(通过覆盖)修改 iCloud 文档容器中的文件时 - 什么都没有,查询不会触发。

  2. 当我按 setUbiquitous:NO 序列修改文件时,写入本地文件 setUbiquitous:YES 查询触发一次,我检测到更改,当我再次更改同一个文件时,没有召回查询处理程序。

因此,尽管我在 Apple 文档中发现写入 iCloud 文件的方式如 1. 以上适用于新文件,但似乎也有必要修改现有文件。

但是,无论如何,我怎样才能让查询机制重复运行呢?

干杯...

【问题讨论】:

    标签: ios ios6 icloud nsmetadataquery icloud-api


    【解决方案1】:

    经过更多努力,我找到了一个非凡的解决方案。因此,如果其他人遇到困难,我只是分享我的经验:

    1. 观察者实例变量应保留为保留引用(或在使用 ARC 时为强引用)
    2. 在启用更新之前,必须重新创建观察者。

    似乎就是这样。目前它似乎有效。

    【讨论】:

    • #2 是什么意思?
    • 据我所知:代码行“[query enableUpdates];”之前需要 NSNotificationCenter 调用“addObserverForName:...”,就像我发布的清单一样。
    • 感谢为 NSMetadataQuery 实例提供必要的强绑定...让我发疯了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 2012-05-05
    相关资源
    最近更新 更多