如何在iCloud中验证文件是否存在?

时间:2014-01-13 15:06:22

标签: objective-c file icloud nsfilemanager

我知道该文件存在,因为我可以下载它,但我需要检查它是否存在。我尝试过使用

[NSFileManager contentsOfDirectoryAtPath:error:]

但它给了我null。我不明白为什么那是因为我仍然可以下载我正在寻找的文件。也许这是一个不正确的URL,但我正在使用的URL是我在创建我正在寻找的UIDocument时打印的URL。也许我使用了错误的方法?

编辑:

我也尝试过使用NSMetadataQuery,我可以让它回馈通知,但即使我可以明确下载我正在寻找的文件,它也没有结果。

3 个答案:

答案 0 :(得分:3)

要在iCloud中查找文件,请使用NSMetadataQuery。这将找到已下载的文件以及用户帐户中尚未下载到本地设备的文件。使用NSFileManager最多只会查找已下载的文件。

你用这样的东西设置它:

NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
[self setMetadataQuery:query];
[query setSearchScopes:@[NSMetadataQueryUbiquitousDataScope]];
[query setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE '*'", NSMetadataItemFSNameKey]];

您需要观察NSMetadataQueryDidStartGatheringNotificationNSMetadataQueryDidUpdateNotification,可能NSMetadataQueryDidFinishGatheringNotification。然后开始查询:

[query startQuery];

完成后,您将在查询发现iCloud文件时收到通知。通知将包含NSMetadataItem的实例,您可以使用它们来获取文件大小,下载状态等信息。

答案 1 :(得分:1)

使用元数据查询 - 这是一些示例代码

/*!  Creates and starts a metadata query for iCloud files

 */
- (void)createFileQuery {
    [_query stopQuery];

        if (_query) {
            [_query startQuery];
        }
        else {
            _query = [[NSMetadataQuery alloc] init];

            [_query setSearchScopes:[NSArray arrayWithObjects:NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope, nil]];
            // NSString * str = [NSString stringWithFormat:@"*.%@",_fileExtension];
            NSString *str = @"*";
            [_query setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, str]];

            NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
            [notificationCenter addObserver:self selector:@selector(fileListReceived) name:NSMetadataQueryDidFinishGatheringNotification object:_query];
            [notificationCenter addObserver:self selector:@selector(fileListReceived) name:NSMetadataQueryDidUpdateNotification object:_query];
            [_query startQuery];
        }

}

/*! Gets called by the metadata query any time files change.  We need to be able to flag files that
 we have created so as to not think it has been deleted from iCloud.

 */
- (void)fileListReceived {
    LOG(@"fileListReceived called.");

    NSArray* results = [[_query results] sortedArrayUsingComparator:^(NSMetadataItem* firstObject, NSMetadataItem* secondObject) {
        NSString* firstFileName = [firstObject valueForAttribute:NSMetadataItemFSNameKey];
        NSString* secondFileName = [secondObject valueForAttribute:NSMetadataItemFSNameKey];
        NSComparisonResult result = [firstFileName.pathExtension compare:secondFileName.pathExtension];
        return result == NSOrderedSame ? [firstFileName compare:secondFileName] : result;
    }];

    //FLOG(@" results of query are %@", results);
    for (NSMetadataItem* result in results) {
        NSURL* fileURL = [result valueForAttribute:NSMetadataItemURLKey];
        NSString* fileName = [result valueForAttribute:NSMetadataItemDisplayNameKey];
        NSNumber* percentDownloaded = [result valueForAttribute:NSMetadataUbiquitousItemPercentDownloadedKey];
        NSNumber *isDownloaded = nil;
        NSNumber *isDownloading = nil;
        NSError *er;
        [fileURL getResourceValue: &isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:&er];
        [fileURL getResourceValue: &isDownloading forKey:NSURLUbiquitousItemIsDownloadingKey error:&er];
        FLOG(@" Found file %@", fileName);
   }

}

答案 2 :(得分:1)

来自docs

  

在iOS中,在需要时主动下载文件。 iCloud中的项目但不是   但是本地不会被iOS自动下载;只有他们的元数据   自动下载。最初下载基于新的iCloud   文档需要您的注意和在您的应用程序中仔细设计。   明确下载此类项目后,系统会处理   下载来自iCloud的更改。

     

考虑跟踪   文件下载状态是iOS应用程序模型层的一部分。有   这些信息可以让您提供更好的用户体验:您可以   设计您的应用程序,以免在需要时长时间延迟用户   打开尚未本地化的文档。对于每个文件(或文件)   包)您的应用程序的元数据查询提供的URL,获取值   调用NSURLUbiquitousItemIsDownloadedKey方法调用NSURL密钥   getResourceValue:forKey:error:。读取尚未存档的文件   下载可能需要很长时间,因为协调阅读   操作阻止,直到文件完成下载(或无法完成   下载)。

     

对于尚未本地的文件(或文件包),您可以启动   在用户请求时或之前下载。如果你的应用程序   用户文件数量不大或数量不多,需要考虑一种策略   是主动下载元数据指示的所有文件   查询。对于查询提供的每个文件(或文件包)URL,make   通过调用NSFileManager方法将相应的项本地化   startDownloadingUbiquitousItemAtURL:error:。如果你通过这个方法a   已经是本地的项目的URL,该方法不执行任何工作   返回YES。

更新:iOS7应使用NSURLUbiquitousItemDownloadingStatusKey代替NSURLUbiquitousItemIsDownloadedKey