在之前的項目中被iOS應用后臺常駐這一問題所困擾,很多解決方法都有瑕疵,在應用審核時很容易被pass,比如:播放無聲音頻、調(diào)用定位等通過后臺任務實現(xiàn)方法。在查看文檔時,偶然的機遇發(fā)現(xiàn)了UIStateRestoration這個類,這不就能實現(xiàn)類似于"后臺常駐"的效果了嘛,果斷研究了一下。

UIStateRestoration簡介
狀態(tài)恢復(State Restoration)是在應用重新啟動時恢復到上一次結(jié)束時的狀態(tài)。當APP切到后臺,很難保證應用不被用戶或系統(tǒng)殺掉。如果希望應用長時間在前臺,顯然這種被殺掉的結(jié)果不是產(chǎn)品經(jīng)理想要的。
產(chǎn)品經(jīng)理:我想要的是當用戶打開APP時,給用戶一種App從來沒有被關閉的感覺,這種無縫順滑、渾然一體的感覺才是我想要的,要讓用戶模糊啟動和退出的概念。
程序員:哦。
在iOS 6.0中,蘋果為我們提供了UIStateRestoration來實現(xiàn)應用狀態(tài)的保持和恢復。
APP的生命周期

這張圖很常見吧,大多數(shù)APP的生命周期都要遵循以
下的狀態(tài)流程:
Not running -> Inactive -> Active -> Background -> Suspended -> Not Running(killed)App從未運行狀態(tài),到被用戶點擊后,進入運行狀態(tài),App進入前臺,顯示啟動畫面,然后將控制權交給App本身,此時App是活動狀態(tài),如果用戶點擊“Home”鍵,App會進入后臺,如果此時的App沒有開啟后臺多任務支持,在沒有特別設計的情況下,不多久App就會進入 Suspended 狀態(tài),程序被掛起。如果系統(tǒng)在內(nèi)存需求足夠的情況下,是不會主動殺死這些已經(jīng) Suspended 的App的,這樣用戶在再次啟動應用時,App會保持上次退出的狀態(tài),這樣會給用戶帶來一種無縫的體驗,模糊啟動和退出的概念。而當用戶主動殺死應用,或者系統(tǒng)因為內(nèi)存不足而將掛起應用殺死時,用戶再次點擊APP時會有明顯的二次啟動的感覺。
而當我們開啟應用狀態(tài)保存后,app的狀態(tài)流程就會是這個樣子。

UIStateRestoration接口介紹


蘋果推出UIStateRestoration類的目的應該是希望應用能給用戶帶來順滑的體驗,讓APP能快速地還原到用戶上次的停留點。接下來讓我們開始吧!
1.在Application Delegate中啟動狀態(tài)保持
// 開啟應用狀態(tài)保存
- (BOOL) application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
return YES;
}
// 開啟應用狀態(tài)回復
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
return YES;
}
當shouldSaveApplicationState回調(diào)是在進入后臺的瞬間詢問的,如果返回值是YES,程序會在當前應用的沙盒文件中Library文件夾下創(chuàng)建狀態(tài)保存目錄Saved Application State用于存儲相關數(shù)據(jù)。

在存儲數(shù)據(jù)的同時,程序還會創(chuàng)建一個快照,以替換Default.png在iOS App switcher中顯示,我們在下次啟動的時候, 就不會顯示默認的啟動圖片, 而是上次退出應用前的UI快照。

2.UIViewController操作
當需要對具體UI進行操作時,需要在UIViewController中通過接口來實現(xiàn)狀態(tài)的保存。

下面簡單介紹一下這些接口功能:
- restorationIdentifier:為當前的ViewController 設置一個標識,以在恢復時使用。
- restorationClass:類名,在恢復時使用,此類需要實現(xiàn) UIViewControllerRestoration。
- encodeRestorableStateWithCoder:序列化時回調(diào)接口,用于手動存儲當前的對象的狀態(tài)。
- decodeRestorableStateWithCoder:實例化時回調(diào)接口,用于手動恢復存儲對象的狀態(tài)。
- applicationFinishedRestoringState:在實例化完成后調(diào)用,可以用于完成一些附加的業(yè)務邏輯。
舉個例子:

調(diào)試方法
- 在Xcode中運行程序
- 在模擬器/真機設備上按Home鍵返回桌面
- 在Xcode中結(jié)束程序運行
- 再次run,run,run
后記
- 多看文檔有好處
- 文章大部分是引用別人已有成果,我只不過是站在巨人的肩膀上以自己的邏輯來寫文章
- 如果有不對之處,還希望指出來。
- 關于不同設備Crash的臨界值可以通過下面的鏈接查看別人的答案,其中還分享了一個測試Crash臨界值的工具。
蘋果設備內(nèi)存Crash臨界值查詢
