數(shù)據(jù)持久化方案解析(八) —— UIDocument的數(shù)據(jù)存儲(chǔ)(一)

版本記錄

版本號(hào) 時(shí)間
V1.0 2019.08.25 星期日

前言

數(shù)據(jù)的持久化存儲(chǔ)是移動(dòng)端不可避免的一個(gè)問題酝掩,很多時(shí)候的業(yè)務(wù)邏輯都需要我們進(jìn)行本地化存儲(chǔ)解決和完成悯舟,我們可以采用很多持久化存儲(chǔ)方案口四,比如說plist文件(屬性列表)羊异、preference(偏好設(shè)置)、NSKeyedArchiver(歸檔)读慎、SQLite 3CoreData槐雾,這里基本上我們都用過夭委。這幾種方案各有優(yōu)缺點(diǎn),其中募强,CoreData是蘋果極力推薦我們使用的一種方式株灸,我已經(jīng)將它分離出去一個(gè)專題進(jìn)行說明講解。這個(gè)專題主要就是針對(duì)另外幾種數(shù)據(jù)持久化存儲(chǔ)方案而設(shè)立擎值。
1. 數(shù)據(jù)持久化方案解析(一) —— 一個(gè)簡(jiǎn)單的基于SQLite持久化方案示例(一)
2. 數(shù)據(jù)持久化方案解析(二) —— 一個(gè)簡(jiǎn)單的基于SQLite持久化方案示例(二)
3. 數(shù)據(jù)持久化方案解析(三) —— 基于NSCoding的持久化存儲(chǔ)(一)
4. 數(shù)據(jù)持久化方案解析(四) —— 基于NSCoding的持久化存儲(chǔ)(二)
5. 數(shù)據(jù)持久化方案解析(五) —— 基于Realm的持久化存儲(chǔ)(一)
6. 數(shù)據(jù)持久化方案解析(六) —— 基于Realm的持久化存儲(chǔ)(二)
7. 數(shù)據(jù)持久化方案解析(七) —— 基于Realm的持久化存儲(chǔ)(三)

Overview

UIDocument用于管理應(yīng)用數(shù)據(jù)的離散部分的抽象基類慌烧。

首先看下框架基本信息

使用UIDocument及其底層架構(gòu)的應(yīng)用程序可為其文檔帶來許多好處:

  • 異步讀取和寫入后臺(tái)隊(duì)列(background queue)上的數(shù)據(jù)。因此幅恋,在進(jìn)行讀寫操作時(shí)杏死,應(yīng)用程序?qū)τ脩舻捻憫?yīng)性不會(huì)受到影響。
  • 協(xié)調(diào)讀取和寫入與云服務(wù)自動(dòng)集成的文檔文件捆交。
  • 支持發(fā)現(xiàn)文檔的不同版本之間的沖突(如果發(fā)生)淑翼。
  • 通過首先將數(shù)據(jù)寫入臨時(shí)文件然后用它替換當(dāng)前文檔文件來安全地保存文檔數(shù)據(jù)。
  • 在適當(dāng)?shù)臅r(shí)刻自動(dòng)保存文檔數(shù)據(jù)品追;這種機(jī)制包括支持處理暫停行為玄括。

Model-View-Controller設(shè)計(jì)模式中,UIDocument對(duì)象是模型對(duì)象或模型控制器對(duì)象 - 它管理文檔的數(shù)據(jù)或共同構(gòu)成文檔數(shù)據(jù)的聚合模型對(duì)象肉瓦。您通常將其與視圖控制器配對(duì)遭京,該視圖控制器管理顯示文檔內(nèi)容的視圖。 UIDocument不支持管理文檔視圖泞莉。

基于文檔的應(yīng)用程序包括可以生成多個(gè)文檔的應(yīng)用程序哪雕,每個(gè)文檔都有自己的文件系統(tǒng)位置■瓿茫基于文檔的應(yīng)用程序必須為其文檔創(chuàng)建UIDocument的子類斯嚎。有關(guān)詳細(xì)信息,請(qǐng)參閱下面的Subclassing Notes

注意:如果使用數(shù)據(jù)庫存儲(chǔ)文檔數(shù)據(jù)堡僻,請(qǐng)創(chuàng)建UIManagedDocument類的子類而不是UIDocument糠惫;UIManagedDocumentUIDocument的子類。

UIDocument體系結(jié)構(gòu)中文檔的主要屬性是其文件URL钉疫。 通過調(diào)用initWithFileURL:初始化文檔子類的實(shí)例時(shí)硼讽,必須傳遞在應(yīng)用程序沙箱中查找文檔文件的文件URLUIDocument從文件URL確定文件類型(與文件擴(kuò)展名關(guān)聯(lián)的統(tǒng)一類型標(biāo)識(shí)符)和文檔名稱(文件名組件)牲阁。 您可以覆蓋fileTypelocalizedName屬性的訪問器方法以提供不同的值固阁。

以下概述了典型document的生命周期(有關(guān)實(shí)現(xiàn)細(xì)節(jié),請(qǐng)參閱Subclassing Notes):

  • 1) 您可以創(chuàng)建新文檔或打開現(xiàn)有文檔城菊。

    • 要?jiǎng)?chuàng)建新文檔您炉,請(qǐng)分配并初始化子類的實(shí)例,然后在實(shí)例上調(diào)用saveToURL:forSaveOperation:completionHandler:役电。
    • 要打開現(xiàn)有文檔(由用戶選擇)赚爵,請(qǐng)分配并初始化子類的實(shí)例,然后在實(shí)例上調(diào)用 openWithCompletionHandler:法瑟。
  • 2) 用戶編輯文檔冀膝。

    • 在用戶編輯時(shí),跟蹤對(duì)文檔的更改霎挟。 UIDocument會(huì)定期記錄何時(shí)有未保存的更改并將文檔數(shù)據(jù)寫入其文件窝剖。
  • 3) 用戶請(qǐng)求將文檔與云服務(wù)集成(可選)。

    • 您必須啟用云存儲(chǔ)文檔酥夭。 您還必須解決同一文檔的不同版本之間的任何沖突赐纱。
  • 4) 用戶關(guān)閉文檔。

    • 在文檔實(shí)例上調(diào)用closeWithCompletionHandler:熬北,如果有任何未保存的更改疙描,UIDocument將保存文檔。

典型的基于文檔的應(yīng)用程序在主線程上調(diào)用openWithCompletionHandler:讶隐,closeWithCompletionHandler:saveToURL:forSaveOperation:completionHandler:起胰。當(dāng)這些方法啟動(dòng)的讀取或保存操作結(jié)束時(shí),完成處理程序塊在調(diào)用該方法的同一調(diào)度隊(duì)列上執(zhí)行巫延,允許您根據(jù)讀取或保存操作完成任何任務(wù)效五。如果操作不成功,則將NO傳遞到完成 - 處理(completion-hander)程序塊炉峰。


Implementation of the NSFilePresenter Protocol

UIDocument類采用NSFilePresenter協(xié)議畏妖。當(dāng)另一個(gè)客戶端嘗試讀取基于UIDocument的應(yīng)用程序的文檔時(shí),該讀取將暫停疼阔,直到UIDocument對(duì)象有機(jī)會(huì)保存對(duì)該文檔所做的任何更改戒劫。

雖然有些實(shí)現(xiàn)什么都不做适瓦,但UIDocument實(shí)現(xiàn)了所有NSFilePresenter方法。具體來說谱仪,UIDocument

在您的UIDocument子類中敬尺,如果重寫NSFilePresenter方法,則始終可以調(diào)用超類實(shí)現(xiàn)(super)贴浙。


Subclassing Notes

每個(gè)基于文檔的應(yīng)用程序必須創(chuàng)建UIDocument的子類砂吞,其實(shí)例表示其文檔。大多數(shù)應(yīng)用程序的子類化要求很簡(jiǎn)單:

  • 對(duì)于編寫操作崎溃,請(qǐng)實(shí)現(xiàn)contentsForType:error:方法以提供文檔數(shù)據(jù)的快照蜻直。數(shù)據(jù)必須采用NSData對(duì)象(對(duì)于平面文件)或NSFileWrapper對(duì)象(對(duì)于文件包)的形式。寫操作通常通過自動(dòng)保存功能啟動(dòng)袁串。
  • 對(duì)于讀取操作概而,實(shí)現(xiàn)loadFromContents:ofType:error:方法以接收NSDataNSFileWrapper對(duì)象并使用它初始化應(yīng)用程序的數(shù)據(jù)結(jié)構(gòu)。
  • 實(shí)施更改跟蹤以啟用自動(dòng)保存功能囱修。有關(guān)詳情赎瑰,請(qǐng)參閱 Change Tracking
  • 為文檔啟用云服務(wù)時(shí),解決文檔的不同版本之間的沖突破镰。有關(guān)詳細(xì)信息餐曼,請(qǐng)參閱 Conflict Resolution and Error Handling

