0

我正在寻找一种更好的方法将一堆文件从我的 iCloud 容器下载到我的沙箱。这是我目前使用的:

for (FileAttachments *fileLink in items) {
        NSURL *cloudFileURL = [fileLink urlForCloudAttachmentWithName];

        NSURL *fileURL = [backupCloudLocalDirectoryURL URLByAppendingPathComponent: fileLink.fileName];

        NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];

        [fileCoordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&error

                                             byAccessor:^(NSURL *newURL) {

                   NSError *blockError = nil;

                   [fileManager copyItemAtURL:cloudFileURL toURL:fileURL error:&blockError];
                                }];
        }
}

以这种方式制作 iCloud 项目的副本有什么问题吗?在生产中,我有一些用户抱怨他们的所有文件都没有下载。改用会更好NSFileManager's startDownloadingUbiquitousItemAtURL:error吗?如果是这样,为什么?谢谢。

4

3 回答 3

12

从评论中我仍然不完全清楚您是如何发现这些 URL 的,但是影响您的情况的一些重要细节是:

  1. 使用与从iCloud下载文件coordinateReadingItemAtURL:block:无关。的目的是在文件的读取者和写入者之间进行协调,例如,您不会让两个线程同时尝试写入同一个文件。您在 iCloud 中使用文件协调器,因为 iCloud 系统需要读取和写入文件,您的应用程序也是如此。使用协调器可以避免损坏文件,但同样与下载文件无关。NSFileCoordinator

  2. 要从 iCloud 下载文件,您需要使用startDownloadingUbiquitousItemAtURL:error:,然后等待文件下载。这里的正常流程是:

    一个。用于NSMetadataQuery查找 iCloud 帐户中存在的文件

    湾。用于startDownloadingUbiquitousItemAtURL:error:确保它们在本地设备上可用。

    您需要使用此调用的原因仅仅是因为这就是 iCloud 在 iOS 上的工作方式。在您要求文件下载之前不会下载文件,这就是您的要求。[在 OS X 上有所不同,所有内容都会自动下载。]

  3. 除非您已经知道文件已下载,否则您不能简单地从 iCloud URL 复制到另一个位置文件复制操作不会下载文件,因此如果文件在本地不可用,则复制将失败。

于 2014-04-11T18:59:51.533 回答
0

您必须使用元数据查询来识别文件及其下载状态,如果尚未下载,则启动下载,并使用元数据查询确定下载何时完成,然后将文件从 ubiquity 容器复制到应用程序沙箱使用文件协调器的目录。如果您尝试在文件部分下载时复制文件,您可能会得到一些奇怪的结果。

于 2014-04-11T10:08:37.007 回答
0

我和你有同样的问题。

我的情况是:当网络断开连接时,iCloud 服务将文件从 iCloud 容器复制到沙箱。当这一行执行时,它不能进入​​块复制文件。这就是无法复制此文件的原因。

fileCoordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL *newURL)

我的解决方案是:在将文件从 iCLoud 容器复制到沙箱之前,您必须检查网络。如果不可用,请不要执行此代码(返回方法)。如果网络连接,则执行 fileCoordinator 并复制。

更多信息:当将文件从 iCloud 容器复制到沙箱时,方法 fileManager copyItemAtURL:toURL:error: 可以,因为我实现了这个方法,它很好。

希望这有效。

于 2014-04-15T16:57:06.930 回答