適用于iOS的應(yīng)用程序編程指南(六)

實施特定應(yīng)用功能的策略

不同的應(yīng)用程序有不同的需求凫岖,但是一些是在許多類型的應(yīng)用程序常見的行為支救,以下部分提供有關(guān)如何在應(yīng)用程序中實現(xiàn)特定類型的功能的指導(dǎo)幢泼。

隱私策略

在設(shè)計應(yīng)用程序時渡嚣,保護(hù)用戶的隱私是重要的考慮因素渣淳。隱私保護(hù)包括保護(hù)用戶的數(shù)據(jù)脾还,包括用戶的身份和個人信息。系統(tǒng)框架已經(jīng)提供隱私控制來管理諸如聯(lián)系人之類的數(shù)據(jù)入愧,但是您的應(yīng)用程序應(yīng)該采取措施保護(hù)您在本地使用的數(shù)據(jù)鄙漏。

使用磁盤加密保護(hù)數(shù)據(jù)

數(shù)據(jù)保護(hù)使用內(nèi)置硬件以磁盤上的加密格式存儲文件嗤谚,并根據(jù)需要進(jìn)行解密。當(dāng)用戶的設(shè)備被鎖定時怔蚌,受保護(hù)的文件是無法訪問的巩步,甚至是創(chuàng)建它們的應(yīng)用程序。在應(yīng)用程序可以訪問其受保護(hù)的文件之前媚创,用戶必須解鎖設(shè)備(通過輸入相應(yīng)的密碼)渗钉。

大多數(shù)iOS設(shè)備都提供數(shù)據(jù)保護(hù),并符合以下要求:

用戶設(shè)備上的文件系統(tǒng)必須支持?jǐn)?shù)據(jù)保護(hù)钞钙。大多數(shù)設(shè)備支持此行為。

用戶必須為設(shè)備設(shè)置一個活動的密碼鎖芒炼。

要保護(hù)文件,請向文件添加一個屬性鲸湃,指示所需的保護(hù)級別。使用NSData類或NSFileManager類添加此屬性暗挑。編寫新文件時斜友,可以使用具有相應(yīng)保護(hù)值的writeDataFile:options:NSData的error:method作為寫入選項之一。對于現(xiàn)有文件鲜屏,可以使用NSFileManager的setAttributes:ofItemAtPath:error:method來設(shè)置或更改NSFileProtectionKey的值。使用這些方法時洛史,請為文件指定以下保護(hù)級別之一:

無保護(hù) - 文件已加密惯殊,但不受密碼保護(hù),并在設(shè)備鎖定時可用也殖。指定NSDataWritingFileProtectionNone選項(NSData)或NSFileProtectionNone屬性(NSFileManager)土思。

完成 - 設(shè)備被鎖定時,文件被加密并且不可訪問忆嗜。指定NSDataWritingFileProtectionComplete選項(NSData)或NSFileProtectionComplete屬性(NSFileManager)己儒。

完成,除非已經(jīng)打開 - 文件已加密霎褐。當(dāng)設(shè)備被鎖定時,無法訪問關(guān)閉的文件该镣。用戶解鎖設(shè)備后冻璃,您的應(yīng)用程序可以打開該文件并使用該文件。如果用戶在文件打開時鎖定設(shè)備,您的應(yīng)用程序可以繼續(xù)訪問它省艳。指定NSDataWritingFileProtectionCompleteUnlessOpen選項(NSData)或NSFileProtectionCompleteUnlessOpen屬性(NSFileManager)娘纷。

完成,直到第一次登錄 - 文件被加密跋炕,無法訪問赖晶,直到設(shè)備啟動并且用戶已解鎖一次。指定NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication選項(NSData)或NSFileProtectionCompleteUntilFirstUserAuthentication屬性(NSFileManager)辐烂。

如果您保護(hù)文件遏插,您的應(yīng)用程序必須準(zhǔn)備好丟失對該文件的訪問。啟用完整的文件保護(hù)后纠修,當(dāng)用戶鎖定設(shè)備時胳嘲,您的應(yīng)用程序?qū)⑹プx取和寫入文件內(nèi)容的能力。您可以使用以下技術(shù)之一跟蹤對受保護(hù)文件狀態(tài)的更改:

