从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文件,并且永远不会调用完成处理程序。
我不知道该怎么做。我需要该程序停止运行代码,直到下载完成,但我不知道如何执行此操作。
答案 0 :(得分:1)
不确定您是否找到了答案,但我要做的是为您的库创建一个协议,然后设置一个委托,您可以在完成处理程序完成时调用它。
然后在您的主控制器中可以设置为委托,一旦文件准备就绪,您就可以从库中接收该文件可以使用的调用。所以伪代码就是这样......
做你需要做的任何事情,设置活动指示器或锁定界面或两者都没有,只是假设它工作,除非代表告诉你它没有。基本上你的块将会结束,当调用委托函数时,你的主控制器将重新获得对接口的控制。
在委托功能中,您将从iCloudStorageManager收到是否成功的状态。一旦你从iCloudStorageManager接到这个电话,你就可以释放界面,发布事情进展顺利的警报或事情向南发出并提供答复......无论你想做什么。
但这就是我处理它的方式。 (是的,这是一个老问题,但我觉得我有一些见解:))
答案 1 :(得分:0)
在等待文件完成下载时冻结用户界面(通过主线程上的睡眠调用)对我来说似乎非常苛刻,我希望你的客户不会那样喜欢。
为什么不抛出一个活动微调器,如:
然后在调用iCloud完成处理程序时将其删除?当活动视图在屏幕上时,您可以通过UIView的userInteractionEnabled
属性(设置为FALSE)禁用其余的UI交互。