contentsForType:error:loadFromContents:ofType:error:通常在主隊(duì)列上調(diào)用方法鲜漩。進(jìn)一步來說:

如果您對(duì)讀取和寫入contentsForType:error:loadFromContents:ofType:error:方法的文檔數(shù)據(jù)有特殊要求瓶佳,則可以重寫UIDocument類的其他方法。有關(guān)這些要求和方法的討論鳞青,請(qǐng)參閱Advanced Overrides霸饲。

1. Change Tracking

要啟用UIDocument的自動(dòng)保存功能,您必須在用戶更改文檔時(shí)通知它臂拓。 UIDocument定期檢查hasUnsavedChanges方法是否返回YES; 如果是厚脉,則啟動(dòng)文檔的保存操作。

UIDocument子類中實(shí)現(xiàn)更改跟蹤有兩種主要方法:

  • 調(diào)用NSUndoManager類的方法來實(shí)現(xiàn)文檔的撤消和重做胶惰。 您可以從undoManager屬性訪問默認(rèn)的NSUndoManager對(duì)象傻工。 這是首選方法,尤其適用于已支持撤消和重做的現(xiàn)有應(yīng)用程序。
  • 在代碼中的相應(yīng)接口處調(diào)用updateChangeCount:方法中捆。

2. Conflict Resolution and Error Handling

UIDocument對(duì)象在其生命周期中的任何時(shí)刻都具有特定狀態(tài)鸯匹。您可以通過查詢documentState屬性來檢查當(dāng)前狀態(tài),并通過觀察UIDocumentStateChangedNotification通知獲得有關(guān)更改的通知泄伪。

如果為iCloud啟用了文檔殴蓬,則檢查是否存在沖突版本并嘗試解決沖突非常重要。通過偵聽UIDocumentStateChangedNotification通知然后檢查文檔狀態(tài)是否為UIDocumentStateInConflict來執(zhí)行此操作蟋滴。此狀態(tài)表示文檔存在沖突版本染厅,您可以通過調(diào)用NSFileVersion類方法unresolvedConflictVersionsOfItemAtURL:來訪問該文檔,并傳入文檔的文件URL津函。如果您無需用戶交互即可正確解決沖突肖粮,請(qǐng)執(zhí)行此操作。否則尔苦,離散地通知用戶存在沖突并讓他們選擇如何解決沖突涩馆。可能的方法包括:

  • 顯示沖突的版本允坚,用戶可以從中選擇一個(gè)或兩個(gè)版本來保留
  • 顯示合并版本并為用戶提供選擇它的選項(xiàng)
  • 顯示文件修改日期并為用戶提供選擇其中一個(gè)或兩個(gè)的選項(xiàng)

除了指示文件間沖突之外凌净,文檔狀態(tài)可以指示錯(cuò)誤。例如屋讶,UIDocumentStateClosed表示讀取時(shí)出錯(cuò)冰寻,UIDocumentStateSavingError表示保存或還原文檔時(shí)出錯(cuò)。通過傳遞給openWithCompletionHandler:皿渗,closeWithCompletionHandler:斩芭,revertToContentsOfURL:completionHandler:saveToURL:forSaveOperation:completionHandler:方法的完成處理程序的success參數(shù),通知您的應(yīng)用程序讀取和寫入錯(cuò)誤乐疆。

您可以通過調(diào)用或?qū)崿F(xiàn) handleError:userInteractionPermitted:方法來處理錯(cuò)誤划乖;此方法由openWithCompletionHandler的默認(rèn)實(shí)現(xiàn)調(diào)用和saveToURL:forSaveOperation:completionHandler:分別在UIDocument對(duì)象遇到讀取或?qū)懭脲e(cuò)誤時(shí)的方法。您可以通過通知用戶來處理讀取挤土,保存和還原錯(cuò)誤琴庵,如果情況允許,則嘗試從錯(cuò)誤中恢復(fù)仰美。

請(qǐng)務(wù)必閱讀contentsForType:error:方法的說明迷殿,以獲取有關(guān)處理文檔保存期間遇到的錯(cuò)誤的指導(dǎo)。

3. Advanced Overrides

