6

我正在尝试将一个充满文档的本地文件夹上传到远程 iCloud 文件夹。我编写了这个方法来遍历本地文件夹中的文件数组,检查它们是否已经存在,如果它们不存在,则将它们上传到 iCloud。注意 - 此代码在后台线程而不是主线程上执行。

//Get the array of files in the local documents directory
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *localDocuments = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:nil];

//Compare the arrays then upload documents not already existent in iCloud
for (int item = 0; item < [localDocuments count]; item++) {
    //If the file does not exist in iCloud, upload it
     if (![[iCloud previousQueryResults] containsObject:[localDocuments objectAtIndex:item]]) {
          NSLog(@"Uploading %@ to iCloud...", [localDocuments objectAtIndex:item]);
          //Move the file to iCloud
          NSURL *destinationURL = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@",[localDocuments objectAtIndex:item]]];
          NSError *error;
          NSURL *directoryURL = [[NSURL alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:[localDocuments objectAtIndex:item]]];
          BOOL success = [[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:directoryURL destinationURL:destinationURL error:&error];
          if (success == NO) {
              //Determine Error
              NSLog(@"%@",error);
          }
     } else {
          ...
     } }

当我运行此代码时,For Loop 工作正常——我使用 NSLog 语句来找出它正在上传的文件——并且本地存储但尚未在 iCloud 中的每个文件都应该开始上传。For Loop 完成后,我使用developer.icloud.com检查哪些文档现在在 iCloud 中。在本地存储的许多上传到 iCloud 的文件中,只有一个文件(我的应用程序不断制作但从未使用过的 sqlite 文件)。为什么使用 for 循环时只上传一个文件?

当我使用相同的代码上传单个文件(没有 For 循环)时,它们会完美地上传到 iCloud。为什么 For 循环会阻碍文件的上传?这是否与 For Loop 继续下一行代码而不等待最后一个进程/行完成执行有关?这里发生了什么?

编辑:通常当我将大文件上传到 iCloud(不使用 For Loop)时,我可以在 iCloud 开发网站上看到该文件几乎立即处于待上传状态。我正在通过 WiFi 测试所有内容,我已经等了一段时间,但什么都没有出现(除了 sqlite 文件)。

编辑:我还以不同的方法检查 iCloud 可用性,如果 iCloud 可用,则允许调用此方法。我还确保阅读了文档并观看了 Apple 网站上的 WWDC 视频,但是它们很复杂,并没有为我正在尝试做的事情提供太多解释。

编辑:修改上面的代码(添加错误功能)后,我现在在日志中收到此错误消息:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x1f5dd070 {NSUnderlyingError=0x208ad9b0 "The operation couldn’t be completed. (LibrarianErrorDomain error 2 - No source URL specified.)"}

这使事情变得更加混乱,因为其中一个文件成功上传,而其他文件则没有。

4

1 回答 1

6

好的,最后的编辑很有用。该错误抱怨源 URL(directoryURL在您的代码中)丢失 - 可能是因为它是nil. 为什么会这样nil?因为你创建错了。您正在使用-[NSURL initWithString:],并且文档说:

此字符串必须符合 RFC 2396 中描述的 URL 格式。此方法根据 RFC 1738 和 1808 解析 URLString。

您传递的是文件路径,而不是 URL。如果您传递NSURL了一些它无法识别为有效 URL 的内容,它通常会返回nil. 看起来NSURL无论如何都会经常产生一个文件 URL,但失败是这里的预期行为。据我所知,如果文件名不包含空格,它似乎可以工作,但这没有记录,也不是你可以依赖的东西。

您应该做的是更改您初始化的行directoryURL以使用接受文件路径的内容。就像是:

NSURL *directoryURL = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingPathComponent:[localDocuments objectAtIndex:item]]];

另外,请确保验证directoryURL不是nil,以防万一。

于 2013-01-17T22:38:19.580 回答