2014-04-09 68 views
0

我正在寻找更好的方法将一堆文件从我的iCloud容器下载到我的沙盒中。这是我目前使用:将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更好吗?如果是这样,为什么? 谢谢。

+0

在运行上面的代码之前,您是否做过任何事情以确保文件已被下载? –

+0

或者更好的方法是,你如何找到云文件的URL,以便知道你想从哪个URL复制? –

+0

将这些URL从文件添加到应用程序时保存在Core Data中。他们持有对该文件的有效参考;只是它们在某些情况下没有被下载,并且不可重现。它不应该从fileCoordinator coordinateReadingItemAtURL块中工作吗? –

回答

8

它仍然没有完全清楚,我从评论你是如何发现的URL,但是会影响你的情况了一些重要的细节是:

  1. 使用coordinateReadingItemAtURL:block:什么做下载文件iCloud中。 NSFileCoordinator的目的是在读者和作者之间协调一个文件,例如,你不会有两个线程试图同时写入同一个文件。您在iCloud中使用文件协调员,因为iCloud系统需要读取和写入文件,您的应用程序也一样。使用协调器可避免破坏文件,但与下载文件无关。

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

    一个。使用NSMetadataQuery发现存在于iCloud帐户

    b文件。使用startDownloadingUbiquitousItemAtURL:error:以确保它们在本地设备上可用。

    你需要使用这个调用的原因很简单,因为这是iCloud中如何适用于iOS。直到您要求他们下载文件才会下载,这就是您要求的方式。 [在OS X上是不同的,一切都将自动下载]

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

+0

添加文件时会保存网址进入应用程序,然后上传到iCloud(使用setUbiquitous)。所有这些文件应该在应用程序使用过程中始终保存在iCloud中......只有在这个用例中,当用户进行备份时,此代码会尝试将所有文​​件放入沙箱并将它们放入zip文件。所以,当你说“这个文件在本地不可用”时,这些文件在本地是不可用的(除非你的意思是他们在我不知道的设备上的某个iCloud缓存中)。那么,为什么大部分时间都会工作,而且只是偶尔会失败? –

+0

如果你可以打开并使用一个文件,那么**就可以在本地使用**。除非它存在于本地设备上,否则无法打开文档。这就是“下载”在这种情况下的含义,即文件已从iCloud下载到本地设备。如果文件“本地不可用”,那么除了请求下载外,您无法以任何方式使用这些文档。 –

+0

至于为什么它有时会工作,但并非总是如此,如果没有对代码的详细分析,就不可能说。但是一个可能的情况是它在本地创建文档时工作*,并且在本地设备上仍然可用。它在此备份操作期间失败*,因为这是用户试图抓取所有内容的一次,包括未下载的文件,并且您没有下载这些文件。 –

0

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

+0

问题是复制是在FileCoordinator的coordinateReadingItemAtURL块中完成的。为什么在这种情况下不起作用? –

+0

我不记得细节,但在处理iCloud文件时,我似乎记得你必须使用元数据查询,并且你必须启动下载 - 阅读Apple文档以确认。在任何情况下,我都会使用这种方法与示例应用程序进行备份和恢复核心数据文件 - 请参阅它们是否适用于您,然后对文件使用相同的方法。 http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/ –

0

我和你有同样的问题。

我的情况是:当网络断开时,从iCloud的容器沙箱iCloud服务拷贝文件。当该行执行时,它不能进入​​该块来复制文件。这是该文件无法被复制的原因。

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

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

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

希望这个工程。

+0

如果状态NSMetadataUbiquitousItemDownloadingStatusKey是NSMetadataUbiquitousItemDownloadingStatusCurrent(已下载到本地iCloud容器),那么也需要使用fileCoordinator从url读取? @nmh –