如果應(yīng)用程序?qū)ψx取或?qū)懭胛臋n數(shù)據(jù)有特殊要求咖杂,它可以覆蓋除loadFromContents:ofType:error:contentsForType:error:之外的UIDocument方法庆寺。這些要求通常包括以下內(nèi)容:

  • 增量讀取和寫入大數(shù)據(jù)文件
    • 重寫readFromURL:error:writeContents:toURL:forSaveOperation:originalContentsURL:error方法。
  • 文檔數(shù)據(jù)的自定義表示(即诉字,不是NSDataNSFileWrapper對(duì)象)
    • 覆蓋readFromURL:error:方法(讀取文檔數(shù)據(jù)時(shí))和writeContents:toURL:forSaveOperation:originalContentsURL:error:方法(寫入文檔數(shù)據(jù)時(shí))懦尝。
  • 在讀取或?qū)懭霐?shù)據(jù)之前或之后執(zhí)行操作
    • 覆蓋openWithCompletionHandler:saveToURL:forSaveOperation:completionHandler:知纷。
  • 一種安全保存的自定義方法
    • 覆蓋writeContents:andAttributes:safelyToURL:forSaveOperation:error:方法。
  • 在保存之前更改文檔的文件類型
    • 重寫saveFileType方法以返回默認(rèn)(fileType)以外的文件類型陵霉。一個(gè)例子是RTF文檔琅轧,在用戶向其添加圖像之后,應(yīng)該將其保存為RTFD文檔踊挠。

如果覆蓋大多數(shù)這些方法乍桂,請(qǐng)注意所有文檔數(shù)據(jù)的讀取和寫入必須在后臺(tái)隊(duì)列上完成,并且必須與其他嘗試讀取和寫入同一文檔文件相協(xié)調(diào)止毕。因此,您通常應(yīng)該將超類實(shí)現(xiàn)(super)作為覆蓋的一部分來調(diào)用漠趁,如果調(diào)用其他UIDocument方法扁凛,則通常應(yīng)該在傳入performAsynchronousFileAccessUsingBlock:方法調(diào)用的塊中調(diào)用它們。閱讀方法描述以獲取詳細(xì)信息闯传。

4. Thread Safety Considerations

如果通過覆蓋相關(guān)的訪問器方法來覆蓋任何文檔屬性屬性(在 Accessing Document Attributes下列出)谨朝,請(qǐng)注意UIKit框架可以在后臺(tái)線程上調(diào)用這些訪問器方法。 因此甥绿,您的重寫實(shí)現(xiàn)必須是線程安全的字币。


Topics

1. Initializing a Document Object

返回使用其文件系統(tǒng)位置初始化的文檔對(duì)象。

2. Accessing Document Attributes

3. Writing Document Data

4. Reading Document Data

5. Accessing Document Files Asynchronously

6. Reverting a Document

7. Disabling and Enabling Editing

  • disableEditing

    • 重寫以在對(duì)文檔進(jìn)行更改不安全時(shí)禁用編輯。
  • enableEditing

    • 重寫以在再次安全時(shí)進(jìn)行編輯以對(duì)文檔進(jìn)行更改郎仆。

8. Tracking Changes and Autosaving

9. Supporting User Activities

10. Resolving Conflicts and Handling Errors

11. Constants

12. Notifications

13. Conforms To

后記

本篇主要講述了UIDocument的數(shù)據(jù)存儲(chǔ),感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冤竹,一起剝皮案震驚了整個(gè)濱河市楷扬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贴见,老刑警劉巖烘苹,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異片部,居然都是意外死亡镣衡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門档悠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廊鸥,“玉大人,你說我怎么就攤上這事辖所《杷担” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵缘回,是天一觀的道長吆视。 經(jīng)常有香客問我典挑,道長,這世上最難降的妖魔是什么啦吧? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任您觉,我火速辦了婚禮,結(jié)果婚禮上授滓,老公的妹妹穿的比我還像新娘琳水。我一直安慰自己,他們只是感情好般堆,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布在孝。 她就那樣靜靜地躺著,像睡著了一般淮摔。 火紅的嫁衣襯著肌膚如雪私沮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天噩咪,我揣著相機(jī)與錄音顾彰,去河邊找鬼极阅。 笑死胃碾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筋搏。 我是一名探鬼主播仆百,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼奔脐!你這毒婦竟也來了俄周?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤髓迎,失蹤者是張志新(化名)和其女友劉穎峦朗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體排龄,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡波势,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了橄维。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尺铣。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖争舞,靈堂內(nèi)的尸體忽然破棺而出凛忿,到底是詐尸還是另有隱情,我是刑警寧澤竞川,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布店溢,位于F島的核電站叁熔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏逞怨。R本人自食惡果不足惜者疤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叠赦。 院中可真熱鬧驹马,春花似錦、人聲如沸除秀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽册踩。三九已至泳姐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間暂吉,已是汗流浹背胖秒。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慕的,地道東北人阎肝。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像肮街,于是被迫代替她去往敵國和親风题。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容