應(yīng)用程序委托可以實現(xiàn)applicationProtectedDataWillBecomeUnavailable:和applicationProtectedDataDidBecomeAvailable:methods扣草。

任何對象都可以注冊UIApplicationProtectedDataWillBecomeUnavailable和UIApplicationProtectedDataDidBecomeAvailable通知了牛。

任何對象都可以檢查共享UIApplication對象的protectedDataAvailable屬性的值,以確定文件當(dāng)前是否可訪問鹰祸。

對于新文件蛙婴,建議您在寫入任何數(shù)據(jù)之前啟用數(shù)據(jù)保護(hù)敬锐。如果使用writeToFile:options:error:方法將NSData對象的內(nèi)容寫入磁盤台夺,則會自動進(jìn)行。對于現(xiàn)有文件颤介,添加數(shù)據(jù)保護(hù)將使用新的受保護(hù)版本替換未受保護(hù)的文件滚朵。

識別您的應(yīng)用程序的唯一用戶

只有在這樣做時辕近,才能識別應(yīng)用程序的用戶移宅,才能為該用戶提供明確的收益漏峰。如果您只需要將應(yīng)用的一個用戶與其他用戶區(qū)分開來倔喂,則iOS提供可幫助您執(zhí)行此操作的標(biāo)識符席噩。但是班挖,如果您需要更高級別的安全性萧芙,您可能需要自己做更多的工作双揪。例如渔期,提供金融服務(wù)的應(yīng)用程序可能希望提示用戶登錄憑據(jù)疯趟,以確保用戶有權(quán)訪問特定帳戶信峻。

重要提示:在識別用戶時,始終要透明了解您獲取的任何信息的意圖踢步。識別用戶是不可接受的丑掺,防止您可以偷偷跟蹤它們兼丰。

以下是一些常見的情況地粪,可能需要您識別用戶蟆技,以及如何實現(xiàn)它們的解決方案质礼。

您希望將用戶鏈接到服務(wù)器上的特定帳戶眶蕉。包括登錄屏幕,要求用戶安全地輸入帳戶信息饭入。通過以加密形式存儲肛真,始終保護(hù)您從用戶收集的帳戶信息乾忱。

您想?yún)^(qū)分不同設(shè)備上運行的應(yīng)用程序的實例窄瘟。使用UIDevice類的identifierForVendor屬性來獲取一個區(qū)分一個設(shè)備上的用戶與其他設(shè)備上的用戶的ID∧ぃ現(xiàn)在新蟆,該技術(shù)可以讓您識別特定的用戶。單個用戶可以具有多個設(shè)備帕翻,每個設(shè)備具有不同的ID值。

您想要為廣告目的識別用戶。使用ASIdentifierManager類的advertisingIdentifier屬性獲取用戶的ID泉蝌。

由于用戶可以在所有iOS設(shè)備上運行應(yīng)用程序勋陪,因此Apple不提供在多個設(shè)備上識別同一用戶的方法诅愚。如果您需要識別特定用戶,則必須使用普遍唯一的ID(UUID)等浊,登錄帳戶或其他類型的身份識別系統(tǒng)提供您自己的解決方案筹燕。

評級限制

用戶可以設(shè)置限制撒踪,指定要在應(yīng)用程序中使用的媒體的評級。如果您的應(yīng)用程序根據(jù)限制播放媒體或修改其行為泵三,則需要確定當(dāng)前設(shè)置并在設(shè)置更改時進(jìn)行響應(yīng)俺抽。

要獲取當(dāng)前設(shè)置,請獲取共享的standardUserDefaults對象冕末,并使用objectForKey:方法查看以下項的值:

媒體評級鍵值

com.apple.content-rating.ExplicitBooksAllowed

布爾档桃。如果此鍵的值為NO,則不允許顯式書籍

com.apple.content-rating.ExplicitMusicPodcastsAllowed

布爾。如果此鍵的值為NO斗幼,則不允許顯示音樂蜕窿,電影和播客毁兆。

com.apple.content-rating.AppRating

的NSNumber气堕。該鍵的值范圍為0到1000.不允許其評級高于當(dāng)前鍵值的應(yīng)用程序。

