iOS5可能會刪除本地檔案儲存 - Caches 也不安全

來源:互聯網
上載者:User

標籤:

轉自:http://blog.163.com/ray_jun/blog/static/1670536422011101225132544/

出處:http://superman474.blog.163.com/blog/static/120661462011101115811199/

 

關於iOS 5的本地檔案儲存Marco(Instapaper 的開發人員)寫過一篇很好的文章闡述過相關問題,有興趣的同學可以先閱讀下他的文章然後再看下文。

在蘋果開發人員的論壇上也有許多相關問題的討論貼:

安全地儲存檔案?

如何在快取檔案夾內持久儲存檔案?

如果我想讓檔案永久儲存且不會和iTunes同步,我該把檔案儲存在哪裡?

iCloud 的雲備份佔用了巨大的空間?

 

幾點困惑

在蘋果開發人員論壇的討論中,總結出以下幾點令人困惑的問題:

  1. 關於緩衝和臨時檔案目錄的含義
  2. 蘋果開發文檔的更新修改
  3. 應用審核被拒
  4. iTunes和iCloud會備份哪些檔案
  5. iOS 5的機制改變

下面讓我們逐個討論:

 

關於緩衝和臨時檔案目錄的含義

如果你有OS X或者Unix的開發背景,就會很容易明白蘋果的立場:即無法保證資料在這兩個目錄中能持續地儲存多久。

實際上在應用沙箱(sandbox)裡的臨時檔案目錄(tmp directory)和根目錄下臨時檔案目錄(root /tmp)不太相同,但也不需要區別對待這些目錄。

過去如果你從沒觀察到檔案在這些目錄裡被刪除,那並不保證以後不會。特別是當這個改變和開發文檔說明一致時,這是一個普遍的規律。

 

蘋果開發文檔的更新修改

直到2011年6月的官方開發文檔中關於 <Application_Home>/Documents 的說法是:

“使用這個目錄來儲存使用者文檔和應用資料檔案”

這個用法相當明確。而iOS 5改變了Documents 目錄用法卻不給出任何合適的替代方法,因此難怪開發人員感到不高興。

而關於 <Application_Home>/Library/Caches 的說法是:

“使用這個目錄來寫入任意應用的專屬支援檔案,以便你可以使它們在應用程式啟動時或者在應用程式更新時保持不變。

你的應用程式通常要負責這些檔案的添加和刪除,有些情況下也要能夠重新建立所需檔案,因為iTunes會在復原模式下刪除儲存在這裡的檔案。”

這段話的涵義很不明確。我讀完覺得大意是蘋果在iOS 5上做了個根本上的改變,而使得看這段說明很矛盾。但是如果你仔細看字眼“通常要”(”generally”)和“能重新建立”(”able to re-create”)的話,在蘋果警告你的應用內檔案不合規範時,你就會明白那些地方需要改進了。

關於iOS 資料存放區指導手冊(iOS Data Storage Guidelines)的說明:

“為了儘力確保檔案備份高效,請務必根據以下的指導來儲存你的應用資料:

1、只有那些使用者產生的文檔和其他資料或者是那些不能被你的應用所重建的資料應當儲存在<Application_Home>/Documents 目錄內。這些資料檔案將會自動的通過iCloud備份。

2、那些可以重新下載或者重新建立的資料應當儲存在<Application_Home>/Library/Caches 目錄內。你可以把資料庫快取檔案或者可下載的內容如雜誌、報紙、地圖應用的資料等放入緩衝目錄裡(Caches directory)

3、臨時需要的資料應該儲存在<Application_Home>/tmp 目錄內。儘管這些檔案不會備份到iCloud裡,請記住在你不再需要它們時立即刪除掉這些檔案,這樣它們就不會繼續浪費使用者裝置的儲存空間了。”

事實上許多報紙、雜誌和地圖的應用單純的目的就是想離線顯示內容,如果我們暫時無視這點,那麼以上的指導講的很清楚,可以去參考。

 

應用審核被拒

開發人員目前報告說那些在Document 目錄內儲存任意/少量/大量資料的應用正在審核中被拒。

