【问题标题】:NSMetadataQuery says there are no documents, despite data successfully syncing?NSMetadataQuery 说没有文档,尽管数据成功同步?
【发布时间】:2013-06-12 19:45:21
【问题描述】:

我正在尝试让我的 OS X 应用程序根据对 iCloud 文档的更改自动更新,但我很难让通知正常工作。具体来说,我得到了一些代码,应该列出我的NSMetadataQuery 的所有结果(只是这样我可以进行一些测试和确认),但它返回 0 结果。尽管事实上我的无处不在的容器中显然有一些东西,因为数据正在从我的 OS X 应用程序成功上传,并在启动时再次成功下载。这就是我现在所拥有的。

CloudDocument.h:

@property (nonatomic, strong) NSMetadataQuery *alertQuery;

CloudDocument.m:

@implementation CloudDocument

@synthesize alertQuery;

-(id)init {
    self = [super init];
    if (self) {
        alertQuery = [[NSMetadataQuery alloc] init];
        if (alertQuery) {
            // Search the Documents subdirectory only.
            [alertQuery setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];

            // Add a predicate for finding the documents.
            NSString *filePattern = @"*";
            [alertQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, filePattern]];
        }

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];

        NSLog(@"Notification created");

        [alertQuery startQuery];
    }
    return self;
}

-(void)queryDidUpdate:(NSNotification *)notification {
    [alertQuery disableUpdates];

    NSLog(@"Something changed!!! - %@", [notification name]);

    // Look at each element returned by the search
    // - note it returns the entire list each time this method is called, NOT just the changes
    int resultCount = (int)[alertQuery resultCount];
    NSLog(@"%i", resultCount);
    for (int i = 0; i < resultCount; i++) {
        NSMetadataItem *item = [alertQuery resultAtIndex:i];
        [self logAllCloudStorageKeysForMetadataItem:item];
    }

    [alertQuery enableUpdates];
}

- (void)logAllCloudStorageKeysForMetadataItem:(NSMetadataItem *)item {
    NSLog(@"LogAll gets called");
    NSNumber *isUbiquitous = [item valueForAttribute:NSMetadataItemIsUbiquitousKey];
    NSNumber *hasUnresolvedConflicts = [item valueForAttribute:NSMetadataUbiquitousItemHasUnresolvedConflictsKey];
    NSNumber *isDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey];
    NSNumber *isDownloading = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadingKey];
    NSNumber *isUploaded = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey];
    NSNumber *isUploading = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadingKey];
    NSNumber *percentDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentDownloadedKey];
    NSNumber *percentUploaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentUploadedKey];
    NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];

    BOOL documentExists = [[NSFileManager defaultManager] fileExistsAtPath:[url path]];

    NSLog(@"isUbiquitous:%@ hasUnresolvedConflicts:%@ isDownloaded:%@ isDownloading:%@ isUploaded:%@ isUploading:%@ %%downloaded:%@ %%uploaded:%@ documentExists:%i - %@", isUbiquitous, hasUnresolvedConflicts, isDownloaded, isDownloading, isUploaded, isUploading, percentDownloaded, percentUploaded, documentExists, url);
}

-(NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
    [Data setSyncProgressIndicators:NO];
    return [NSKeyedArchiver archivedDataWithRootObject:[Data getAllNotes]];
}

-(BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
    [Data setSyncProgressIndicators:YES];
    NSDictionary *dict = (NSDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)data];
    [Data didReceiveCloudData:dict];
    [Data setSyncProgressIndicators:NO];
    return YES;
}

+(BOOL)autosavesInPlace {
    return YES;
}

@end

我看到的结果是 queryDidUpdate: 在启动时被调用了 2-3 次,全部来自 NSMetadataQueryDidFinishGatheringNotification。问题是,“resultCount”变量始终为 0,因此无论我多久编辑一次云文档,logAllCloudStorageKeysForMetadataItem 都不会被调用,NSMetadataQueryDidUpdateNotification 根本不会被调用。

任何人都可以就搜索返回 0 个结果的原因提供任何建议,尽管显然有一个文件正在来回同步?或者更好的是,你能完全看出代码有什么问题吗?我能做些什么来让NSMetadataQueryDidUpdateNotification 走上正轨并告诉我什么时候对我的文件进行了编辑?顺便说一句,我正在使用以下方法保存文件:

+(NSURL *)notesURL {
    NSURL *url = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    return [url URLByAppendingPathComponent:kAllNotes];
}

其中“kAllNotes”=“笔记”。

提前感谢您的帮助!

编辑:请注意,当我说它同步成功时,它并没有因为 NSMetadataQuery 而做。我在其他地方有一个 cloudDoc = [[CloudDocument alloc]initWithContentsOfURL:[self notesURL] ofType:NSPlainTextDocumentType error:nil]; 行加载 CloudDocument,所以我知道那里有一个文档,我知道它正在被应用程序的 iOS 版本更改,但我现在要掌握的 NSMetadataQuery 是只有在那里才能与NSMetadataQueryDidUpdateNotification 一起工作,而且似乎都不能正常工作。

另外,我绝对是个初学者,所以非常非常感谢您提出建议时的代码 sn-ps 和示例!

【问题讨论】:

    标签: cocoa nsnotifications nsmetadataquery


    【解决方案1】:

    好的,我找到了答案:我一直将文件保存到根文件夹,但在 NSMetadataQueryUbiquitousDocumentsScope 中搜索。应该是NSMetadataQueryUbiquitousDataScope,现在它似乎运行良好。我希望这对未来的人们有所帮助!

    【讨论】:

    • 如果您的应用制作并保存文档,您不应该将它们保存在您的 Documents 文件夹中(并在相应的范围内查找它们)吗?
    • 哦,彼得。你和你对“有意义”的坚持。是的,这可能是个好主意...
    • 你能给我一个代码sn-p参考如何做以下,因为我是文件上传和下载的新手。我想实现什么应用程序。 1) 在 iCloud 自定义文件夹中上传文档 2) 跟踪进度并向用户显示 3) 上传成功通知用户 100% 完成到 iCloud 4) 在 iCloud 自定义文件夹中下载文档 5) 下载进度并向用户显示 6) 下载成功通知用户 100% 完成 iCloud
    • 请注意,我没有做实时 iCloud 文档参考,就像 whatsapp 存储媒体文件的 Zip 和 Sqlite 文件一样,当应用程序安装到另一台设备时我将恢复这些文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    • 2013-06-12
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多