com.apple.content-rating.MovieRating

的NSNumber畔咧。該鍵的值范圍為0到1000.不允許其分級高于當(dāng)前鍵值的影片茎芭。

com.apple.content-rating.TVShowRating

的NSNumber。該鍵的值范圍為0到1000.不允許其等級高于當(dāng)前鍵值的電視節(jié)目誓沸。

注意:如果objectForKey:為特定鍵返回nil梅桩,則表示有關(guān)此特定限制的信息不可用。在這種情況下拜隧,您的應(yīng)用程序可以使用自己的策略來確定適當(dāng)?shù)脑u級宿百。

要檢測用戶何時更改限制洪添,請注冊通知NSUserDefaultsDidChangeNotification宋光。共享的standardUserDefaults對象在檢測到位于其中一個持久域中的首選項的更改時赘艳,會將此通知發(fā)送到您的應(yīng)用程序旭蠕。

應(yīng)用程序評級是針對我們的國家/地區(qū)代碼定義的旗芬,并被普遍應(yīng)用。表5-1顯示了與每個美國應(yīng)用程序評級相關(guān)聯(lián)的值。

表5-1應(yīng)用程序評分

評分名稱

數(shù)值

4+

100

9+

200

12+

300

17+

600

電影和電視的評分因國家而異定鸟。如果一個國家或地區(qū)沒有為電影或電視節(jié)目指定評級系統(tǒng)季眷,您的應(yīng)用程序應(yīng)使用自己的策略來確定適當(dāng)?shù)脑u級挺峡。雖然大多數(shù)地區(qū)定義電影評級,但只有少數(shù)人定義電視節(jié)目評分暖眼。

區(qū)域可以定義多個評級級別,每個級別與描述評級的名稱和范圍為0到1000的數(shù)字相關(guān)聯(lián)嫩絮。例如,美國使用字符串“G”,數(shù)字100指定最低級別電影評級等級。

即使您的應(yīng)用沒有播放媒體椅您,也可能需要將自己的評分系統(tǒng)映射到電影或電視節(jié)目評分系統(tǒng)马僻。例如溶弟,只有當(dāng)美國電影評級“R”被允許時菜拓,游戲才能啟用某些功能俺夕。要查看當(dāng)前的評分列表劝贸,請下載此文檔的伴隨文件(鏈接位于頁面頂部)。

支持多種版本的iOS

支持最新版本的iOS以及一個或多個早期版本的應(yīng)用程序必須使用運行時檢查來防止在舊版本的iOS上使用較新的API。運行時檢查會阻止您的應(yīng)用程序在嘗試使用當(dāng)前操作系統(tǒng)上不可用的功能時崩潰曾我。

您可以進(jìn)行幾種類型的檢查:

要確定一個類是否存在悦陋,請查看它的Class對象是否為nil踏揣。鏈接器對于任何未知的類對象返回nil捞稿,使得可以使用類似于以下的條件檢查:

if ([UIPrintInteractionController class]) {

// Create an instance of the class anduse it.

}

else {

// The print interaction controller isnot available so use an alternative technique.

}

要確定方法是否可用于現(xiàn)有類,請使用instancesRespondToSelector:class方法或respondToSelector:instance方法拼缝。

要確定基于C的函數(shù)是否可用娱局,請執(zhí)行函數(shù)名為NULL的布爾比較。如果符號不為NULL珍促,則可以調(diào)用該函數(shù)铃辖。例如:

if(UIGraphicsBeginPDFPage!= NULL){

UIGraphicsBeginPDFPage();

}

有關(guān)如何編寫支持多個部署目標(biāo)的代碼的更多信息和示例猪叙,請參閱SDK兼容性指南娇斩。SDK Compatibility Guide

保持你的應(yīng)用程序的視覺外觀Across Launches