應用審核部門不太可能面面俱到,比如理清楚哪些檔案該儲存到哪些目錄內、哪些檔案是使用者產生的、哪些資料是可以重新下載或重新被建立的。有些開發人員報告中說,他們跟應用審核部門解釋清楚應用是如何儲存資料、如何遵守指導原則的,之後他們的應用也得到了通過。

 

iTunes和iCloud會備份哪些檔案

應用裡home 目錄內的所有資料都會被備份除了:

  1. 編譯後的應用程式套件檔案 (.app)
  2. <Application_Home>/tmp 目錄內的檔案
  3. <Application_Home>/Library/Caches 目錄內的檔案

這些在iOS資料儲存指導手冊上(iOS Data Storage Guidelines)和Michael Jurewitz的評論裡已講的很清楚了。

其他開發文檔裡也明確的指出Application Support 目錄內的檔案也會被iTunes備份(假設iCloud也會)。在討論中有些開發人員認為Application Support 目錄內儲存檔案相比Caches 目錄更安全點(更加持久)。我覺得應用審核部門會拒掉那些在Application Support 目錄內儲存大量資料的應用,這和Document 目錄內的嚴格審核是一樣的,都是拜iCloud的儲存空間不足所賜。

 

還有些什麼值得注意的?

再也沒有一個目錄可以讓你的應用儲存檔案於其中並可以:

  1. 不被iTunes或者iCloud備份
  2. 不會因空間受限而被清除

很明顯在iOS 5.0上想做到這些已經遲了。但是如果足夠多的開發人員據理力爭,讓蘋果知道他們非常需要在自己的應用內保持這個功能,或許下個版本會加入進來。提示:提交檔案bug 報告。

 

開發人員要做些什嗎?

如果你當前正在Documents 目錄內儲存檔案的話

你的應用當然可以繼續在iOS 5內正常工作,你的使用者可能會抱怨有大量的資料被備份到了iCloud上。(詳見以下內容)

然而當你更新你的應用時,可能會因為在Documents目錄內儲存太多資料而被拒絕通過審核。

如果你正在或者考慮到在Caches 目錄內儲存檔案的話

請確保在Caches 目錄內你儲存的檔案忽然消失的情況下,你的應用依然可以處理妥當。一種處理的方法是,把儲存在Caches目錄內的所有檔案的源URL(原始路徑或地址)列入進一個清單裡。這樣應用通過遍曆清單就可以驗證檔案是否依然存在了。

如果有任何檔案消失了你可以顯示對話方塊向使用者致歉,解釋清原因並詢問是否要重新下載檔案。假如裝置是離線的,你只能對使用者致歉然後告訴使用者“你完了”。

還有許多比這兩種更複雜的情況,例如:分裝的資料哪些還能使用。你需要決定顯示哪些資料,顯示多少等。

一名開發人員在蘋果論壇上講的使用者使用案例,我覺得很有趣:他的應用是為飛行員顯示地圖的。 如果他把可以重新下載的地圖放到Caches 目錄內,那麼如果地圖資料被iOS 5突然刪掉,這時飛機還在天上,可能就悲劇了。讓飛行員重新下載地圖資料的對話方塊絕對會深深地傷害到他的感情。

遷移已存在的資料

如果你服從 iOS 5或iCloud的新規則去更新應用並把檔案儲存到Caches 目錄內的話,那麼你可能需要把已存放在Document 內的檔案轉移到 Caches 內。我確信應用審核部分不會去測試這個,因為他們沒有你存有資料的老版本應用。但是這樣做很對。

記住不要在應用程式啟動時的主線程中消耗太多的資源來進行檔案轉移。這樣會使你的應用被啟動時間監視程式Kill掉。

提前警告

當應用在運行時,如果裝置正處於空間不足的情況下,你可以告知使用者。雖然這樣不能阻止檔案被刪掉,但至少可以讓使用者認識到這個問題的存在。

