2014-04-09 66 views
0

我正在尋找更好的方法將一堆文件從我的iCloud容器下載到我的沙盒中。這是我目前使用:將iCloud文件複製到沙盒

for (FileAttachments *fileLink in items) { 
     NSURL *cloudFileURL = [fileLink urlForCloudAttachmentWithName]; 

     NSURL *fileURL = [backupCloudLocalDirectoryURL URLByAppendingPathComponent: fileLink.fileName]; 

     NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 

     [fileCoordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&error 

              byAccessor:^(NSURL *newURL) { 

        NSError *blockError = nil; 

        [fileManager copyItemAtURL:cloudFileURL toURL:fileURL error:&blockError]; 
           }]; 
     } 
} 

是否與製作的iCloud項目的副本這樣什麼問題?在製作中,我有一些用戶抱怨說他們的所有文件都沒有下載。代替使用NSFileManager's startDownloadingUbiquitousItemAtURL:error更好嗎?如果是這樣,爲什麼? 謝謝。

+0

在運行上面的代碼之前,您是否做過任何事情以確保文件已被下載? –

+0

或者更好的方法是,你如何找到雲文件的URL,以便知道你想從哪個URL複製? –

+0

將這些URL從文件添加到應用程序時保存在Core Data中。他們持有對該文件的有效參考;只是它們在某些情況下沒有被下載,並且不可重現。它不應該從fileCoordinator coordinateReadingItemAtURL塊中工作嗎? –

回答

8

它仍然沒有完全清楚,我從評論你是如何發現的URL,但是會影響你的情況了一些重要的細節是:

  1. 使用coordinateReadingItemAtURL:block:什麼做下載文件iCloud中。 NSFileCoordinator的目的是在讀者和作者之間協調一個文件,例如,你不會有兩個線程試圖同時寫入同一個文件。您在iCloud中使用文件協調員,因爲iCloud系統需要讀取和寫入文件,您的應用程序也一樣。使用協調器可避免破壞文件,但與下載文件無關。

  2. 下載從iCloud中,您需要使用startDownloadingUbiquitousItemAtURL:error:,然後等到文件下載的文件。這裏的正常流程是:

    一個。使用NSMetadataQuery發現存在於iCloud帳戶

    b文件。使用startDownloadingUbiquitousItemAtURL:error:以確保它們在本地設備上可用。

    你需要使用這個調用的原因很簡單,因爲這是iCloud中如何適用於iOS。直到您要求他們下載文件纔會下載,這就是您要求的方式。 [在OS X上是不同的,一切都將自動下載]

  3. 不能簡單地從iCloud中的網址複製到另一個位置,除非你已經知道該文件已被下載。文件複製操作不會下載該文件,因此如果該文件在本地不可用,則複製將失敗。

+0

添加文件時會保存網址進入應用程序,然後上傳到iCloud(使用setUbiquitous)。所有這些文件應該在應用程序使用過程中始終保存在iCloud中......只有在這個用例中,當用戶進行備份時,此代碼會嘗試將所有文​​件放入沙箱並將它們放入zip文件。所以,當你說「這個文件在本地不可用」時,這些文件在本地是不可用的(除非你的意思是他們在我不知道的設備上的某個iCloud緩存中)。那麼,爲什麼大部分時間都會工作,而且只是偶爾會失敗? –

+0

如果你可以打開並使用一個文件,那麼**就可以在本地使用**。除非它存在於本地設備上,否則無法打開文檔。這就是「下載」在這種情況下的含義,即文件已從iCloud下載到本地設備。如果文件「本地不可用」,那麼除了請求下載外,您無法以任何方式使用這些文檔。 –

+0

至於爲什麼它有時會工作,但並非總是如此,如果沒有對代碼的詳細分析,就不可能說。但是一個可能的情況是它在本地創建文檔時工作*,並且在本地設備上仍然可用。它在此備份操作期間失敗*,因爲這是用戶試圖抓取所有內容的一次,包括未下載的文件,並且您沒有下載這些文件。 –

0

您必須使用元數據查詢來識別文件及其下載狀態的話,如果他們沒有被下載啓動下載,並使用元數據查詢確定下載完成後,然後將文件從無處不在容器複製使用文件協調器將應用程序安裝到應用程序沙箱目錄。如果在部分下載時嘗試複製文件,可能會得到一些奇怪的結果。

+0

問題是複製是在FileCoordinator的coordinateReadingItemAtURL塊中完成的。爲什麼在這種情況下不起作用? –

+0

我不記得細節,但在處理iCloud文件時,我似乎記得你必須使用元數據查詢,並且你必須啓動下載 - 閱讀Apple文檔以確認。在任何情況下,我都會使用這種方法與示例應用程序進行備份和恢復核心數據文件 - 請參閱它們是否適用於您,然後對文件使用相同的方法。 http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/ –

0

我和你有同樣的問題。

我的情況是:當網絡斷開時,從iCloud的容器沙箱iCloud服務拷貝文件。當該行執行時,它不能進入​​該塊來複制文件。這是該文件無法被複制的原因。

fileCoordinator coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL *newURL) 

我的解決方案是:在將文件從iCLoud容器複製到沙箱之前,您必須檢查網絡。如果它不可用,請不要執行此代碼(返回方法)。如果網絡連接,執行fileCoordinator並複製。

更多信息:當將文件從IClo​​ud容器複製到沙箱時,方法fileManager copyItemAtURL:toURL:error:是的,因爲我實現了這個方法,這很好。

希望這個工程。

+0

如果狀態NSMetadataUbiquitousItemDownloadingStatusKey是NSMetadataUbiquitousItemDownloadingStatusCurrent(已下載到本地iCloud容器),那麼也需要使用fileCoordinator從url讀取? @nmh –