阅读背景:

使用For循环时,文档无法上传到iCloud - iOS

来源:互联网 

I am attempting to upload a local folder full of documents to a remote iCloud folder. I wrote this method to loop through the array of files in the local folder, check if they already exist, and if they don't exist upload them to iCloud. Note- this code is being executed on the background thread not the main thread.

我正在尝试将一个装满文档的本地文件夹上传到远程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 {
          ...
     } }

When I run this code the For Loop works fine - I use NSLog statements to find out which file it is uploading - and every file stored locally that isn't already in iCloud is supposed to start uploading. After the For Loop is finished I check which documents are now in iCloud using developer.icloud.com. Only one file (an sqlite file that my app keeps making but never uses) out of the many stored locally uploads to iCloud. Why would only one file upload when using for loops?

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

When I use the same code to upload individual files (without a For Loop) they upload to iCloud perfectly. Why would a For Loop hinder the uploading of files? Does this have to do with the For Loop continuing to the next line of code without waiting for the last process / line to finish executing? What's going on here?

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

EDIT: Usually when I upload large files to iCloud (without using a For Loop) I can see on the iCloud dev site that the file is Pending Upload almost instantly. I'm testing everything over WiFi and I've been waiting a while but nothing appears (except for the sqlite file).

编辑:通常当我将大文件上传到iCloud(不使用For循环)时,我可以在iCloud开发站点上看到该文件几乎立即被挂起。我正在通过WiFi测试一切,我已经等了一段时间但没有出现(除了sqlite文件)。

EDIT: I also check for iCloud availability in a different method which then allows calls to this method if iCloud is available. I've also made sure to read over the documentation and watched the WWDC videos on Apple's website, however they are complex and don't provide much explanation for what I'm trying to do.

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

EDIT: After revising the code above (adding the error functionality), I now get this error message in the log:

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

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.)"}

This makes things even more confusing because one of the files uploads successfully, whereas the others do not.

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

1 个解决方案

#1


6  

OK, that last edit is useful. The error complains that the source URL (directoryURL in your code) is missing-- probably because it's nil. Why would it be nil? Because you're creating it wrong. You're using -[NSURL initWithString:], and the docs say that:

好的,最后一次编辑很有用。错误抱怨源URL(代码中的directoryURL)丢失 - 可能是因为它是零。为什么会是零?因为你错了。你正在使用 - [NSURL initWithString:],文档说:

This string must conform to URL format as described in RFC 2396. This method parses URLString according to RFCs 1738 and 1808.

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

You're passing in a file path, not a URL. If you pass NSURL something it doesn't recognize as a valid URL, it normally returns nil. It looks like NSURL will frequently produce a file URL anyway, but failure is the expected behavior here. From what I can tell it seems to work if the filename contains no spaces, but that's not documented and not something you could rely on.

您传入的是文件路径,而不是URL。如果你传递的NSURL不能识别为有效的URL,它通常会返回nil。看起来NSURL经常会生成一个文件URL,但失败是这里的预期行为。从我所知道的,如果文件名不包含空格似乎可行,但是没有记录,也没有你可以依赖的东西。

What you should do is change the line where you initialize directoryURL to use something that accepts a file path. Something like:

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

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

Also, make sure to verify that directoryURL is not nil, just in case.

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


分享到: