2011-12-29 79 views
1

當加載從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

不知道你是否找到了答案,但我會做的是爲你的庫創建一個協議,然後建立一個委託,當完成處理程序完成時你可以調用。

然後在您的主控制器中可以設置爲委託,一旦文件準備就緒,您可以從庫中接收該文件準備使用的調用。因此,僞代碼將是這樣的......

  1. 創建iCloudStorageManager
  2. 套自爲iCloudStorageManager的代表
  3. 調用文件的iCloudStorageManager
  4. 什麼就做什麼,你需要做開放,設置活動指標或者鎖定界面或者兩者都不,只是假設它工作,除非委託人告訴你它沒有。基本上在這裏你的模塊會結束,當委託功能被調用時,你的主控制器將重新控制接口。

  5. 在委託函數中,您將從iCloudStorageManager獲得狀態,判斷它是否成功。一旦你從iCloudStorageManager獲得這個呼叫,你就可以釋放界面,發佈一個事情進展順利或者事情向南並提供答覆的提醒......無論你想做什麼。

但這就是我處理它的方式。 (是的,這是一個老問題,但我覺得我有一些洞察力:))

+0

我不再在這個項目上工作,因爲我的老闆在看完我的基礎知識後決定與其他人一起選擇。但如果我仍然在研究這個問題,這就是我會做的。當時我不知道代表們如何工作。感謝您的有益迴應:) – BreadicalMD 2012-05-18 21:26:35

0

在等待文件完成下載時,凍結用戶界面(通過主線程中的睡眠呼叫)似乎對我來說真的很難受,而且我希望您的客戶不會那麼喜歡。

爲什麼不扔了一個活動微調,如:

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

相關問題