即使您的應(yīng)用程序支持后臺執(zhí)行,也不能永久運行穴翩。在某些時候犬第,系統(tǒng)可能需要終止您的應(yīng)用程序以釋放當(dāng)前前臺應(yīng)用程序的內(nèi)存。但是芒帕,用戶不應(yīng)該關(guān)心應(yīng)用程序是否已在運行或終止歉嗓。從用戶的角度來說,退出應(yīng)用程序似乎暫時中斷背蟆。當(dāng)用戶返回到應(yīng)用程序時鉴分,該應(yīng)用程序應(yīng)始終將用戶返回到最后一個使用點,以便用戶可以繼續(xù)執(zhí)行任何正在進(jìn)行的任務(wù)带膀。這種行為為用戶提供了更好的體驗志珍,并且與UIKit內(nèi)置的狀態(tài)恢復(fù)支持相對容易實現(xiàn)。

UIKit中的狀態(tài)保存系統(tǒng)提供了一個簡單但靈活的基礎(chǔ)設(shè)施垛叨,用于保存和恢復(fù)應(yīng)用程序視圖控制器和視圖的狀態(tài)伦糯。基礎(chǔ)設(shè)施的工作是在適當(dāng)?shù)臅r候推動維護(hù)和恢復(fù)過程嗽元。為此敛纲,UIKit需要您的應(yīng)用程序的幫助。只有您了解您的應(yīng)用程序的內(nèi)容剂癌,因此只有您可以編寫保存和還原該內(nèi)容所需的代碼淤翔。當(dāng)您更新應(yīng)用程序的UI時,只有您知道如何將較舊的保留內(nèi)容映射到界面中的較新對象佩谷。

你有三個地方必須在你的應(yīng)用程序中考慮狀態(tài)保存:

您的應(yīng)用程序委托對象旁壮,它管理應(yīng)用程序的頂級狀態(tài)

您的應(yīng)用程序的視圖控制器對象辞做,用于管理應(yīng)用程序用戶界面的整體狀態(tài)

您的應(yīng)用的自定義視圖,可能有一些需要保留的自定義數(shù)據(jù)

UIKit允許您選擇要保留的用戶界面的哪些部分寡具。如果您已經(jīng)有處理狀態(tài)保存的自定義代碼秤茅,則可以繼續(xù)使用該代碼,并根據(jù)需要將部分遷移到UIKit狀態(tài)保存系統(tǒng)童叠。

在您的應(yīng)用程序中啟用狀態(tài)保存和恢復(fù)

狀態(tài)保存和恢復(fù)不是自動功能框喳,應(yīng)用程序必須選擇使用它。應(yīng)用程序通過在其應(yīng)用程序委托中實施以下方法來表明他們對該功能的支持:

應(yīng)用:shouldSaveApplicationState:

應(yīng)用:shouldRestoreApplicationState:

通常厦坛,這些方法的實現(xiàn)只是返回YES五垮,表示可以發(fā)生狀態(tài)保存和恢復(fù)。但是杜秸,要在不發(fā)生操作的情況下放仗,有條件地保留和恢復(fù)狀態(tài)的應(yīng)用程序可以返回NO。例如撬碟,在發(fā)布對您的應(yīng)用程序的更新后诞挨,您可能希望從應(yīng)用程序返回NO:shouldRestoreApplicationState:方法,如果您的應(yīng)用程序無法從先前版本有效地還原狀態(tài)呢蛤。

保存和恢復(fù)過程

狀態(tài)保存和恢復(fù)是一個選擇加入功能惶傻,并在您的應(yīng)用程序的幫助下工作。您的應(yīng)用程序標(biāo)識應(yīng)該保留的對象其障,UIKit會在適當(dāng)?shù)臅r候執(zhí)行保存和還原這些對象的工作银室。因為UIKit處理這么多的過程,所以它有助于了解它在幕后做的事情励翼,以便您了解自定義代碼如何適應(yīng)整體方案蜈敢。

在考慮狀態(tài)保護(hù)和恢復(fù)時,首先有助于分離兩個進(jìn)程汽抚。 UIKit會在適當(dāng)?shù)臅r間保留應(yīng)用的狀態(tài)抓狭,例如當(dāng)您的應(yīng)用程序從前臺移動到后臺時。當(dāng)UIKit確定需要新的狀態(tài)信息時殊橙,它會查看應(yīng)用程序的視圖和視圖控制器辐宾,以查看哪些應(yīng)該保留狱从。對于每個對象膨蛮,UIKit將保存相關(guān)數(shù)據(jù)寫入加密的磁盤文件。下一次您的應(yīng)用程序從頭開始季研,UIKit會查找該文件敞葛,如果存在,則使用它來嘗試恢復(fù)應(yīng)用程序的狀態(tài)与涡。因為文件是加密的惹谐,所以狀態(tài)保存和恢復(fù)只有在設(shè)備解鎖時才會發(fā)生持偏。

