轉自:http://blog.163.com/ray_jun/blog/static/1670536422011101225132544/html
出處:http://superman474.blog.163.com/blog/static/120661462011101115811199/ios
關於iOS 5的本地文件儲存Marco(Instapaper 的開發者)寫過一篇很好的帖子闡述過相關問題,有興趣的同窗能夠先閱讀下他的文章而後再看下文。web
在蘋果開發者的論壇上也有許多相關問題的討論貼:數據庫
安全地保存文件?緩存
若是我想讓文件永久保存且不會和iTunes同步,我該把文件保存在哪裏?網絡
iCloud 的雲備份佔用了巨大的空間?session
幾點困惑app
在蘋果開發者論壇的討論中,總結出如下幾點使人困惑的問題:ide
下面讓咱們逐個討論:
關於緩存和臨時文件目錄的含義
若是你有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)的說明:
「爲了盡力確保文件備份高效,請務必根據如下的指導來保存你的應用數據:
一、只有那些用戶生成的文檔和其餘數據或者是那些不能被你的應用所重建的數據應當保存在<Application_Home>/Documents 目錄內。這些數據文件將會自動的經過iCloud備份。
二、那些能夠從新下載或者從新建立的數據應當保存在<Application_Home>/Library/Caches 目錄內。你能夠把數據庫緩存文件或者可下載的內容如雜誌、報紙、地圖應用的數據等放入緩存目錄裏(Caches directory)
三、臨時須要的數據應該保存在<Application_Home>/tmp 目錄內。儘管這些文件不會備份到iCloud裏,請記住在你再也不須要它們時當即刪除掉這些文件,這樣它們就不會繼續浪費用戶設備的儲存空間了。」
事實上許多報紙、雜誌和地圖的應用單純的目的就是想離線顯示內容,若是咱們暫時無視這點,那麼以上的指導講的很清楚,能夠去參考。
應用審覈被拒
開發者目前報告說那些在Document 目錄內保存任意/少許/大量數據的應用正在審覈中被拒。
應用審覈部門不太可能面面俱到,好比理清楚哪些文件該儲存到哪些目錄內、哪些文件是用戶生成的、哪些數據是能夠從新下載或從新被建立的。有些開發者報告中說,他們跟應用審覈部門解釋清楚應用是如何保存數據、如何遵照指導原則的,以後他們的應用也獲得了經過。
iTunes和iCloud會備份哪些文件
應用裏home 目錄內的全部數據都會被備份除了:
這些在iOS數據儲存指導手冊上(iOS Data Storage Guidelines)和Michael Jurewitz的評論裏已講的很清楚了。
其餘開發文檔裏也明確的指出Application Support 目錄內的文件也會被iTunes備份(假設iCloud也會)。在討論中有些開發者認爲Application Support 目錄內保存文件相比Caches 目錄更安全點(更加持久)。我以爲應用審覈部門會拒掉那些在Application Support 目錄內保存大量數據的應用,這和Document 目錄內的嚴格審覈是同樣的,都是拜iCloud的儲存空間不足所賜。
還有些什麼值得注意的?
再也沒有一個目錄可讓你的應用保存文件於其中並能夠:
很明顯在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.index esvideo(1373,0x39c8a9dc) malloc: recording malloc and VM allocation stacks to disk using standard recorder esvideo(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.index 2015-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"}
關於Caches的官方描述:
tmp: Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when it determines they are no longer needed. Caches: Use this directory to write any app-specific support files that your app can re-create easily. Your app is generally responsible for managing the contents of this directory and for adding and deleting files as needed. In iOS 2.2 and later, the contents of this directory are not backed up by iTunes. In addition, iTunes removes files in this directory during a full restoration of the device. On iOS 5.0 and later, the system may delete the Caches directory on rare occasions when the system is very low on disk space. This will never occur while an app is running. However, you should be aware that iTunes restore is not necessarily the only condition under which the Caches directory can be erased.
轉自:http://my.oschina.net/u/1266799/blog/165631
有這樣一個問題,用戶用iOS設備下載了大量的數據,保存在設備本地,若是用戶升級了應用自己,這些文件是否仍然存在。
找了一些官方解釋和Stackflow上的說明
To prevent the syncing and backup processes on iOS devices from taking a long time, be selective about where you place files inside your app’s home directory. Apps that store large files can slow down the process of backing up to iTunes or iCloud. These apps can also consume a large amount of a user's available storage, which may encourage the user to delete the app or disable backup of that app's data to iCloud. With this in mind, you should store app data according to the following guidelines:
Put user data in the <Application_Home>/Documents/. User data is any data that cannot be recreated by your app, such as user documents and other user-generated content.
Handle support files—files your application downloads or generates and can recreate as needed—in one of two ways:
In iOS 5.0 and earlier, put support files in the <Application_Home>/Library/Caches directory to prevent them from being backed up
In iOS 5.0.1 and later, put support files in the <Application_Home>/Library/Application Support directory and apply thecom.apple.MobileBackup extended attribute to them. This attribute prevents the files from being backed up to iTunes or iCloud. If you have a large number of support files, you may store them in a custom subdirectory and apply the extended attribute to just the directory.
Put data cache files in the <Application_Home>/Library/Caches directory. Examples of files you should put in this directory include (but are not limited to) database cache files and downloadable content, such as that used by magazine, newspaper, and map apps. Your app should be able to gracefully handle situations where cached data is deleted by the system to free up disk space.
Put temporary data in the <Application_Home>/tmp directory. Temporary data comprises any data that you do not need to persist for an extended period of time. Remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device.
也就是說,通常從網上下載的那些內容,包括雜誌、報紙、視頻什麼的,都要放在 <Application_Home> /Library/Caches 目錄下面
<Application_Home>/Library/ |
This directory is the top-level directory for files that are not user data files. You typically put files in one of several standard subdirectories but you can also create custom subdirectories for files you want backed up but not exposed to the user. You should not use this directory for user data files. The contents of this directory (with the exception of the Caches subdirectory) are backed up by iTunes. For additional information about the Library directory, see 「The Library Directory Stores App-Specific Files.」 |
Library目錄下面的內容,也會被被iTunes備份,可是Caches目錄除外,也就是說這些網絡下載內容文件放在這裏是不會被備份的,
Caches |
Use this directory to write any app-specific support files that your app can re-create easily. Your app is generally responsible for managing the contents of this directory and for adding and deleting files as needed. In iOS 2.2 and later, the contents of this directory are not backed up by iTunes. In addition, iTunes removes files in this directory during a full restoration of the device. On iOS 5.0 and later, the system may delete the Caches directory on rare occasions when the system is very low on disk space. This will never occur while an app is running. However, you should be aware that iTunes restore is not necessarily the only condition under which the Caches directory can be erased. |
上面寫的的比較清楚,Library/Caches目錄下,通常狀況下是不會被刪除的,我理解,也包括stackoverflow網友的證實,應用升級的時候也不會被刪除,實際上,應用升級的具體系統操做是這樣的:
Files Saved During Application Updates When a user downloads an application update, iTunes installs the update in a new application directory. It then moves the user’s data files from the old installation over to the new application directory before deleting the old installation. Files in the following directories are guaranteed to be preserved during the update process:
Although files in other user directories may also be moved over, you should not rely on them being present after an update.
系統先新建一個應用目錄,而後安裝一個新版本應用,而後再把舊版本的應用數據拷貝過來,而後再刪除舊版本的應用安裝目錄。
最後注意一下,Library/Caches目錄下的數據雖然在通常狀況下不會被刪除,可是在系統恢復和其餘一些罕見的狀況下(好比很是底的磁盤空間條件下有可能)會被清除,因此你的程序每次都要檢查一些,這些文件都還在不在了,不在的話只能從新下了。
Application_Home/Library/Caches Use this directory to write any application-specific support files that you want to persist between launches of the application or during application updates. Your application is generally responsible for adding and removing these files. It should also be able to re-create these files as needed because iTunes removes them during a full restoration of the device. In iOS 2.2 and later, the contents of this directory are not backed up by iTunes.
參考鏈接:http://stackoverflow.com/questions/7155964/will-application-home-library-caches-be-clear-on-app-update/7277797#7277797
File System Programming Guide
https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW1