UIKit框架為管理多個(gè)文檔的應(yīng)用程序提供支持陶耍,每個(gè)文檔包含存儲在應(yīng)用程序沙箱或iCloud中的文件中的唯一數(shù)據(jù)集薛夜。
這個(gè)支持的核心是在iOS 5.0中引入的UIDocument類。 基于文檔的應(yīng)用程序必須創(chuàng)建UIDocument的子類遍尺,它將文檔數(shù)據(jù)加載到其內(nèi)存數(shù)據(jù)結(jié)構(gòu)中蔬啡,并向UIDocument提供要寫入文檔文件的數(shù)據(jù)。 UIDocument負(fù)責(zé)管理與文檔管理有關(guān)的許多細(xì)節(jié)血久。 除了與iCloud的集成外,UIDocument還會在后臺讀取和寫入文檔數(shù)據(jù)帮非,以便您的應(yīng)用程序的用戶界面在這些操作中不會變得無響應(yīng)氧吐。 它還可以自動定期保存文檔數(shù)據(jù),讓用戶免于明確保存喜鼓。
概述
雖然基于文檔的應(yīng)用程序負(fù)責(zé)一系列行為,但是編寫基于應(yīng)用程序文檔的應(yīng)用程序通常不是一件困難的任務(wù)衔肢。
文檔對象是模型控制器
在Model-View-Controller設(shè)計(jì)模式中庄岖,文檔對象(即UIDocument的子類的實(shí)例)是模型控制器。文檔對象管理與文檔相關(guān)聯(lián)的數(shù)據(jù)角骤,特別是內(nèi)部表示用戶正在查看和編輯的模型對象隅忿。文檔對象通常由向用戶呈現(xiàn)文檔的視圖控制器來管理。
相關(guān)章節(jié):設(shè)計(jì)基于文檔的應(yīng)用程序
設(shè)計(jì)應(yīng)用程序時(shí)邦尊,考慮文檔數(shù)據(jù)格式和其他問題
在編寫代碼之前背桐,您應(yīng)該考慮到基于文檔的應(yīng)用程序特定的設(shè)計(jì)方面。最重要的是蝉揍,您的應(yīng)用程序的文檔數(shù)據(jù)的最佳格式是什么链峭,以及如何使該格式在iOS和Mac OS X中為您的應(yīng)用程序工作?什么是最合適的文件類型又沾?
您還需要規(guī)劃視圖控制器(和視圖)來管理打開文檔弊仪,指示錯誤以及將所選文檔移入和移出iCloud存儲的任務(wù)。
相關(guān)章節(jié):設(shè)計(jì)基于文檔的應(yīng)用程序杖刷,基于文檔的應(yīng)用程序預(yù)檢
創(chuàng)建UIDocument的子類需要兩個(gè)方法覆蓋
文檔對象的主要作用是將文檔文件和內(nèi)部表示文檔數(shù)據(jù)的模型對象之間的數(shù)據(jù)“管理”励饵。它給UIDocument類寫入文檔文件的數(shù)據(jù),在讀取文檔文件之后滑燃,它使用UIDocument給出的數(shù)據(jù)來初始化其模型對象役听。為了履行此角色,您的UIDocument子類必須分別重寫contentForType:error:method和loadFromContents:ofType:error:method表窘。
相關(guān)章節(jié):創(chuàng)建自定義文檔對象
應(yīng)用程序通過其生命周期管理文檔
應(yīng)用程序負(fù)責(zé)管理文檔生命周期中的以下事件:
創(chuàng)建文件
打開和關(guān)閉文檔
監(jiān)視文檔狀態(tài)的更改并響應(yīng)錯誤或版本沖突
將文檔移動到iCloud存儲(并將其從iCloud存儲中刪除)
刪除文件
相關(guān)章節(jié):管理文件的生命周期
應(yīng)用程序在用戶請求后存儲iCloud中的文檔文件
應(yīng)用程序?yàn)橛脩籼峁⑺形臋n文件放在iCloud存儲或本地沙箱中的所有文檔文件的選項(xiàng)典予。要將文檔文件移動到iCloud,它們將文檔URL組織到應(yīng)用程序的iCloud容器目錄中乐严,然后調(diào)用NSFileManager類的特定方法熙参,傳遞文件URL。將文檔文件從iCloud存儲移動到應(yīng)用程序沙箱遵循類似的過程麦备。
相關(guān)章節(jié):管理文件的生命周期
應(yīng)用程序確保文檔數(shù)據(jù)自動保存
UIDocument遵循無保留模式孽椰,并以特定的間隔自動保存文檔的數(shù)據(jù)昭娩。用戶通常不需要明確保存文檔。但是黍匾,您的應(yīng)用程序必須發(fā)揮其作用栏渺,才能使無節(jié)制模式正常工作,無論是通過執(zhí)行撤消和重做锐涯,還是通過跟蹤文檔的更改磕诊。
相關(guān)章節(jié):更改跟蹤和撤消操作
應(yīng)用程序解決不同文檔版本之間的沖突
當(dāng)文檔存儲在iCloud中時(shí),可能會發(fā)生文檔版本之間的沖突纹腌。發(fā)生沖突時(shí)霎终,UIKit通知應(yīng)用程序。應(yīng)用程序必須嘗試解決沖突本身或邀請用戶選擇他或她喜歡的版本升薯。
相關(guān)章節(jié):解決文件版本沖突
如何使用本文檔
在開始為基于文檔的應(yīng)用程序編寫任何代碼之前莱褒,您應(yīng)至少閱讀前兩章,設(shè)計(jì)基于文檔的應(yīng)用程序和基于文檔的應(yīng)用程序預(yù)檢涎劈。這些章節(jié)將討論設(shè)計(jì)和配置問題广凸,并概述了精心設(shè)計(jì)的基于文檔的應(yīng)用程序所需的任務(wù)
先決條件
在閱讀“基于文檔的iOS應(yīng)用程序編程指南”之前,您應(yīng)該熟悉iOS應(yīng)用程序編程指南中提供的信息蛛枚。
也可以看看
以下文檔以某種方式與基于文檔的iOS應(yīng)用程序編程指南相關(guān):
統(tǒng)一類型標(biāo)識符概述和相關(guān)參考討論了統(tǒng)一類型標(biāo)識符(UTI)谅海,它們是文檔類型的主要標(biāo)識符。
“文件元數(shù)據(jù)搜索編程指南”介紹了如何使用NSMetadataQuery類和相關(guān)類進(jìn)行搜索蹦浦。您使用元數(shù)據(jù)查詢來查找存儲在iCloud中的應(yīng)用程序的文檔扭吁。
iCloud設(shè)計(jì)指南提供了iCloud文檔支持的介紹。
設(shè)計(jì)基于文檔的應(yīng)用程序
在iOS 5.0中引入的UIDocument類在基于文檔的iOS應(yīng)用程序中起主要作用盲镶。它是一個(gè)抽象的基類 - 這意味著你有一些有用的東西智末,你必須創(chuàng)建一個(gè)適合你的應(yīng)用程序需求的子類。添加到子類中的特定于應(yīng)用程序的代碼增強(qiáng)了UIDocument可以實(shí)現(xiàn)的功能:與iCloud存儲集成的移動環(huán)境中的文檔的高效行為徒河。
為什么要創(chuàng)建一個(gè)基于文檔的應(yīng)用程序系馆?
當(dāng)您有任何應(yīng)用的想法并坐下來設(shè)計(jì)它時(shí),您必須評估許多選項(xiàng)顽照。您應(yīng)該使用什么樣的應(yīng)用程序(主 - 細(xì)節(jié)由蘑,基于頁面的實(shí)用程序,OpenGL游戲等)代兵?應(yīng)用程序是否會自己繪制圖形尼酿,是否會對手勢或觸摸事件做出響應(yīng),并且會合并視聽資產(chǎn)嗎植影?如果應(yīng)用程序使用核心數(shù)據(jù)裳擎,數(shù)據(jù)模型將是什么?是否使您的應(yīng)用程序基于文檔的決定可能似乎使這一系列選擇變得復(fù)雜思币,但它真的歸結(jié)為如何預(yù)期人們將使用您的應(yīng)用程序鹿响。
當(dāng)用戶期望在可視容器中輸入和編輯內(nèi)容并以指定的名稱存儲該內(nèi)容時(shí)羡微,基于文檔的應(yīng)用程序是理想的,甚至是必要的惶我。每個(gè)容器的信息 - 一個(gè)文件 - 是唯一的妈倔。您無疑熟悉桌面和移動系統(tǒng)中發(fā)現(xiàn)的幾種基于文檔的應(yīng)用程序。舉幾個(gè)例子绸贡,有文字處理程序盯蝴,電子表格和繪圖程序。通過iCloud技術(shù)听怕,您可以使您的應(yīng)用程序文檔更加引人入勝捧挺。例如,您的用戶可以使用OS X桌面系統(tǒng)上的應(yīng)用程序創(chuàng)建文檔尿瞭,然后再使用iOS版本的應(yīng)用程序在iPad上編輯該文檔闽烙,而無需進(jìn)行任何同步或復(fù)制。這個(gè)功能使他們有更多的動機(jī)去購買你的應(yīng)用程序筷厘。
當(dāng)您采用基于文檔的應(yīng)用程序的UIDocument方法時(shí)鸣峭,您的應(yīng)用程序可以免費(fèi)獲取大量行為宏所,或者以最少的編碼工作酥艳。
與iCloud存儲集成。 UIDocument對象協(xié)調(diào)從iCloud存儲器讀取和寫入文檔數(shù)據(jù)的所有內(nèi)容爬骤。它通過采用NSFilePresenter協(xié)議和調(diào)用NSFileCoordinator和NSFileManager類的方法來實(shí)現(xiàn)充石。
后臺寫入和讀寫文件數(shù)據(jù)。如果您的應(yīng)用程序同步讀取和寫入文檔霞玄,它將變得暫時(shí)無響應(yīng)骤铃。 UIDocument對象通過在背景調(diào)度隊(duì)列上異步讀取和寫入文檔數(shù)據(jù)來避免此問題。
無需保存的模型坷剧,基于文檔的應(yīng)用程序的用戶很少需要明確保存文檔; UIDocument對象按照用戶正在使用的文檔進(jìn)行優(yōu)化的間隔自動保存文檔數(shù)據(jù)惰爬。您可以通過實(shí)施撤銷管理或更改跟蹤來實(shí)現(xiàn)基于文檔的應(yīng)用程序“無節(jié)制”(請參閱更改跟蹤和撤消操作信息)。
安全保存惫企,UIDocument對象安全地保存文檔數(shù)據(jù);因此撕瞧,如果一些外部事件中斷保存操作,文檔數(shù)據(jù)將不會保持不一致的狀態(tài)狞尔。該對象通過首先將最新版本的文檔寫入臨時(shí)文件丛版,然后用其替換當(dāng)前文檔文件來實(shí)現(xiàn)安全保存。
支持處理錯誤和版本沖突偏序。當(dāng)UIDocument對象檢測到不同版本的文檔之間的沖突時(shí)页畦,它會通知應(yīng)用程序。然后研儒,應(yīng)用程序可以嘗試解決沖突本身豫缨,或者可以要求用戶選擇所需的文檔版本独令。當(dāng)保存操作不成功時(shí),UIDocument對象還會通知應(yīng)用程序州胳。管理文檔的生命周期描述了如何觀察這些通知;解決文檔版本沖突討論了處理文檔版本沖突的策略
iOS中的文檔
雖然文檔的廣泛定義是“信息容器”记焊,但可以通過多種方式查看該容器。對于用戶栓撞,文檔是他或她以唯一的名稱創(chuàng)建遍膜,編輯和保存的文本,圖像瓤湘,形狀和其他形式的信息瓢颅。文檔還可以參考文檔文件:文檔數(shù)據(jù)的持久磁盤表示。一個(gè)文檔可以表示一個(gè)UIDocument對象弛说,它表示和管理同一數(shù)據(jù)的內(nèi)存中的表示挽懦。
文檔對象在將文檔數(shù)據(jù)在其在磁盤上的表示與其在存儲器中的表示之間的轉(zhuǎn)換中也起關(guān)鍵作用。它與UIDocument類合作木人,將文檔數(shù)據(jù)寫入文件并讀取該數(shù)據(jù)信柿。對于寫入,文檔通常提供可以寫入文檔文件的數(shù)據(jù)的快照;為了閱讀醒第,它接收數(shù)據(jù)并用它初始化文檔的模型對象渔嚷。在某種意義上,文檔是存儲在文件中的數(shù)據(jù)與該數(shù)據(jù)的內(nèi)部表示之間的通道稠曼。圖1-1說明了這些關(guān)系形病。
圖1-1由文檔對象管理的文檔文件,文檔對象和模型對象
iCloud存儲中的文檔
在iCloud中霞幅,文件駐留在與應(yīng)用程序關(guān)聯(lián)的容器目錄中漠吻。該目錄具有內(nèi)部結(jié)構(gòu),其中最重要的是一個(gè)Documents子目錄司恳。在iCloud方案中途乃,寫入Documents子目錄的文件和文件包將被視為文檔文件 - 即使它們不是基于文檔的應(yīng)用程序。寫入容器目錄中其他位置的文件被視為數(shù)據(jù)文件扔傅。
文檔對象是文件呈現(xiàn)器耍共,因?yàn)閁IDocument類采用NSFilePresenter協(xié)議。文件演示者與NSFileCoordinator對象一起使用铅鲤,以協(xié)調(diào)對應(yīng)用程序?qū)ο笾g以及應(yīng)用程序和其他進(jìn)程之間的文件或目錄的訪問划提。文件演示者涉及其他客戶端訪問相同的文件或目錄。
當(dāng)用戶要求將文檔文件存儲在iCloud存儲中時(shí)邢享,基于文檔的應(yīng)用程序應(yīng)將這些文件(包括文件包)保存在iCloud容器目錄的Documents子目錄中鹏往。有關(guān)詳細(xì)信息,請參閱管理文檔的生命周期。有關(guān)iCloud移動容器的更多信息伊履,請參閱iCloud設(shè)計(jì)指南韩容。
UIDocument對象的屬性
文檔對象具有多個(gè)定義屬性,其中大部分與其作為文檔數(shù)據(jù)管理器的角色有關(guān)唐瀑。這些屬性由UIDocument類聲明群凶。
檔案網(wǎng)址,文檔必須具有可以存儲的位置哄辣,無論該位置在本地文件系統(tǒng)還是在iCloud存儲中请梢。 fileURL屬性標(biāo)識此位置。創(chuàng)建UIDocument對象時(shí)力穗,必須指定文件URL作為UIDocument的initWithFileURL:initializer方法的參數(shù)毅弧。
文件名稱。 UIDocument對象從文件URL的文件名組件獲取默認(rèn)文檔名稱当窗,并將其存儲在localizedName屬性中够坐。您可以覆蓋此屬性的getter方法來提供自定義的本地化文檔名稱。
注意:文檔的顯示名稱不必與文檔的文件名對應(yīng)崖面。此外元咙,不需要用戶指定文檔名稱。有關(guān)此主題的更多信息巫员,請參閱創(chuàng)建新文檔庶香。
文件類型。文件類型是從文件URL的擴(kuò)展名導(dǎo)出并分配給fileType屬性的統(tǒng)一類型標(biāo)識符(UTI)疏遏。有關(guān)詳細(xì)信息脉课,請參閱iOS如何識別應(yīng)用程序的文檔救军。
修改日期财异。文檔文件上次修改的日期。該值存儲在fileModificationDate屬性中唱遭。它可以用于(除其他外)解決文檔版本沖突戳寸。
文件狀態(tài)文檔在其運(yùn)行期間處于幾種可能狀態(tài)之一。這些狀態(tài)可以指示拷泽,例如疫鹊,保存文檔或存在沖突的文檔版本時(shí)出錯。 UIDocument將當(dāng)前文檔狀態(tài)存儲在documentState屬性中司致。有關(guān)觀察文檔狀態(tài)更改的信息拆吆,請參閱監(jiān)控文檔狀態(tài)更改和處理錯誤。
基于文檔的應(yīng)用程序的設(shè)計(jì)注意事項(xiàng)
在為基于文檔的應(yīng)用程序編寫一行代碼之前脂矫,請考慮幾個(gè)設(shè)計(jì)問題枣耀。
定義對象關(guān)系
與所有應(yīng)用程序一樣,您應(yīng)該為基于模型 - 視圖 - 控制器設(shè)計(jì)模式(MVC)的基于文檔的應(yīng)用程序的對象設(shè)計(jì)整體設(shè)計(jì)庭再。雖然建議使用以下MVC設(shè)計(jì)文件捞奕,您可以自由地提出自己的對象關(guān)系設(shè)計(jì)牺堰。
在MVC術(shù)語中,文檔是模型控制器;它“擁有”并管理表示文檔內(nèi)容的模型對象颅围。文檔對象本身由視圖控制器擁有和管理伟葫。根據(jù)定義,視圖控制器還管理呈現(xiàn)由文檔對象管理的內(nèi)容的視圖院促。因此筏养,它是這種關(guān)系網(wǎng)絡(luò)中的中介控制器,從文檔對象獲取需要呈現(xiàn)的數(shù)據(jù)常拓,并將用戶輸入或更改的數(shù)據(jù)傳遞給文檔對象撼玄。圖1-2描述了這些對象關(guān)系。
圖1-2視圖控制器管理文檔對象和呈現(xiàn)文檔數(shù)據(jù)的視圖
正如視圖控制器嵌入其視圖一樣墩邀,視圖控制器可以將文檔對象嵌入為聲明的屬性掌猛。當(dāng)應(yīng)用程序?qū)嵗晥D控制器時(shí),它將使用文檔對象或文檔的文件URL(視圖控制器本身可以創(chuàng)建文檔對象)來初始化它眉睹。
當(dāng)然荔茬,基于文檔的應(yīng)用程序?qū)⒕哂衅渌晥D控制器(帶有其視圖)和可能的其他模型對象。要了解可能需要其他視圖控制器的信息竹海,請參閱設(shè)計(jì)用戶界面慕蔚。
設(shè)計(jì)用戶界面
UIKit和開發(fā)人員工具都不會為基于文檔的應(yīng)用程序的用戶界面提供任何支持。例如斋配,沒有UIDocumentView類或UIDocumentViewController類孔飒,沒有用于選擇文檔的標(biāo)準(zhǔn)接口。不要后悔缺席艰争,而是為了為您的基于文檔的應(yīng)用程序創(chuàng)建一個(gè)使其脫穎而出的用戶界面坏瞄。
盡管如此,所有基于文檔的應(yīng)用程序都應(yīng)使用戶能夠執(zhí)行需要用戶界面元素的某些功能;這些包括以下內(nèi)容:
- 查看和編輯文檔
- 創(chuàng)建一個(gè)新的文檔
- 從應(yīng)用程序所擁有的文檔列表中選擇文檔
- 打開甩卓,關(guān)閉和刪除所選文檔
- 將選定的文檔放在iCloud存儲中(并從iCloud存儲中刪除選定的文檔)
- 指示錯誤條件鸠匀,包括文檔版本沖突
- 撤消和重做更改(推薦但不需要)
設(shè)計(jì)應(yīng)用程序時(shí),請確保包含執(zhí)行這些操作所必需的視圖控制器逾柿,視圖和控件缀棍。
選擇文檔數(shù)據(jù)的類型,格式和策略
在為基于文檔的應(yīng)用程序設(shè)計(jì)數(shù)據(jù)模型時(shí)机错,請問和回答以下問題至關(guān)重要:
我的文檔類型是什么爬范?
文檔必須具有文檔類型,表示文檔特征的信息集合弱匪,并將其與應(yīng)用程序相關(guān)聯(lián)青瀑。文檔類型具有與一個(gè)或多個(gè)文件擴(kuò)展名配對的名稱,圖標(biāo)(可選),處理程序排名和統(tǒng)一類型標(biāo)識符(UTI)狱窘。對于在iOS和OS X中編輯相同文檔的應(yīng)用程序杜顺,文檔類型信息應(yīng)該是一致的。
創(chuàng)建和配置項(xiàng)目說明了如何在基于文檔的iOS應(yīng)用程序中指定文檔類型蘸炸。有關(guān)UTI和統(tǒng)一類型標(biāo)識符的描述躬络,請參閱統(tǒng)一類型標(biāo)識符概述常見的統(tǒng)一類型標(biāo)識符的說明。
我應(yīng)該如何表示寫入文件的文檔數(shù)據(jù)搭儒?
你基本上有三個(gè)選擇:
Core Data穷当。核心數(shù)據(jù)是對象圖管理和持久性的技術(shù)和框架。它可以使用內(nèi)置的SQLite數(shù)據(jù)庫作為數(shù)據(jù)庫系統(tǒng)淹禾。 UIManagedDocument類是UIDocument的子類馁菜,用于使用Core Data的基于文檔的應(yīng)用程序。
支持的對象格式,UIDocument支持NSData和NSFileWrapper對象作為文檔數(shù)據(jù)表示的本機(jī)類型铃岔。 NSData適用于平面文件汪疮,NSFileWrapper適用于文件包,它們是iOS視為單個(gè)文件的目錄毁习。如果給UIDocument這些對象之一智嚷,它會將其保存到文件系統(tǒng)中,而無需進(jìn)一步參與纺且。
自定義對象格式,如果要將寫入文件的文檔數(shù)據(jù)為NSData或NSFileWrapper以外的類型盏道,則可以在特定的UIDocument方法的替換中自己將其寫入文件。請記住载碌,您的代碼必須重復(fù)UIDocument為您做的猜嘱,因此您必須處理更大的復(fù)雜性和更大的錯誤可能性。有關(guān)更多信息嫁艇,請參閱UIDocument類參考朗伶。
為什么要將文檔數(shù)據(jù)存儲在數(shù)據(jù)庫而不是文件中?
如果由文檔對象管理的數(shù)據(jù)集主要是一個(gè)較大的對象圖裳仆,但是您的應(yīng)用程序隨時(shí)只使用該圖形的一個(gè)子部分腕让,則UIManagedDocument和Core Data是一個(gè)很好的選擇孤钦。核心數(shù)據(jù)為基于文檔的應(yīng)用程序帶來許多好處:
- 增量讀寫文件資料
- 支持撤消和重做操作
- 自動支持解決文檔版本沖突
- 跨平臺應(yīng)用程序的數(shù)據(jù)兼容性
核心數(shù)據(jù)的“缺點(diǎn)”是它是一項(xiàng)復(fù)雜的技術(shù);熟悉其概念歧斟,課程和技術(shù)需要時(shí)間。要了解更多信息偏形,請閱讀“核心數(shù)據(jù)編程指南”和“UIManagedDocument類參考”静袖。
支持的對象格式(NSData或NSFileWrapper)最適合我的應(yīng)用程序?
是否對文檔數(shù)據(jù)使用NSData或NSFileWrapper對象取決于數(shù)據(jù)的復(fù)雜程度以及文檔的模型對象圖形的部分內(nèi)容是否可以單獨(dú)寫入文件俊扭。例如队橙,如果您的文檔數(shù)據(jù)是純文本,而沒有其他數(shù)據(jù),則NSData是適合的容器捐康。但是仇矾,如果數(shù)據(jù)具有多個(gè)組件(例如文本和圖像),請使用NSFileWrapper方法為數(shù)據(jù)創(chuàng)建文件包解总。
文件包裝器對象和它們所代表的文件包比二進(jìn)制數(shù)據(jù)對象提供了一些優(yōu)勢贮匕。
文件包裝器支持增量保存。與單個(gè)二進(jìn)制數(shù)據(jù)對象相反花枫,如果文件包裝器包含文檔數(shù)據(jù)(例如文本和圖像)刻盐,文本更改,則只有包含文本的文件必須寫入磁盤劳翰。此功能可以帶來更好的性能敦锌。
文件包裝(和文件包)使得版本文檔更容易。例如佳簸,文件包可以包含一個(gè)屬性列表文件乙墙,其中包含有關(guān)文檔的版本信息和其他元數(shù)據(jù)。
將文檔數(shù)據(jù)存儲在文件包中討論(并說明)如何使用NSFileWrapper對象來表示可以作為文件包編寫的表單中的文檔數(shù)據(jù)生均。
我可以歸檔我的模型對象圖并將該NSData對象寫入文檔文件嗎伶丐?
是的,這是可能的疯特,但前面提到的一些注意事項(xiàng)適用哗魂。如果您的文檔的模型對象圖形的任何部分可以寫入單獨(dú)的文件,請不要?dú)w檔該部分漓雅。相反录别,將NSData存檔和分區(qū)項(xiàng)目存儲為文件包的單獨(dú)組件。
如果我的文檔文件非常大邻吞,該怎么辦组题?
如果存儲在文檔文件中的數(shù)據(jù)可能很大,您可能必須逐步寫入和讀取數(shù)據(jù)抱冷,以確保良好的用戶體驗(yàn)崔列。你可能會采取幾種方法:
- 使用UIManagedDocument。記住旺遮,核心數(shù)據(jù)可以免費(fèi)增加閱讀和寫作赵讯。
- 將文檔數(shù)據(jù)的可分離組件存儲在文件包中。
- 覆蓋UIDocument的較低級別的方法耿眉,并自己進(jìn)行數(shù)據(jù)的讀寫边翼。 (有關(guān)詳細(xì)信息,請參閱UIDocument類參考鸣剪。)應(yīng)始終使用適用于數(shù)據(jù)類型的增量讀寫API组底,例如丈积,AV Foundation框架具有用于增量閱讀大型多媒體文件的方法。
如果我希望我的文檔在兩個(gè)平臺上可以編輯债鸡,我該怎么考慮江滨?
如果您的用戶可以在iOS移動設(shè)備(iPhone,iPad和iPad touch)和OS X桌面系統(tǒng)上創(chuàng)建和編輯文檔厌均,您的應(yīng)用程序?qū)⒕哂懈偁巸?yōu)勢牙寞。但是為了可以這樣做,兩個(gè)平臺上的文檔數(shù)據(jù)的格式應(yīng)該是兼容的莫秆。文檔數(shù)據(jù)兼容性的一些重要注意事項(xiàng)是:
一些技術(shù)在一個(gè)平臺上可用间雀,但不是另一個(gè)财松。例如辕羽,如果您在OS X中使用RTF作為文檔格式,則該格式在iOS中將無法運(yùn)行气筋,因?yàn)槠湮谋鞠到y(tǒng)不支持富文本缝驳。
每個(gè)平臺中的相應(yīng)類別不兼容连锯。這對于顏色(UIColor和NSColor),圖像(UIImage和NSImage)以及Bezier路徑(UIBezierPath和NSBezierPath)尤其如此用狱。例如运怖,NSColor對象是根據(jù)顏色空間(NSColorSpace)定義的,但在UIKit中沒有顏色空間類夏伊。
如果您使用其中一個(gè)類定義了一個(gè)文檔屬性摇展,則必須設(shè)計(jì)一種方法(在準(zhǔn)備文檔數(shù)據(jù)以進(jìn)行寫入時(shí))將該屬性轉(zhuǎn)換為可以在另一個(gè)平臺上精確重構(gòu)的表單。這樣做的一個(gè)方法是將“下拉”到兩個(gè)平臺共享的較低級別的框架溺忧。例如咏连,UIColor定義了一個(gè)CIColor屬性,它保存一個(gè)表示顏色的Core Image對象;在OS X端鲁森,您的應(yīng)用程序可以使用colorWithCIColor:class方法從CIColor對象創(chuàng)建一個(gè)NSColor對象祟滴。
每個(gè)平臺的默認(rèn)坐標(biāo)系是不同的,這種差異可能會影響內(nèi)容的繪制方式歌溉。 (有關(guān)此主題的討論垄懂,請參閱iOS繪圖和打印指南中的iOS中的坐標(biāo)系和繪圖)。
如果您部分或全部歸檔文檔的模型對象圖形痛垛,則在對模型對象進(jìn)行編碼和解碼時(shí)草慧,您可能必須使用NSCoder方法執(zhí)行平臺敏感轉(zhuǎn)換。
基于文檔的應(yīng)用程序預(yù)檢
對于大多數(shù)開發(fā)人員來說榜晦,制作基于文檔的應(yīng)用程序比基于文檔的應(yīng)用程序不需要更多的工作冠蒋。基本的區(qū)別在于您必須創(chuàng)建UIDocument的自定義子類乾胶,然后通過其運(yùn)行時(shí)生命周期來管理文檔抖剿,包括與iCloud存儲的集成。本章概述了大多數(shù)應(yīng)用程序執(zhí)行的特定于文檔的任務(wù)识窿,并描述了在iOS中創(chuàng)建和配置基于文檔的應(yīng)用程序項(xiàng)目的一般步驟斩郎。
基于文檔的應(yīng)用程序您必須做的事情
要創(chuàng)建基于文檔的應(yīng)用程序,您應(yīng)該完成以下任務(wù):
創(chuàng)建UIDocument的自定義子類喻频,為UIKit框架提供文檔數(shù)據(jù)的快照缩宜,并從文檔文件的內(nèi)容中初始化文檔的模型對象。
創(chuàng)建自定義文檔對象描述所需的方法覆蓋甥温,如果將文檔數(shù)據(jù)存儲為文件包锻煌,說明如何使用NSFileWrapper對象進(jìn)行文檔數(shù)據(jù)。允許用戶創(chuàng)建新文檔姻蚓,并選擇并打開現(xiàn)有文檔宋梧。您還應(yīng)執(zhí)行關(guān)閉文檔和刪除所選文檔的補(bǔ)充任務(wù)。
請注意狰挡,創(chuàng)建或打開文檔的后續(xù)任務(wù)是在視圖中顯示文檔的內(nèi)容捂龄。
創(chuàng)建新文檔,打開和關(guān)閉文檔以及刪除文檔描述這些任務(wù)的要求和步驟加叁。這些討論還包括管理文檔數(shù)據(jù)的顯示的示例倦沧。
實(shí)施撤銷管理或更改跟蹤功能,實(shí)現(xiàn)自動保存文檔數(shù)據(jù)(無保存模型)它匕。
有關(guān)詳細(xì)信息展融,請參閱更改跟蹤和撤消操作。將文檔(通常由用戶選擇的文檔)放入iCloud存儲豫柬。當(dāng)用戶請求時(shí)愈污,也可以從iCloud存儲中刪除文檔。
從iCloud Storage移動文件討論這些過程轮傍。觀察文檔狀態(tài)更改的通知暂雹,如果發(fā)生錯誤,請適當(dāng)回復(fù)创夜。
監(jiān)控文檔狀態(tài)更改和處理錯誤描述了執(zhí)行此操作的一般步驟杭跪。如果發(fā)生不同版本的文檔之間的沖突,請通知用戶并提供解決沖突的方法驰吓。
解決文檔版本沖突描述了如何通知用戶版本沖突涧尿,并討論解決這些沖突的策略。
您還可以為基于文檔的應(yīng)用程序添加額外的功能檬贰,例如打印文檔姑廉,拼寫檢查或?qū)⑵浒l(fā)送給其他人的功能。
如果您的應(yīng)用程序具有高級要求(例如翁涤,增量讀取和寫入大型文檔文件或處理除支持的文檔數(shù)據(jù)格式之外的文檔數(shù)據(jù)格式)桥言,請參閱UIDocument類參考萌踱。所有這些高級任務(wù)都涉及覆蓋UIDocument方法。
創(chuàng)建和配置項(xiàng)目
為基于文檔的應(yīng)用程序創(chuàng)建Xcode項(xiàng)目時(shí)号阿,請選擇合適的模板并鸵。 (請注意,沒有專門針對基于文檔的應(yīng)用程序的模板扔涧。)通常园担,您希望應(yīng)用程序的第一個(gè)視圖是用戶可以選擇現(xiàn)有文檔并創(chuàng)建新應(yīng)用程序的視圖。因?yàn)镸aster-Detail Xcode模板適用于此目的枯夜,所以在本文檔的代碼示例中使用弯汰。此模板為您提供了iPhone的初始表視圖和iPad的拆分視圖。您的項(xiàng)目應(yīng)使用故事板湖雹,因此請務(wù)必選擇此選項(xiàng)咏闪。
注意:如果您使用Core Data來管理文檔數(shù)據(jù),請務(wù)必在“新建項(xiàng)目”助手中選擇“使用核心數(shù)據(jù)”選項(xiàng)劝枣。
根據(jù)您的應(yīng)用程序的設(shè)計(jì)(請參閱設(shè)計(jì)基于文檔的應(yīng)用程序)汤踏,創(chuàng)建應(yīng)用程序所需的視圖控制器子類。所有你需要的是最低限度聲明的頭文件和源文件在這一點(diǎn)上舔腾。然后溪胶,在項(xiàng)目故事板中創(chuàng)建應(yīng)用程序的用戶界面(如果您的應(yīng)用程序是通用應(yīng)用程序,則創(chuàng)建故事板);將自定義視圖控制器與故事板中的視圖控制器占位符相關(guān)聯(lián)稳诚。
接下來哗脖,您需要通過在Xcode目標(biāo)設(shè)置中指定應(yīng)用程序知道的文檔的類型或類型來配置文檔項(xiàng)目。
iOS如何識別您的應(yīng)用程序的文檔
iOS中文檔對象最重要的屬性是其文件URL(fileURL)扳还。文件網(wǎng)址很重要才避,除其他原因外,因?yàn)樗嬖ViOS哪些應(yīng)用程序了解文檔的格式氨距。文件URL以擴(kuò)展名(例如html)結(jié)尾桑逝,此擴(kuò)展名與統(tǒng)一類型標(biāo)識符(例如,public.html)匹配俏让。統(tǒng)一類型標(biāo)識符(UTI)是文檔類型的主體標(biāo)識符楞遏。使用擴(kuò)展名,UIDocument查找文檔類型UTI(如圖2-1所示)首昔,并將其分配給fileType屬性寡喝。與OSX中的基于文檔的應(yīng)用程序不同,iOS中的應(yīng)用程序不需要將UIDocument子類與文檔類型相關(guān)聯(lián)勒奇。
圖2-1 iOS從其文件URL的擴(kuò)展名查找文檔UTI
文件類型UTI可以由系統(tǒng)定義;請參閱系統(tǒng)聲明的統(tǒng)一類型標(biāo)識符中的統(tǒng)一類型標(biāo)識符參考這些常見標(biāo)識符的列表预鬓。基于文檔的應(yīng)用程序還可以為其文檔定義自己的專有UTI(并且通常是)赊颠。如果它聲明一個(gè)自定義UTI格二,它還必須導(dǎo)出該UTI以使操作系統(tǒng)了解它劈彪。
聲明文檔類型
要在Xcode中聲明文檔類型,首先單擊目標(biāo)信息設(shè)置中的添加按鈕蟋定,然后從彈出菜單中選擇添加文檔類型粉臊。單擊“無標(biāo)題”旁邊的三角形以公開屬性字段草添,并添加表2-1中的屬性驶兜。
表2-1定義文檔類型的屬性(CFBundleDocumentTypes)
鍵 | Xcode字段 | 價(jià)值和評論 |
---|---|---|
LSItemContentTypes | 類型 | 一系列UTI字符串。通常每個(gè)文檔類型指定一個(gè)远寸。 |
CFBundleTypeName | 名稱 | 文檔類型的可選名稱抄淑。 |
CFBundleTypeIconFiles | 圖標(biāo) | 應(yīng)用程序包中圖標(biāo)圖像文件的路徑數(shù)組。 |
CFBundleTypeExtensions | 在“附加文檔類型屬性”表中驰后。 | 與文件UTI配對的文件擴(kuò)展名數(shù)組肆资。 |
LSHandlerRank | 在“附加文檔類型屬性”表中。 | 所有者灶芝,替代郑原,無。 (通常是所有者)夜涕。 |
LSTypeIsPackage | 在“附加文檔類型屬性”表中犯犁。 | 如果文檔數(shù)據(jù)存儲在文件包中,請將此屬性設(shè)置為YES女器。否則省略酸役。 |
有關(guān)這些鍵的更多信息,請參閱信息屬性列表鍵參考中的CFBundleDocumentTypes驾胆。
完成輸入文檔類型的屬性后涣澡,Xcode的“文檔類型”區(qū)域應(yīng)類似于圖2-2中的示例。
圖2-2 Xcode中文檔類型的規(guī)范
應(yīng)用程序可以有多種類型的文檔 - 例如丧诺,文字處理應(yīng)用程序可能具有常規(guī)(空白)文檔的類型入桂,另一種類型可以是預(yù)格式化的文檔。對于每種類型驳阎,您需要通過上面給出的程序抗愁。
導(dǎo)出文檔UTI
如果您為文檔定義了自定義UTI,則還必須導(dǎo)出它搞隐。要導(dǎo)出Xcode中的文檔類型驹愚,首先單擊目標(biāo)信息設(shè)置中的添加按鈕,然后從彈出菜單中選擇添加導(dǎo)出的UTI劣纲。單擊Untitled旁邊的三角形以公開屬性字段逢捺,并添加表2-2中的屬性。
注意:聲明和導(dǎo)出UTI的過程在“統(tǒng)一類型標(biāo)識符概述”中聲明新的統(tǒng)一類型標(biāo)識符中進(jìn)行了說明癞季。
表2-2導(dǎo)出文檔的屬性UTI(UTExportedTypeDeclarations)
鍵 | Xcode字段 | 價(jià)值和評論 |
---|---|---|
UITypeIdentifier | 識別碼 | 自定義文檔UTI劫瞳,一個(gè)字符串倘潜。 |
UTTypeConformsTo | 符合 | UTI符合UTI的自定義文檔。如果數(shù)據(jù)表示是文件包志于,請指定com.apple.package涮因。 |
UTTypeDescription | 描述 | 導(dǎo)出類型的說明(可選)。 |
UTTypeTagSpecification | 在“其他導(dǎo)出的UTI屬性”表中伺绽。 | 創(chuàng)建一個(gè)名為public.filename-extension的數(shù)組养泡。然后作為項(xiàng)目添加文檔文件的所有擴(kuò)展名。 |
有關(guān)這些鍵的更多信息奈应,請參閱信息屬性列表鍵參考中的CFBundleDocumentTypes澜掩。
輸入文檔類型的屬性后,Xcode的Exported UTIs區(qū)域應(yīng)與圖2-3中的示例類似杖挣。
圖2-3在Xcode中導(dǎo)出自定義文檔UTI