在恢復(fù)過程中,UIKit使用保留的數(shù)據(jù)重新構(gòu)建您的界面氨肌,但實際對象的創(chuàng)建將由您的代碼來處理鸿秆。因為您的應(yīng)用程序可能會自動從故事板文件加載對象,只有您的代碼知道需要創(chuàng)建哪些對象怎囚,哪些對象可能已經(jīng)存在卿叽,并且可以簡單地返回。在創(chuàng)建每個對象之后恳守,UIKit將使用保留的狀態(tài)信息來初始化它們考婴。

在保存和恢復(fù)過程中,您的應(yīng)用程序有很少的責(zé)任催烘。

在保存期間沥阱,您的應(yīng)用程序負(fù)責(zé):

告訴UIKit它支持狀態(tài)保存。

告訴UIKit應(yīng)該保留哪些視圖控制器和視圖伊群。

編碼任何保留對象的相關(guān)數(shù)據(jù)考杉。

在恢復(fù)期間,您的應(yīng)用程序負(fù)責(zé):

告訴UIKit它支持狀態(tài)恢復(fù)舰始。

提供(或創(chuàng)建)UIKit請求的對象奔则。

解碼保存對象的狀態(tài)并使用它將對象返回到之前的狀態(tài)。

在應(yīng)用程序的責(zé)任方面蔽午,最重要的是告訴UIKit在后續(xù)啟動期間保留哪些對象并提供這些對象易茬。 這兩個行為是設(shè)計應(yīng)用程序的保存和恢復(fù)代碼時應(yīng)該花費大部分時間的地方。他們也是您對實際過程最有控制力的地方及老。 為了理解為什么會這樣抽莱,它有助于看一個例子。

圖5-1顯示了用戶與幾個選項卡進(jìn)行交互之后骄恶,選項卡欄界面的視圖控制器層次結(jié)構(gòu)食铐。 您可以看到,一些視圖控制器將自動加載作為應(yīng)用程序的主要故事板文件的一部分僧鲁,但是某些視圖控制器已被呈現(xiàn)或被推送到不同選項卡中的視圖控制器上虐呻。在沒有狀態(tài)恢復(fù)的情況下,僅在主故事板文件中的視圖控制器將在后續(xù)啟動期間恢復(fù)寞秃。 通過添加對狀態(tài)恢復(fù)的支持斟叼,您可以保留所有的視圖控制器。


圖5-1示例視圖控制器層次結(jié)構(gòu)

UIKit僅保留那些具有分配的恢復(fù)標(biāo)識符的對象春寿。 恢復(fù)標(biāo)識符是一個字符串朗涩,用于標(biāo)識UIKit和您的應(yīng)用程序的視圖或視圖控制器。此字符串的值僅對您的代碼有意義绑改,但是此字符串的存在告訴UIKit它需要保留標(biāo)記的對象谢床。

在保存過程中兄一,UIKit會拖動應(yīng)用程序的視圖控制器層次結(jié)構(gòu),并保留具有恢復(fù)標(biāo)識符的所有對象识腿。如果視圖控制器沒有恢復(fù)標(biāo)識符出革,則該視圖控制器及其所有視圖和子視圖控制器都不會被保留。 圖5-2顯示了先前視圖層次結(jié)構(gòu)的更新版本渡讼,現(xiàn)在具有應(yīng)用于大多數(shù)(但不是全部)視圖控制器的恢復(fù)標(biāo)識蹋盆。


圖5-2添加恢復(fù)標(biāo)識查看控制器

根據(jù)您的應(yīng)用程序,保留每個視圖控制器可能或可能無意義硝全。如果視圖控制器顯示臨時信息栖雾,則可能不希望在恢復(fù)時返回到同一點,而是選擇將用戶返回到界面中更穩(wěn)定的位置伟众。

對于您選擇保留的每個視圖控制器析藕,您還需要確定以后如何還原它。 UIKit提供了兩種重建對象的方式。您可以讓您的應(yīng)用程序委托重新創(chuàng)建它,或者您可以將恢復(fù)類分配給視圖控制器欠拾,并讓該類重新創(chuàng)建它≈文啵恢復(fù)類實現(xiàn)UIViewControllerRestoration協(xié)議,并負(fù)責(zé)在還原時查找或創(chuàng)建指定的對象遮精。以下是有關(guān)何時使用每一個的提示:

如果視圖控制器在啟動時始終從應(yīng)用程序的主要故事板文件中加載居夹,請不要分配恢復(fù)類。相反本冲,讓您的應(yīng)用程序委托找到該對象准脂,或者利用UIKit的支持來隱式查找恢復(fù)的對象。

對于在啟動時未從主故事板文件加載的視圖控制器檬洞,請分配恢復(fù)類狸膏。最簡單的選擇是使每個視圖控制器都有自己的恢復(fù)類。

在保存過程中添怔,UIKit識別要保存并將每個受影響對象的狀態(tài)寫入磁盤的對象湾戳。每個視圖控制器對象都有機(jī)會寫出任何要保存的數(shù)據(jù)。例如广料,選項卡視圖控制器保存所選選項卡的標(biāo)識砾脑。UIKit還將視圖控制器的恢復(fù)類信息保存到磁盤。如果任何視圖控制器的視圖具有恢復(fù)標(biāo)識符性昭,UIKit也會要求它們保存狀態(tài)信息拦止。

下一次應(yīng)用程序啟動時县遣,UIKit照常加載應(yīng)用程序的主要故事板或nib文件糜颠,調(diào)用應(yīng)用程序委托的應(yīng)用程序:willFinishLaunchingWithOptions:方法汹族,然后嘗試恢復(fù)應(yīng)用程序的上一個狀態(tài)。它的第一件事是要求您的應(yīng)用程序提供與保留的控件對象匹配的一組視圖控制器對象其兴。如果給定的視圖控制器具有分配的恢復(fù)類顶瞒,則要求該類提供對象;否則,應(yīng)用程序代理被要求提供元旬。

保存過程的流程

圖5-3顯示了在狀態(tài)保存期間發(fā)生的高級事件榴徐,并顯示了應(yīng)用程序的對象如何受到影響。在保存甚至發(fā)生之前匀归,UIKit會通過調(diào)用應(yīng)用程序來發(fā)出應(yīng)用程序委托:shouldSaveApplicationState:method坑资。如果該方法返回YES,則UIKit將開始收集和編碼應(yīng)用程序的視圖和視圖控制器穆端。完成后袱贮,將編碼的數(shù)據(jù)寫入磁盤。


圖5-3高級流界面保存

下次應(yīng)用程序啟動時体啰,系統(tǒng)會自動查找保留的狀態(tài)文件攒巍,如果存在,則使用它來恢復(fù)您的界面荒勇。由于此狀態(tài)信息僅與應(yīng)用程序的上一個和當(dāng)前啟動周期相關(guān)柒莉,因此在應(yīng)用程序完成啟動后,該文件通常會被丟棄沽翔。只要恢復(fù)您的應(yīng)用程序出現(xiàn)錯誤兢孝,該文件也會被丟棄。例如仅偎,如果您的應(yīng)用程序在恢復(fù)過程中崩潰西潘,系統(tǒng)會在下一個啟動周期內(nèi)自動丟棄狀態(tài)信息,以避免再次崩潰哨颂。

恢復(fù)過程的流程

圖5-4顯示了狀態(tài)恢復(fù)期間發(fā)生的高級別事件喷市,并顯示了應(yīng)用程序的對象如何受到影響。標(biāo)準(zhǔn)初始化和UI加載完成后威恼,UIKit會通過調(diào)用應(yīng)用程序來調(diào)用應(yīng)用程序:shouldRestoreApplicationState:method來請求您的應(yīng)用程序委托狀態(tài)恢復(fù)品姓。這是您的應(yīng)用程序代理機(jī)會檢查保留的數(shù)據(jù),并確定是否可以恢復(fù)狀態(tài)箫措。如果是腹备,UIKit使用應(yīng)用程序委托和恢復(fù)類來獲取對應(yīng)用程序的視圖控制器的引用。然后向每個對象提供需要將其恢復(fù)到其先前狀態(tài)的數(shù)據(jù)斤蔓。


圖5-4恢復(fù)用戶界面的高級流程

雖然UIKit有助于還原各個視圖控制器植酥,但它不會自動恢復(fù)這些視圖控制器之間的關(guān)系。相反,每個視圖控制器負(fù)責(zé)編碼足夠的狀態(tài)信息以將其自身恢復(fù)到其先前的狀態(tài)友驮。例如漂羊,導(dǎo)航控制器對其導(dǎo)航堆棧上的視圖控制器的順序的信息進(jìn)行編碼。然后卸留,它稍后使用此信息將這些視圖控制器返回到堆棧上的先前位置走越。具有嵌入式子視圖控制器的其他視圖控制器同樣負(fù)責(zé)編碼他們以后要還原他們的孩子所需的任何信息。

注意:并非所有視圖控制器都需要對子視圖控制器進(jìn)行編碼耻瑟。例如旨指,標(biāo)簽欄控制器不編碼有關(guān)其子視圖控制器的信息。相反喳整,假設(shè)您的應(yīng)用程序遵循在創(chuàng)建標(biāo)簽欄控制器本身之前創(chuàng)建適當(dāng)?shù)淖右晥D控制器的常規(guī)模式谆构。

由于您負(fù)責(zé)重新創(chuàng)建應(yīng)用程序的視圖控制器,因此您可以在恢復(fù)過程中更改您的界面框都。例如低淡,您可以重新排序標(biāo)簽欄控制器中的選項卡,并仍然使用保留的數(shù)據(jù)將每個選項卡返回到之前的狀態(tài)

瞬项。當(dāng)然蔗蹋,如果您對視圖控制器層次結(jié)構(gòu)進(jìn)行了顯著的更改,例如在應(yīng)用程序更新期間囱淋,您可能無法使用保留的數(shù)據(jù)猪杭。

當(dāng)您排除視圖控制器組時會發(fā)生什么?

當(dāng)視圖控制器的恢復(fù)標(biāo)識符為零時妥衣,該視圖控制器及其管理的任何子視圖控制器不會自動保留皂吮。例如,在圖5-5中税手,由于導(dǎo)航控制器沒有恢復(fù)標(biāo)識符蜂筹,因此從保留的數(shù)據(jù)中省略它及其所有子視圖控制器和視圖。


圖5-5從自動保存過程中排除視圖控制器

即使您決定不保留視圖控制器芦倒,這并不意味著所有這些視圖控制器完全從視圖層次結(jié)構(gòu)中消失艺挪。 在啟動時,您的應(yīng)用程序仍然可以創(chuàng)建視圖控制器作為其默認(rèn)設(shè)置的一部分兵扬。例如麻裳,如果任何視圖控制器從應(yīng)用程序的故事板文件自動加載,它們?nèi)詫⒊霈F(xiàn)器钟,盡管是默認(rèn)配置津坑,如圖5-6所示。



圖5-6加載默認(rèn)視圖控制器

還有一點需要注意的是傲霸,即使視圖控制器沒有自動保留疆瑰,您仍然可以編碼對該視圖控制器的引用并手動保留眉反。在圖5-5中,第一導(dǎo)航控制器的三個子視圖控制器具有恢復(fù)標(biāo)識符穆役,即使父導(dǎo)航控制器沒有寸五。如果您的應(yīng)用程序委托(或任何保留的對象)編碼對這些視圖控制器的引用

,則會保留其狀態(tài)孵睬。即使導(dǎo)航控制器中的命令未被保存播歼,您仍然可以使用這些引用來重新創(chuàng)建視圖控制器伶跷,并在后續(xù)的啟動周期將它們安裝在導(dǎo)航控制器中掰读。

實施狀態(tài)保護(hù)和恢復(fù)清單