我不清楚在iOS 5的清除程式運行前,磁碟空間的最低值是多少,並且我也懷疑蘋果會給出具體細節。如果你有任何自己實驗出的結果請務必在下面添加評論指出。

讓蘋果意識到這是個很大的問題

提交檔案bug 報告(File a bug report)。

 

使用者能做什嗎?

一直到現在,那些儲存許多資料在目錄內的應用對於備份來說很頭疼,因為iTunes備份它們要花很長的時間。當有許多的檔案必須備份時,這種情況尤其惱人。

通過iCloud備份的話,使用者們可能不想佔用他們那可憐的5GB儲存空間(或是花錢購買額外空間)來備份那些他們認為不重要的資料。單個的應用可 以關掉iCloud備份。在應用設定中能很容易的找到設定:iCloud > 儲存與備份>管理儲存空間>備份。在備份選項列表裡每一個應用都可以選擇是否備份。可能你的使用者不太容易能找出設定,你可能需要發郵件去指導 他們。

這些是我的理解,儘管我還沒來得及測試關掉iCloud備份對iTunes的備份是否有影響。但是對於那些再也不用資料線串連電腦來同步的使用者,按上述說明關掉iCloud備份的應用是沒有備份資料的。

 

以下函數可使某個路徑的檔案免於iCloud備份

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    if (&NSURLIsExcludedFromBackupKey == nil) { // iOS <= 5.0.1
        const char* filePath = [[URL path] fileSystemRepresentation];

        const char* attrName = "com.apple.MobileBackup";
        u_int8_t attrValue = 1;

        int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
        return result == 0;
    } else { // iOS >= 5.1


        NSLog(@"%d",[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil]);
        return [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
    }
}


我的經驗:當應用程式曝出如下錯誤資訊時,你的Caches檔案夾下的內容可能就被自動刪除了。
//空間不足時malloc: stack logs being written into /private/var/mobile/Containers/Data/Application/819156CF-C8B8-43FF-BF63-0EABF59CB655/tmp/stack-logs.1373.15a3000.esvideo.aQPqEl.indexesvideo(1373,0x39c8a9dc) malloc: recording malloc and VM allocation stacks to disk using standard recorderesvideo(1373,0x39c8a9dc) malloc: process 1338 no longer exists, stack logs deleted from /private/var/mobile/Containers/Data/Application/819156CF-C8B8-43FF-BF63-0EABF59CB655/tmp/stack-logs.1338.1508000.esvideo.tYs7hy.index2015-08-19 15:22:47.000 esvideo[1373:382143] iRate verbose logging enabled.

//空間不足時,應用程式奔潰malloc: Unable to write to stack logging file /private/var/mobile/Containers/Data/Application/F20F8C6C-9709-490A-9DDA-E294C1EF3B50/tmp/stack-logs.1234.1549000.esvideo.mNh6B0.index (No space left on device)esvideo(1234,0x39c8a9dc) malloc: stack logging disabled due to previous errors.2015-08-19 14:57:06.950 esvideo[1234:373855] Unable to copy temp file. Error: Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x19e68e10 {NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/Application/F20F8C6C-9709-490A-9DDA-E294C1EF3B50/Library/Caches/com.apple.nsurlsessiond/Downloads/com.easou.esvideo/CFNetworkDownload_BHOOzH.tmp, NSUserStringVariant=(    Copy), NSFilePath=/private/var/mobile/Containers/Data/Application/F20F8C6C-9709-490A-9DDA-E294C1EF3B50/Library/Caches/com.apple.nsurlsessiond/Downloads/com.easou.esvideo/CFNetworkDownload_BHOOzH.tmp, NSDestinationFilePath=/var/mobile/Containers/Data/Application/F20F8C6C-9709-490A-9DDA-E294C1EF3B50/Library/Caches/DownLoad/Video/火影忍者605_554cd72c0cf29e8153e068a6/火影忍者605_554cd72c0cf29e8153e068a6_0, NSUnderlyingError=0x19e69b50 "The operation couldn’t be completed. Result too large"}

 

 

 





iOS5可能會刪除本地檔案儲存 - Caches 也不安全

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.