如何检测iCloud是否已完成下载文档,以及运行完成处理程序?

时间:2011-12-29 22:05:02

标签: ios icloud

从iCloud加载文档时,必须调用

openWithCompletionHandler:^(BOOL success)completionHandler

此函数将启动从iCloud下载文件的后台线程,并在完成加载后运行完成处理程序。

发生这种情况时,此通话后的所有代码都会继续运行。

如何在下载完成后停止程序继续运行?

在从云端调用加载后,我的代码立即尝试使用该文档 - 当然,由于未完成下载,代码崩溃了。

详情如下:

我目前正在开发一个保存文件库来处理文件的保存/加载,加密,压缩和iCloud支持。用户调用我的库函数LoadFileAtPath,并且有一个参数指定他们是否要我检查此特定文件的iCloud。

当函数启动并且我打算检查iCloud时,我要做的第一件事是调用我的iCloudload函数,如下所示:

bool cloudLoad = [iCloudStorageManager readFileFromiCloud:filePath name:fileName];

在这个函数中我调用openWithCompletionHandler,如下所示:

if ([fileManager fileExistsAtPath:[docURL path]]) 
        {
            [doc openWithCompletionHandler:^(BOOL success){
                if (!success) 
                {
                    // Handle the error.
                    NSLog(@"Failed to retrieve document:%@ from iCloud URL:%@.", fileName, [docURL absoluteString]);
                }
                else
                {
                    NSLog(@"Replacing document in sandbox with iCloud version");
                    BOOL* dir = nil;
                    if (![fileManager fileExistsAtPath:filePath  isDirectory:dir])
                    {
                        NSError *fileError = nil;
                        if(![fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&fileError])
                        {
                            NSLog(@"Error creating file directory: %@\n%@\n%@\n%@", [fileError localizedDescription], [fileError localizedFailureReason], [fileError localizedRecoveryOptions], [fileError localizedRecoverySuggestion]);
                        }

                    }
                    // save new data if success
                    [iCloudStorage replaceDocumentInSandboxWith:doc newData:doc.loadedContents];
                }
            }];
            [doc release];
        }

之后,我的代码继续尝试提取数据,并使用它执行各种操作,例如解密,解压缩,并将文件数据传递给调用者。

我当前(hacky)解决方案是在初始调用readFileFromiCloud之后,有一个检查bool的循环,如下所示:

while (!cloudDidFinishLoad) 
{
     sleep(10);
}

这个bool初始化为false,在上面看到的函数“replaceDocumentInSandboxWith”中,bool设置为true。

但是,我发现这导致程序挂起,它永远不会完成加载iCloud文件,并且永远不会调用完成处理程序。

我不知道该怎么做。我需要该程序停止运行代码,直到下载完成,但我不知道如何执行此操作。

2 个答案:

答案 0 :(得分:1)

不确定您是否找到了答案,但我要做的是为您的库创建一个协议,然后设置一个委托,您可以在完成处理程序完成时调用它。

然后在您的主控制器中可以设置为委托,一旦文件准备就绪,您就可以从库中接收该文件可以使用的调用。所以伪代码就是这样......

  1. 创建iCloudStorageManager
  2. 将self设置为iCloudStorageManager的委托
  3. 在iCloudStorageManager
  4. 上调用文件
  5. 做你需要做的任何事情,设置活动指示器或锁定界面或两者都没有,只是假设它工作,除非代表告诉你它没有。基本上你的块将会结束,当调用委托函数时,你的主控制器将重新获得对接口的控制。

  6. 在委托功能中,您将从iCloudStorageManager收到是否成功的状态。一旦你从iCloudStorageManager接到这个电话,你就可以释放界面,发布事情进展顺利的警报或事情向南发出并提供答复......无论你想做什么。

  7. 但这就是我处理它的方式。 (是的,这是一个老问题,但我觉得我有一些见解:))

答案 1 :(得分:0)

在等待文件完成下载时冻结用户界面(通过主线程上的睡眠调用)对我来说似乎非常苛刻,我希望你的客户不会那样喜欢。

为什么不抛出一个活动微调器,如:

A nice "Loading" graphic

然后在调用iCloud完成处理程序时将其删除?当活动视图在屏幕上时,您可以通过UIView的userInteractionEnabled属性(设置为FALSE)禁用其余的UI交互。