【问题标题】:Documents not Uploading to iCloud when using For Loops - iOS使用 For 循环时文档未上传到 iCloud - iOS
【发布时间】:2012-12-20 13:32:00
【问题描述】:

我正在尝试将一个充满文档的本地文件夹上传到远程 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 循环工作正常 - 我使用 NSLog 语句来找出它正在上传的文件 - 并且本地存储但尚未在 iCloud 中的每个文件都应该启动上传。 For Loop 完成后,我使用developer.icloud.com 检查哪些文档现在在 iCloud 中。在本地存储的许多上传到 iCloud 的文件中,只有一个文件(我的应用程序不断制作但从未使用过的 sqlite 文件)。 为什么使用for循环只能上传一个文件?

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

编辑:通常当我将大文件上传到 iCloud(不使用 For 循环)时,我可以在 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.)"}

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

【问题讨论】:

  • 不详细检查您的代码,我会问您等待多久才能看到它们是否已上传? iCloud 不是您的应用程序执行的即时上传,而是“最终”同步内容的后台守护程序。现在,“最终”通常非常快,但速度不是亚秒级。
  • 好点,但是通常当我将大文件上传到 iCloud(不使用 For 循环)时,我可以在 iCloud 开发网站上看到文件几乎立即等待上传 .我正在通过 WiFi 测试所有内容,我已经等待了一段时间,但没有出现任何内容(除了 sqlite 文件)。
  • 您是否在检查setUbiquitous 调用是否返回YES,如果它返回NO,您为什么不检查错误状态?该方法有一个error 参数是有原因的。
  • @PeterM 我用另一种方法检查 iCloud 的可用性,如果 iCloud 可用,则允许调用此方法。能否举例说明如何使用error 参数?
  • @RazorSharp 您需要阅读setUbiquitousdeveloper.apple.com/library/mac/#documentation/cocoa/conceptual/… 上的文档

标签: objective-c ios for-loop icloud


【解决方案1】:

好的,最后的编辑很有用。该错误抱怨缺少源 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,以防万一。

【讨论】:

  • 或者更好的是直接使用返回 URL 的方法,而不是使用路径并稍后将它们转换为 URL。
  • 好点,切换到contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error: 也可以完成这项工作。
猜你喜欢
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 2021-11-08
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
相关资源
最近更新 更多