支持狀態(tài)保存和恢復(fù)需要修改您的應(yīng)用程序委托并查看控制器對象以對狀態(tài)信息進(jìn)行編碼和解碼。如果您的應(yīng)用程序有任何自定義視圖也具有可保留的狀態(tài)信息叭莫,那么您還需要修改這些對象蹈集。

在您的代碼中添加狀態(tài)保存和恢復(fù)時,請使用以下列表來提醒您需要編寫的代碼雇初。

(必需)實現(xiàn)應(yīng)用程序:shouldSaveApplicationState:和應(yīng)用程序:shouldRestoreApplicationState:應(yīng)用程序委托中的方法;請參閱在您的應(yīng)用程序中啟用狀態(tài)保存和恢復(fù)拢肆。

(必需)通過為其restoreIdentifier屬性分配一個非空字符串,將恢復(fù)標(biāo)識符分配給要保留的每個視圖控制器;請參閱標(biāo)記您的視圖控制器進(jìn)行保存靖诗。

如果要保存特定視圖的狀態(tài)郭怪,請將非空字符串分配給它們的restoreIdentifier屬性;看保持你的意見狀態(tài)。

(必需)從應(yīng)用程序顯示應(yīng)用程序的窗口:willFinishLaunchingWithOptions:應(yīng)用程序委托的方法刊橘。狀態(tài)恢復(fù)機(jī)構(gòu)需要窗口鄙才,以便可以恢復(fù)應(yīng)用程序界面的滾動位置和其他相關(guān)位。

將修復(fù)類分配給相應(yīng)的視圖控制器促绵。 (如果不這樣做攒庵,您的應(yīng)用程序委托被要求在還原時提供相應(yīng)的視圖控制器。)請參閱在啟動時恢復(fù)視圖控制器败晴。

(推薦)使用encodeRestorableStateWithCoder:和decodeRestorableStateWithCoder編碼和解碼視圖的狀態(tài)并查看控制器:這些對象的方法;請參閱編碼和解碼視圖控制器的狀態(tài)浓冒。

使用應(yīng)用程序?qū)?yīng)用程序的任何版本信息或其他狀態(tài)信息進(jìn)行編碼和解碼:willEncodeRestorableStateWithCoder:和應(yīng)用程序:didDecodeRestorableStateWithCoder:應(yīng)用程序委托的方法;請參閱保存應(yīng)用程序的高級狀態(tài)。

作為表視圖和集合視圖的數(shù)據(jù)源的對象應(yīng)實現(xiàn)UIDataSourceModelAssociation協(xié)議尖坤。雖然不是必需的稳懒,但是該協(xié)議有助于在這些類型的視圖中保留所選和可見的項目。請參閱實施易于維護(hù)的數(shù)據(jù)源慢味。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末僚祷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贮缕,更是在濱河造成了極大的恐慌辙谜,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件感昼,死亡現(xiàn)場離奇詭異装哆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門蜕琴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萍桌,“玉大人,你說我怎么就攤上這事凌简∩涎祝” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵雏搂,是天一觀的道長藕施。 經(jīng)常有香客問我,道長凸郑,這世上最難降的妖魔是什么裳食? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮芙沥,結(jié)果婚禮上诲祸,老公的妹妹穿的比我還像新娘。我一直安慰自己而昨,他們只是感情好救氯,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著歌憨,像睡著了一般着憨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躺孝,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天享扔,我揣著相機(jī)與錄音,去河邊找鬼植袍。 笑死惧眠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的于个。 我是一名探鬼主播氛魁,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厅篓!你這毒婦竟也來了秀存?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤羽氮,失蹤者是張志新(化名)和其女友劉穎或链,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體档押,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡澳盐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年祈纯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叼耙。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡腕窥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出筛婉,到底是詐尸還是另有隱情簇爆,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布爽撒,位于F島的核電站入蛆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏匆浙。R本人自食惡果不足惜安寺,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一厕妖、第九天 我趴在偏房一處隱蔽的房頂上張望首尼。 院中可真熱鬧,春花似錦言秸、人聲如沸软能。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽查排。三九已至,卻和暖如春抄沮,著一層夾襖步出監(jiān)牢的瞬間跋核,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工叛买, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留砂代,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓率挣,卻偏偏與公主長得像刻伊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子椒功,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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