5

我正在为我的应用程序(通过 iCloud)制作备份管理器。我做了一些测试,基础工作正常。但几天后它停止了。我NSMetadataQuery用于搜索是否存在备份文件。我的备份文件被命名为例如Backup29112011154133.xml其中数字代表备份日期(格式为ddMMyyyyHHmmss)。我检查它-viewDidAppear

- (void)viewDidAppear:(BOOL)animated {
    [self checkForRemoteFile];
}

- (void)checkForRemoteFile {
    NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    if (ubiq) {
        NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
        [query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K like 'Backup*'",NSMetadataItemFSNameKey];
        [query setPredicate:pred];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
        [query startQuery];
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"iCloud is unavailable at the moment" message:nil delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
        [alert setTag:TAG_ALERT_NOICLOUD];
        [alert show];
    }
}

- (void)queryDidFinishGathering:(NSNotification *)notif {
    NSMetadataQuery *query = [notif object];
    [query disableUpdates];
    [query stopQuery];
    [self loadRemoteFile:query];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
}

- (void)loadRemoteFile:(NSMetadataQuery *)query {
    if ([query resultCount] == 1) {
        canRestore = YES;
        NSMetadataItem *item = [query resultAtIndex:0];
        // parse the backup file
        [self.tableView reloadData];
    } else {
        canRestore = NO;
        modifDate = @"never";
        backupInfoLoaded = YES;
        [self.tableView reloadData];
    }
}

问题是- (void)queryDidFinishGathering:(NSNotification *)notif永远不会执行。我在那里放了断点和 NSLogs 离子,但什么也没发生。

我还尝试检查其他通知,例如“查询确实开始收集”和“查询过程”。仅发布“查询已开始”通知。

我还有注册了 iCloud 并附加了权利文件的 AppID。

你能帮我看看这是怎么回事吗?也许我错过了什么?

4

4 回答 4

17

首先,如果不是从 MaintThread 调用 startQuery,则 NSMetadataQuery 不起作用。每个路径的谓词也有可能失败。以下代码对我有用。

NSURL *mobileDocumentsDirectoryURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
...
query.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%%K like \"%@*\"", [mobileDocumentsDirectoryURL path]], NSMetadataItemPathKey];
[query startQuery];
于 2011-12-01T18:21:53.050 回答
9

通过创建ivarfor 来修复NSMetadataQuery

我不知道为什么应用程序在没有 NSMetadataquery ivar 的情况下无法读取数据。

于 2011-12-10T13:10:35.150 回答
2

不幸的是,iCloud 和使用NSMetaDataQuery. 老实说,到目前为止,所有与 iCloud 相关的问题的最佳来源是 Apple 开发者论坛。今天 Apple 发布了 iOS 5.1 测试版,并且发布说明仍然说 NSMetaDataQuery 无法正常运行。iCloud 仍然无法正常工作,这非常令人沮丧,但遗憾的是我们无能为力。

于 2011-11-29T16:11:51.450 回答
1

这个问题仍然存在。我已经能够将其追溯到以下分歧:

  • 如果您将查询的搜索谓词限制为名称键,

例如

[NSPredicate predicateWithFormat:@"%K like[cd] %@", NSMetadataItemFSNameKey, @"*"]

然后它将按预期工作(发布所有四个查询生命周期通知)。

  • 但是,如果您尝试使用复合谓词或尝试使用路径,

如在

[NSPredicate predicateWithFormat:@"%K BEGINSWITH %@", NSMetadataItemPathKey, [self cloudDocumentsURL].path]

或者

[NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:namePred, pathPred, nil]];

然后只会发布初始通知。

去年,我在多个测试和预期生产应用程序中尝试了数百种这些可配置变量的组合,但尚未找到该假设的反例。

不幸的是,NSMetadataQuery 不适用于无处不在的商店(从 10.8 开始)。

我的解决方法是从查询中获取原始结果,并主要在绑定的 NSArrayController 上工作,它可以过滤其结果。这将意味着从 query.results 重构大多数现有代码,并且会影响性​​能(大概),但这是我找到的唯一方法。我想要一个替代方案。

于 2012-10-23T16:41:08.913 回答