iCloud官方文档
官方地址:
iOS App Programming Guide ->?iCloud Storage
這個(gè)偏理論一些,提供了很多iCloud應(yīng)用設(shè)計(jì)層面的東西,大家感興趣,可以一看。
如果需要iCloud上手教程,可以參考我的另外一個(gè)貼子:http://www.cocoachina.com/bbs/read.php?tid=86246
-----------------------------------------------------------------------------------------------------------------------------
iCloud支持兩種應(yīng)用存儲:
- document storage:存儲用戶文檔和應(yīng)用數(shù)據(jù)到用戶的iCloud賬戶
- key-value data storage:分享小量的非關(guān)鍵配置數(shù)據(jù)到應(yīng)用的多個(gè)實(shí)例
iCloud App的設(shè)計(jì)考慮
首 先需要確認(rèn)的是采用document storage還是key-value data storage。document storage用于存儲應(yīng)用數(shù)據(jù),要么是應(yīng)用創(chuàng)建并私有管理的數(shù)據(jù),要么是用戶創(chuàng)建的數(shù)據(jù)。所有用戶面對的數(shù)據(jù)都應(yīng)該是document storage,例如用戶創(chuàng)建的文檔。key-value data storage主要用于非關(guān)鍵的配置數(shù)據(jù),你希望在多個(gè)app實(shí)例中共享,例如應(yīng)用使用的參數(shù)和配置信息(典型的例子如Newsstand應(yīng)用中用戶上一次閱讀的刊物和閱讀位置)。
document storage 和 key-value data storage的區(qū)別:
| 屬性 | Document Storage | Key-Value storage |
| 管理的數(shù)據(jù)類型? | 文件和目錄 | 只能是Property-list數(shù)據(jù) |
| 什么時(shí)候應(yīng)該使用? | 使用Document Storage來管理應(yīng)用的關(guān)鍵數(shù)據(jù)。與應(yīng)用main data model直接相關(guān)的文件和數(shù)據(jù),總是應(yīng)該使用Document Storage。如用戶文檔、私有的app數(shù)據(jù)文件、以及應(yīng)用或用戶生成的數(shù)據(jù)文件 | 參數(shù)或其它配置數(shù)據(jù),如果需要在多個(gè)app實(shí)例之間共享,并且不是關(guān)鍵數(shù)據(jù),就可以使用key-vlaue storage。只能存儲property list數(shù)據(jù),并且容量有限。 |
| 是否需要file presenter和file coordinator | 是 | 否 |
| 怎樣定位數(shù)據(jù)? | 使用?NSMetadataQuery 對象來查找文件 | 使用默認(rèn)的?NSUbiquitousKeyValueStore 對象來獲取已知key對應(yīng)的值 |
| 如何管理數(shù)據(jù)? | 使用NSFileManager類來管理文件和目錄。使用標(biāo)準(zhǔn)文件系統(tǒng)函數(shù)來打開、關(guān)閉、讀取和寫入文件 | 使用默認(rèn)的NSUbiquitousKeyValueStore 對象來獲取和設(shè)置key和value |
| 能存儲多少數(shù)據(jù)? | 只受用戶iCloud賬戶的空間限制 | 限制為64KB(單個(gè)key也限制為64KB) |
| 怎樣處理沖突? | 應(yīng)用的?file presenters 必須手工解決沖突 | 最后設(shè)置的值總是當(dāng)前值。設(shè)備提供的時(shí)間戳用于確定最新的值 |
| 要求設(shè)置哪個(gè)entitlement? | com.apple.developer.ubiquity-container-identifiers | com.apple.developer.ubiquity-kvstore-identifier |
| 數(shù)據(jù)什么時(shí)候同步? | 設(shè)備端發(fā)生變化時(shí),iCloud總是會拉取文件元數(shù)據(jù)和數(shù)據(jù);設(shè)備總是會拉取文件元數(shù)據(jù),但是直到應(yīng)用試圖使用文件時(shí)才會拉取文件數(shù)據(jù) | 定期在設(shè)備和iCloud之間傳輸key-value數(shù)據(jù) |
| 怎樣在運(yùn)行時(shí)檢查iCloud可用? | 對某個(gè)你已經(jīng)注冊的容器目錄調(diào)用 URLForUbiquityContainerIdentifier: 方法,如果方法返回nil,表示document storage不可用 | 調(diào)用 NSUbiquitousKeyValueStore 的?synchronize 方法,如果返回YES,iCloud可用,并且有修改同步到本地用戶默認(rèn)數(shù)據(jù)庫;如果返回NO,iCloud要么不可用,要么沒有變化需要同步。無論如何,都可以直接使用本地的用戶默認(rèn)數(shù)據(jù)庫。 |
| 系統(tǒng)提供了什么用戶界面支持? | 沒有,應(yīng)用負(fù)責(zé)提供支持iCloud的信息和界面。 | 沒有,多數(shù)情況下,你不應(yīng)該讓用戶知道key-value數(shù)據(jù)存儲在本地還是iCloud中。 |
另一個(gè)設(shè)計(jì)考慮是應(yīng)用的用戶界面如何整合iCloud支持。特別是文檔,有時(shí)候你需要提醒用戶文檔的狀態(tài),比如是否已經(jīng)下載、版本沖突需要解決等。一般都需要在界面上增加一些不引人注目的元素,以在適當(dāng)?shù)臅r(shí)候提示用戶。
配置應(yīng)用的iCloud Entitlements
使用iCloud的應(yīng)用必須以iCloud特定的Entitlements簽名。這些entitlements為應(yīng)用提供一層安全性,確保只有你的應(yīng)用才能訪問自己創(chuàng)建的文檔。系統(tǒng)也依賴于你提供的Entitlement值來區(qū)分用戶iCloud賬戶中你的應(yīng)用與其它應(yīng)用的文檔。
Xcode中啟用iCloud Entitlements:
當(dāng) 你啟用App target的Entitlements時(shí),Xcode自動為你的應(yīng)用配置了document storage和key-value data storage。每個(gè)Entitlement包含一個(gè)key,是一個(gè)或多個(gè)容器標(biāo)識字符串。容器標(biāo)識字符串標(biāo)識了iCloud中的一個(gè)容器目錄,你用來存儲應(yīng)用的文件。
Xcode按以下方式來配置Entitlements:
- iCloud容器域標(biāo)識了應(yīng)用在用戶iCloud存 儲中能夠訪問的容器目錄(這個(gè)域?qū)?yīng)于com.apple.developer.ubiquity-container-identifiers)。你添 加到這個(gè)列表的字符串必須匹配你的團(tuán)隊(duì)創(chuàng)建的應(yīng)用bundle ID。Xcode使用當(dāng)前app的bundle ID來指定第一個(gè)字符串,如果你希望多個(gè)app共享一個(gè)main容器目錄,你可以修改為不同的bundle ID。你還可以為團(tuán)隊(duì)的其它應(yīng)用添加額外的bundle ID(第一個(gè)字符串必須不包含任何通配符,隨后的字符串則可以包含通配符)
- iCloud的key-value存儲域包含應(yīng)用存儲到iCloud的key-value data storage的單個(gè)容器標(biāo)識字符串(對應(yīng)于?com.apple.developer.ubiquity-kvstore-identifier)
你 在Xcode中設(shè)置的bundle ID并不是完整限定的容器標(biāo)識字符串。完整限定的容器標(biāo)識的格式 是:?<TEAM_ID>.<BUNDLE_IDENTIFIER>,其中<TEAM_ID>是10個(gè)字符的團(tuán)隊(duì)標(biāo) 識;<BUNDLE_IDENTIFIER> 則是iCloud容器域中的某個(gè)bundle ID。當(dāng)在代碼中獲取某個(gè)容器目錄的URL時(shí),你需要傳遞完整限定的字符串給?URLForUbiquityContainerIdentifier: 方法。不過你也可以傳遞nil,來獲取列表中的第一個(gè)容器目錄的URL
通過在Entitlements中指定多個(gè)容器標(biāo)識,使用iCloud document storage的應(yīng)用可以讀取和寫入內(nèi)容到多個(gè)容器目錄。iCloud容器域允許你指定多個(gè)字符串。第一個(gè)字符串是應(yīng)用的main容器標(biāo)識,任何額外的字符串則代表你其它應(yīng)用的容器標(biāo)識。查找時(shí)會返回所有可用容器目錄中的所有文件。
使用iCloud Document Storage
iCloud Document Storage讓你將文件和目錄移動到用戶的iCloud賬戶,并在那里管理這些文件。在某個(gè)設(shè)備上修改文件或目錄,會先存儲在本地,然后再通過本地daemon進(jìn)程push到iCloud。文件傳輸對應(yīng)用是透明的,因此應(yīng)用只需直接操作文件。
設(shè)計(jì)應(yīng)用使用iCloud Document Storage,需要一些重大的應(yīng)用修改,主要包括:
- 應(yīng)用執(zhí)行的早期,調(diào)用?URLForUbiquityContainerIdentifier: 方法檢查iCloud是否啟用。擴(kuò)展應(yīng)用Sandbox來包含應(yīng)用請求的每個(gè)容器目錄,也需要調(diào)用這個(gè)方法。
- 顯式地整合 file presenters(如UIDocument類)到應(yīng)用的數(shù)據(jù)層
- 顯式地移動文件到iCloud
- 準(zhǔn)備好處理版本沖突
- 使用查找來定位iCloud中的文件
- 處理文件在iCloud中,但是沒有完全下載到本地設(shè)備的情況;可能需要向用戶提供及時(shí)的反饋
- 如果要在iCloud中存儲live database,使用Core Data,不要使用SQLite
- 如果應(yīng)用還有Mac OS X版本,為所有應(yīng)用使用通用文檔格式
App支持iCloud的大部分工作都在數(shù)據(jù)層。與iCloud的交互也主要是應(yīng)用要存儲使用的文件和目錄。不過底層數(shù)據(jù)變化時(shí),用戶界面也需要一定的修改,以通知用戶相關(guān)的狀態(tài)。當(dāng)然,應(yīng)用應(yīng)該盡可能地讓用戶無需關(guān)心本地還是iCloud存儲。
檢查iCloud Document Storage是否可用
每個(gè)Apple ID用戶都有一個(gè)免費(fèi)的iCloud賬戶,但是用戶可能禁用某個(gè)設(shè)備的iCloud。因此使用iCloud接口之前,必須先調(diào)用?URLForUbiquityContainerIdentifier: 方法檢確定iCloud是否可用。返回nil表示不可用,返回URL表示可用
第一次對指定的容器目錄調(diào)用?URLForUbiquityContainerIdentifier: 方法,iOS會擴(kuò)展應(yīng)用Sandbox來包含該容器目錄。因此需要至少成功調(diào)用一次該方法,以確保iCloud可用,main容器目錄也可以訪問。
整合 File Presenters 到應(yīng)用
iCloud中存儲的所有文件和目錄都由file presenter對象管理;你對這些文件和目錄的修改都必須通過一個(gè)file coordinator對象。
file presenter實(shí)現(xiàn)了?NSFilePresenter 協(xié)議,主要的職責(zé)是作為特定文件或目錄的響應(yīng)代理。在外部源能夠修改一個(gè)文件之前,注冊的file presenter會得到通知,并有機(jī)會執(zhí)行任何必要的簿記(bookkeeping)工作。
當(dāng)應(yīng)用想要修改一個(gè)文件時(shí),它必須通過一個(gè) NSFileCoordinator 對象來執(zhí)行修改,本質(zhì)上會鎖住文件。file coordinator 阻止外部源修改文件,并且遞送相關(guān)的通知給其它 file presenters。
整 合 file presenter 到應(yīng)用最簡單的方法是使用 UIDocument 類。這個(gè)類實(shí)現(xiàn)了 NSFilePresenter 協(xié)議,并為你處理了所有文件相關(guān)的管理。應(yīng)用唯一需要做的事情,就是在得到通知時(shí),讀取和寫入文檔數(shù)據(jù)。不管是用戶生成內(nèi)容的文件(因此直接顯示給用戶),還是應(yīng)用替用戶創(chuàng)建的文件(無需用戶交互),都可以使用UIDocument。
操作iCloud中的文件和目錄
iCloud文件和目錄和本地文件目錄一樣,應(yīng)用使用相同的技術(shù)來管理文件和目錄。你可以打開、創(chuàng)建、移動、復(fù)制、讀取、寫入、刪除、以及其它操作。本地文件目錄和iCloud文件目錄的唯一區(qū)別是訪問的URL不同。本地文件目錄的URL相對于應(yīng)用Sandbox,而iCloud文件目錄的URL則相對于相應(yīng)的iCloud容器目錄。
要移動一個(gè)文件或目錄到iCloud:
移動一個(gè)文件或目錄到iCloud時(shí),系統(tǒng)從應(yīng)用Sandbox中復(fù)制該item到private本地存儲,這樣才能被iCloud daemon監(jiān)測到。盡管文件此時(shí)已經(jīng)不在應(yīng)用Sandbox中,應(yīng)用仍然對其擁有完全訪問。雖然文件仍然有一份拷貝保留在當(dāng)前設(shè)備的本地,文件同時(shí)還發(fā)送到了iCloud,這樣就能分布到其它設(shè)備去。iCloud daemon處理了所有工作,確保本地拷貝與iCloud是相同的。因此從應(yīng)用的角度來說,文件就是在iCloud中。
你對iCloud中的文件和目錄的所有修改都需要使用一個(gè) file coordinator 對象。包括移動、刪除、復(fù)制、重命名等操作。file coordinator確保iCloud daemon不會同時(shí)修改文件或目錄,并確保你修改時(shí)能夠及時(shí)地通知其它人。
命名文件和目錄時(shí),盡量使用字母數(shù)字,避免使用特殊標(biāo)點(diǎn)和其它特殊字符。同時(shí)你還應(yīng)該假設(shè)文件名是大小寫不敏感的(因?yàn)?span style="text-decoration:underline;">iCloud支持Windows)。最后盡量保持文件名簡單,以確保這些文件能夠在不同文件系統(tǒng)中正確地處理。
選擇一種響應(yīng)版本沖突的策略
iCloud文件的版本沖突不可避免,因此應(yīng)用必須對沖突采取一種解決策略。當(dāng)應(yīng)用的兩個(gè)實(shí)例同時(shí)修改一個(gè)文件并傳輸給iCloud時(shí)就會發(fā)生沖突。iCloud會保存所有沖突的版本,并通知應(yīng)用的file presenter發(fā)生了沖突需要解決。
App應(yīng)該盡快地嘗試解決版本沖突,當(dāng)沖突發(fā)生時(shí),其中一個(gè)文件被指定為current file,其它所有版本都是沖突版本。當(dāng)前文件和沖突版本文件都由 NSFileVersion 對象來管理,可以通過類方法來獲取。
解決沖突:
更新當(dāng)前文件:
設(shè)置所有沖突版本對象的 resolved 屬性為YES。設(shè)置這個(gè)屬性會導(dǎo)致沖突版本對象(及相應(yīng)的文件)從用戶的iCloud storage中刪除。如果使用UIDocument類,你通過 observing 文檔狀態(tài)變化通知,并檢查??documentState 屬性來判斷是否發(fā)生沖突
如果使用自定義 file presenter,每當(dāng)報(bào)告有一個(gè)新版本時(shí),你都應(yīng)該檢查它是否沖突版本。
整合查找(Search)到應(yīng)用基礎(chǔ)架構(gòu)
和應(yīng)用Sandbox不同,iCloud中的文件添加和刪除,你的應(yīng)用可能都不會直接知道。在這臺設(shè)備上創(chuàng)建的文件,最終會出現(xiàn)在另一臺設(shè)備中。如果應(yīng)用不主動查找文件,那就不能及時(shí)地出現(xiàn)在用戶界面中。因此應(yīng)用需要使用 NSMetadataQuery 對象來查找iCloud容器目錄中的文件或目錄。
當(dāng)應(yīng)用在前臺時(shí),你可以保留一個(gè)?metadata query 一直運(yùn)行,來接收文件添加或刪除的通知;應(yīng)用進(jìn)入后臺時(shí),就停止這個(gè)?metadata query 查詢。
只有 iCloud 啟用,并且相應(yīng)的容器目錄已經(jīng)創(chuàng)建時(shí),metadata查詢才會有返回結(jié)果。在運(yùn)行時(shí),確保使用?URLForUbiquityContainerIdentifier: 方法來檢測iCloud已經(jīng)啟用,而且應(yīng)用支持的容器目錄也可用。這個(gè)方法在容器目錄不存在時(shí),會自動創(chuàng)建出來。
Metadata 查找應(yīng)用entitlement中設(shè)置的所有容器目錄,并返回合并后的所有結(jié)果。如果你希望只查找一個(gè)容器目錄,可以使 用?URLForUbiquityContainerIdentifier: 方法來獲得該容器目錄的URL,然后使用?NSFileManager 類來獲取目錄內(nèi)容的靜態(tài)列表。
確定文件或目錄的傳輸狀態(tài)
你寫到iCloud容器目錄的item會盡可能快地自動傳輸?shù)?span style="text-decoration:underline;">iCloud服務(wù)器。但是由于網(wǎng)絡(luò)和設(shè)備類型的原因,文件或目錄可能不會立即下載到設(shè)備或上傳到服務(wù)器。如果你需要確定文件的狀態(tài),可以使用 NSURL 的 getResourceValue:forKey:error: 方法,來獲取以下屬性的值:
- NSURLIsUbiquitousItemKey:表示item是否存儲在iCloud
- NSURLUbiquitousItemIsDownloadedKey:表示當(dāng)前版本是否已經(jīng)下載并且可訪問
- NSURLUbiquitousItemIsDownloadingKey:表示當(dāng)前版本是否正在下載并且暫時(shí)不可用
- NSURLUbiquitousItemPercentDownloadedKey:對于正在下載的item,表示已經(jīng)下載的修改的百分比??梢允褂眠@個(gè)值來更新進(jìn)度條。
- NSURLUbiquitousItemIsUploadedKey:表示本地的修改是否成功上傳到iCloud服務(wù)器
- NSURLUbiquitousItemIsUploadingKey:表示本地的修改是否正在上傳到服務(wù)器
- NSURLUbiquitousItemPercentUploadedKey:對于正在上傳的item,表示當(dāng)前已經(jīng)上傳的修改的百分比
雖然iCloud服 務(wù)器會非常努力地拉取應(yīng)用在本地做的修改,但是iOS設(shè)備通常卻不會主動從服務(wù)器拉取修改,除非你試圖訪問該文件。如果你試圖打開一個(gè)正在下載的文 件,iOS會阻塞發(fā)起打開請求的線程,直到文件被完全下載并且可用。因此如果你擔(dān)心潛在的延遲,就根據(jù)需要檢查文件的當(dāng)前狀態(tài),同時(shí)更新用戶界面,提示用 戶當(dāng)前文件正在下載,暫時(shí)不可用。
使用尚未下載完成的文件
iCloud中的文件發(fā)生改變時(shí),iOS設(shè)備不會自動下載這些修改數(shù)據(jù)。相反iOS設(shè)備會下載文件的元數(shù)據(jù),因此知道此時(shí)文件已經(jīng)有修改。實(shí)際修改的數(shù)據(jù)只有以下情況發(fā)生時(shí),才會被下載:
- 應(yīng)用試圖打開或訪問文件
- 應(yīng)用調(diào)用?startDownloadingUbiquitousItemAtURL:error: 方法,顯式地下載文件修改
如果應(yīng)用打開尚未下載完成的文件,用于打開文件的 file coordinator 會阻塞你的應(yīng)用,直到文件或修改被完全下載。如果文件或修改比較大,可能會導(dǎo)致很差的用戶體驗(yàn),因此試圖打開一個(gè)文件之前,應(yīng)該首先檢查文件的下載狀態(tài)。NSURL 類定義了iCloud item相關(guān)的屬性,可以檢查iCloud文件的狀態(tài)
檢查文件是否已經(jīng)下載完成:
- (BOOL)downloadFileIfNotAvailable:(NSURL*)file {
? ?NSNumber* ?isIniCloud = nil;
? ?if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {
? ? ? // If the item is in iCloud, see if it is downloaded.
? ? ? if ([isIniCloud boolValue]) {
? ? ? ? ?NSNumber* ?isDownloaded = nil;
? ? ? ? ?if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) {
? ? ? ? ? ? if ([isDownloaded boolValue])
? ? ? ? ? ? ? ?return YES;
? ? ? ? ? ? // Download the file.
? ? ? ? ? ? NSFileManager* ?fm = [NSFileManager defaultManager];
? ? ? ? ? ? [fm startDownloadingUbiquitousItemAtURL:file error:nil];
? ? ? ? ? ? return NO;
? ? ? ? ?}
? ? ? }
? ?}
? ? // Return YES as long as an explicit download was not started.
? ? return YES;
}
為iCloud調(diào)整用戶界面
所有為了iCloud所做的用戶界面調(diào)整,都應(yīng)該盡量不引人注意。當(dāng)iCloud不可用時(shí),你存儲在iCloud中的文檔和你存儲在本地是完全一樣的。唯一的區(qū)別是文件系統(tǒng)中的位置。因此大部分用戶界面都應(yīng)該保持一致。
以下情況可能需要針對iCloud修改用戶界面:
- 當(dāng)用戶生成的文檔在使用之前必須被下載。只有你提供了文檔瀏覽器,才需要讓用戶來控制是否下載文檔。應(yīng)用使用的私有文件,應(yīng)該在不可用時(shí)自動去服務(wù)器下載。你用來提示用戶的信息應(yīng)該盡量友好,并提供用戶“開始文檔下載”的選項(xiàng)。如果下載時(shí)間可能超過幾秒鐘,你需要顯示一個(gè)當(dāng)前下載進(jìn)度。
- 當(dāng)出現(xiàn)必須由用戶解決的版本沖突。如果應(yīng)用需要用戶協(xié)助,才能解決沖突,就應(yīng)該友好地提示沖突信息,但千萬不要顯示警告,或其它任何破壞性的界面。
- 當(dāng)你希望提供用戶選項(xiàng),為應(yīng)用啟用或禁用iCloud時(shí)。如果應(yīng)用包含一個(gè)Settings Bundle或者內(nèi)部的參數(shù)設(shè)置,你可以提供一個(gè)參數(shù),讓用戶選擇是否使用iCloud。
iCloud結(jié)合Database使用
只有應(yīng)用使用Core Data來管理數(shù)據(jù)庫時(shí),才能將SQLite數(shù)據(jù)庫整合到iCloud。不支持使用SQLite接口訪問iCloud中的live數(shù)據(jù)庫,這樣做很可能會毀壞你的數(shù)據(jù)庫。
但是只要你遵守一些額外的步驟,來設(shè)置Core Data結(jié)構(gòu),你就可以創(chuàng)建基于SQLite的Core Data,從而啟用iCloud支持。當(dāng)然,其它類型的Core Data Store(不基于SQLite),則無需修改可以直接支持iCloud。
使用Core Data和SQLite store時(shí),實(shí)際的數(shù)據(jù)庫文件不會傳輸?shù)?span style="text-decoration:underline;">iCloud服務(wù)器。相反,每個(gè)設(shè)備都維護(hù)自己的SQLite store拷貝,并通過將修改寫入到日志文件來同步它的內(nèi)容。設(shè)備與iCloud之間真正傳輸?shù)氖莑og file,在每個(gè)設(shè)備中,Core Data拿到log file的內(nèi)容,然后使用這些內(nèi)容來更新本地?cái)?shù)據(jù)庫。當(dāng)然最終的效果就是每個(gè)本地?cái)?shù)據(jù)庫都擁有完全相同的修改。
設(shè)置Core Data store來處理iCloud,只需要你執(zhí)行很少的額外工作。但是具體的步驟取決于你使用Core Data store作為中央庫(Central Library),還是為單個(gè)文檔分別創(chuàng)建獨(dú)立的Core Data Store。
使用Core Data管理文檔
應(yīng) 用管理Core Data store為單獨(dú)的文檔時(shí),可使用?UIManagedDocument 對象來管理單個(gè)文檔。UIManagedDocument 類自動在應(yīng)用bundle中查找所有managed object model,并使用它們作為文檔數(shù)據(jù)的基礎(chǔ)(你也可以覆蓋 managedObjectModel 屬性自定義指定子類的object models)。由于大部分?jǐn)?shù)據(jù)由managed object context處理,意味著你通常可以直接使用 UIManagedDocument 類而不需要繼承子類。UIDocumemnt的自動保存行為,能夠自動處理所有文檔的保存工作。
創(chuàng)建新文檔時(shí),執(zhí)行以下步驟:
當(dāng) 你創(chuàng)建一個(gè)新文檔時(shí),Core Data創(chuàng)建一個(gè)file package,包含文檔的內(nèi)容。這些內(nèi)容有一個(gè)?DocumentMetadata.plist 文件,以及一個(gè)包含SQLite data store的目錄。除了SQLite data store(保留在本地),file package中的任何東西都會被傳輸?shù)?span style="text-decoration:underline;">iCloud服務(wù)器。
打開iCloud中的現(xiàn)有文檔時(shí),執(zhí)行以下步驟:
應(yīng) 用第一次打開其它設(shè)備創(chuàng)建的Core Data文檔時(shí),Core Data會自動檢測到SQLite store不存在,并在本地創(chuàng)建一個(gè)。然后使用?NSPersistentStoreUbiquitousContentNameKey 鍵的值(你添加到屬性的那個(gè))來獲取適當(dāng)?shù)膖ransaction logs,并重新構(gòu)建數(shù)據(jù)庫的內(nèi)容。從這時(shí)候開始,你就可以修改該文檔并保存到iCloud。你所做的修改會保存到新的log file,這樣其它設(shè)備就能將其整合到它們的SQLite store。
當(dāng)應(yīng)用從iCloud中 接收到文檔修改時(shí),Core Data會自動將這些修改合并到文檔的SQLite store,并給應(yīng)用發(fā) 送?NSPersistentStoreDidImportUbiquitousContentChangesNotification 通知。應(yīng)用必須注冊這個(gè)通知,并使用它來刷新任何修改的記錄。如果應(yīng)用不刷新本地的數(shù)據(jù)拷貝,就會將老的修改重新寫到iCloud,并產(chǎn)生一個(gè)沖突版本。通過及時(shí)地整合其它設(shè)備的修改,應(yīng)用就能避免類似的沖突。
刪 除一個(gè)文檔時(shí),你必須同時(shí)刪除文檔的file package,以及包含文檔transaction logs的目錄。同時(shí)刪除所有這些東西,要求你使用?NSFileCoordinator 對象來執(zhí)行coordinated寫入操作。文檔的DocumentMetadata.plist 文件包含一個(gè)?NSPersistentStoreUbiquitousContentURLKey 鍵,它的值就是文檔transaction logs目錄的URL。
使用Core Data管理中央庫(Central Library)
如果應(yīng)用使 用Central Core Data store來管理數(shù)據(jù),就應(yīng)該將data store直接存放在應(yīng)用Sandbox目錄。使用一個(gè)Central data store的應(yīng)用,通常只有一個(gè)persistent store coordinator對象和一個(gè)persistent store對象。因此,最簡單的解決辦法是將Core Data store保留在應(yīng)用Sandbox,僅使用iCloud來同步修改。
在本地創(chuàng)建SQLite store時(shí),執(zhí)行以下步驟:
因?yàn)槟阒挥幸粋€(gè)data store,你可以為?NSPersistentStoreUbiquitousContentNameKey 鍵指定任何名字。對于 NSPersistentStoreUbiquitousContentURLKey 鍵,應(yīng)該指定為應(yīng)用某個(gè)iCloud容 器目錄中的某個(gè)目錄URL。換句話說,這個(gè)URL應(yīng)該基于 URLForUbiquityContainerIdentifier: 方法返回的URL構(gòu)造而成。Core Data將修改寫入到你指定的這個(gè)目錄,其它設(shè)備則在這個(gè)目錄中查找修改。當(dāng)檢測到修改時(shí),Core Data會自動整合修改到本地的SQLite store,并通知你的應(yīng)用。
同樣,你也必須及時(shí)地響應(yīng)iCloud相關(guān)的修改通知。這些通知使應(yīng)用能確保使用最新的數(shù)據(jù),如果你使用老版本的數(shù)據(jù),就可能覆蓋其它設(shè)備的新數(shù)據(jù),并產(chǎn)生沖突版本。
為Core Data Transaction Logs指定自定義位置
應(yīng)用Core Data Store的修改使用transaction logs來保存,這些logs存儲在用戶iCloud賬戶的一個(gè)特殊目錄中。應(yīng)用的所有Core Data Stores全部使用同一個(gè)目錄來保存transaction logs。默認(rèn)情況下,這個(gè)目錄的名字和應(yīng)用bundle ID相同,并保存在應(yīng)用默認(rèn)iCloud容器目錄中。如果你已經(jīng)使用這個(gè)目錄作為其它用途,你可以通過修改Core Data stores的選項(xiàng)來修改目錄的名字。
在 基于文檔的應(yīng)用中,要自定義transaction logs目錄,必須修改每個(gè) UIManagedDocument 對象的?persistentStoreOptions 屬性Dictionary。在字典中增加?NSPersistentStoreUbiquitousContentURLKey 鍵,并設(shè)置值為你希望使用的自定義目錄URL。這個(gè)URL需要首先使用?URLForUbiquityContainerIdentifier: 方法,并通過添加額外的路徑來擴(kuò)展URL。
如果應(yīng)用使用單一的Core Data store管理所有數(shù)據(jù),在創(chuàng)建 persistent store時(shí),調(diào)用?addPersistentStoreWithType:configuration:URL:options:error: 方法,并在options參數(shù)中增加??NSPersistentStoreUbiquitousContentURLKey 鍵,值也是你希望設(shè)置的目錄URL。
使用iCloud Key-Value Data Storage
應(yīng)用使用iCloud Key-Value data storage來存儲參數(shù)、或小量的非關(guān)鍵配置數(shù)據(jù)。key-value data storage概念上類似于本地user defaults數(shù)據(jù)庫,應(yīng)用通常用來存儲配置。區(qū)別在于iCloud數(shù)據(jù)在用戶所有設(shè)備中你的所有應(yīng)用實(shí)例間共享。
使 用?NSUbiquitousKeyValueStore 類需要設(shè)置"com.apple.developer.ubiquity-kvstore-identifier" Entitlement,如果多個(gè)不同的應(yīng)用配置相同的entitlement值,則這些應(yīng)用都可以共享相同的key-value數(shù)據(jù)。
使用?NSUbiquitousKeyValueStore 類寫入數(shù)據(jù)到iCloud key-value store,這個(gè)類概念上也類似于 NSUserDefaults,用于保存和獲取簡單的數(shù)據(jù)類型:數(shù)字、字符串、日期、數(shù)組等等。
應(yīng) 用的key-value store的容量限制為64KB(而每個(gè)鍵的限制當(dāng)前也是64KB)。因此應(yīng)用只能使用key-value storage記錄很少的數(shù)據(jù),不能用于存儲用戶文檔或其它大型數(shù)據(jù)archive。典型的例子是雜志應(yīng)用,可以保存用戶當(dāng)前閱讀的刊物和頁數(shù)。這樣用戶 在其它設(shè)備打開相同應(yīng)用時(shí),就能回到之前閱讀的位置。
NSUbiquitousKeyValueStore 類絕對無法代替 NSUserDefaults 類,應(yīng)用總是應(yīng)該通過?NSUserDefaults 將所有配置數(shù)據(jù)保存在本地磁盤。然后再使用 NSUbiquitousKeyValueStore 將需要共享的數(shù)據(jù)上傳到key-value store。這樣確保iCloud不可用時(shí),你仍然能夠訪問應(yīng)用的配置數(shù)據(jù)。
負(fù)責(zé)任的iCloud App
用戶的iCloud空間有限,并且由所有應(yīng)用共享。用戶可以查看指定應(yīng)用消耗的iCloud空間,可以選擇刪除應(yīng)用相關(guān)聯(lián)的文檔和數(shù)據(jù)。因此,應(yīng)用必須對自己存儲在iCloud中的文件負(fù)責(zé),下面是一些管理iCloud文檔的建議:
- 對存儲iCloud文檔采取一種好的策略。允許用戶啟用或禁用iCloud。
- 從用戶iCloud賬戶中刪除一個(gè)文檔,將從用戶所有計(jì)算機(jī)和設(shè)備中刪除該文檔。確保用戶明白這一點(diǎn),并確認(rèn)刪除操作。如果你只是想刷新文檔的本地拷貝,使用 NSFileManager 的?evictUbiquitousItemAtURL:error: 方法,而不是刪除文件。
- 存儲文檔到iCloud時(shí),盡量將文檔存儲在"Documents"子目錄中。用戶可以單個(gè)刪除Documents目錄中的文檔以釋放空間,但是Documents目錄之外的所有東西,都被當(dāng)做數(shù)據(jù),只能一次全部刪除!
- 永遠(yuǎn)不要存儲緩存或其它應(yīng)用的私有文件到用戶的iCloud storage。用戶的iCloud賬戶只應(yīng)該用于存儲用戶相關(guān)的數(shù)據(jù),以及應(yīng)用無法重新生成的內(nèi)容。
- 對iCloud文件和應(yīng)用Sandbox文件相同對待。保存文件應(yīng)該由應(yīng)用需求和保留用戶數(shù)據(jù)的需求來驅(qū)動。你不應(yīng)該修改應(yīng)用更頻繁或更慢地保存iCloud文件。iCloud會自動優(yōu)化自己向服務(wù)器的傳輸,以確保最佳的性能。
轉(zhuǎn)載于:https://www.cnblogs.com/ligun123/archive/2012/03/22/2411112.html
總結(jié)
以上是生活随笔為你收集整理的iCloud官方文档的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DB2的下载、图解安装、可能出现的问题(
- 下一篇: 步步为营-11-ListT泛型的简单练习