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

问题描述:

当加载从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]; 
     } 

在那之后,我的代码继续试图拉起数据,并用它做各种事情,如解密,解压缩,和到手的文件数据给调用者。

我的电流(哈克)的解决方案是有,到readFileFromiCloud,用于检查一个bool,像这样的循环中的初始呼叫后:

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

此布尔被初始化为假,并且在函数内看到在“replaceDocumentInSandboxWith”之上,布尔被设置为true。

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

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

不知道你是否找到了答案,但我会做的是为你的库创建一个协议,然后建立一个委托,当完成处理程序完成时你可以调用。

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

  1. 创建iCloudStorageManager
  2. 套自为iCloudStorageManager的代表
  3. 调用文件的iCloudStorageManager
  4. 什么就做什么,你需要做开放,设置活动指标或者锁定界面或者两者都不,只是假设它工作,除非委托人告诉你它没有。基本上在这里你的模块会结束,当委托功能被调用时,你的主控制器将重新控制接口。

  5. 在委托函数中,您将从iCloudStorageManager获得状态,判断它是否成功。一旦你从iCloudStorageManager获得这个呼叫,你就可以释放界面,发布一个事情进展顺利或者事情向南并提供答复的提醒......无论你想做什么。

但这就是我处理它的方式。 (是的,这是一个老问题,但我觉得我有一些洞察力:))

+0

我不再在这个项目上工作,因为我的老板在看完我的基础知识后决定与其他人一起选择。但如果我仍然在研究这个问题,这就是我会做的。当时我不知道代表们如何工作。感谢您的有益回应:) – BreadicalMD 2012-05-18 21:26:35

在等待文件完成下载时,冻结用户界面(通过主线程中的睡眠呼叫)似乎对我来说真的很难受,而且我希望您的客户不会那么喜欢。

为什么不扔了一个活动微调,如:

A nice "Loading" graphic

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

+0

虽然这是一个好主意,我的lib没有直接控制接口,它只是一组函数,其他应用程序将呼叫。理想情况下,他们会在单独的线程中调用我的加载函数。 – BreadicalMD 2011-12-29 22:28:41

+0

如果您的图书馆最终“拥有”了正在保存和加载的文档(并且用于提供对该文档的访问),那么如果尚未加载,则返回一个错误或一些NO布尔值。呼叫应用程序需要崩溃没有理由。 – 2011-12-29 22:30:42