轉(zhuǎn)載出處: http://www.reibang.com/p/d3e279de2e32
iOS 后臺(tái)運(yùn)行的規(guī)則
應(yīng)用的運(yùn)行狀態(tài)分為以下五種:
Not running:應(yīng)用還沒有啟動(dòng)光涂,或者應(yīng)用正在運(yùn)行但是途中被系統(tǒng)停止埠况。
Inactive:當(dāng)前應(yīng)用正在前臺(tái)運(yùn)行捅位,但是并不接收事件(當(dāng)前或許正在執(zhí)行其它代碼)绸硕。一般每當(dāng)應(yīng)用要從一個(gè)狀態(tài)切換到另一個(gè)不同的狀態(tài)時(shí),中途過渡會(huì)短暫停留在此狀態(tài)。唯一在此狀態(tài)停留時(shí)間比較長(zhǎng)的情況是:當(dāng)用戶鎖屏?xí)r,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來(lái)電鳍怨、有未讀短信等)事件的時(shí)候。
Active:當(dāng)前應(yīng)用正在前臺(tái)運(yùn)行跪妥,并且接收事件鞋喇。這是應(yīng)用正在前臺(tái)運(yùn)行時(shí)所處的正常狀態(tài)
Suspended:應(yīng)用處在后臺(tái),并且已停止執(zhí)行代碼眉撵。系統(tǒng)自動(dòng)的將應(yīng)用移入此狀態(tài)侦香,且在此舉之前不會(huì)對(duì)應(yīng)用做任何通知落塑。當(dāng)處在此狀態(tài)時(shí),應(yīng)用依然駐留內(nèi)存但不執(zhí)行任何程序代碼罐韩。當(dāng)系統(tǒng)發(fā)生低內(nèi)存告警時(shí)憾赁,系統(tǒng)將會(huì)將處于 Suspended 狀態(tài)的應(yīng)用清除出內(nèi)存以為正在前臺(tái)運(yùn)行的應(yīng)用提供足夠的內(nèi)存。
Background:應(yīng)用處在后臺(tái)散吵,并且還在執(zhí)行代碼龙考。一般的應(yīng)用,都只會(huì)在這個(gè)狀態(tài)短暫停留(最多十分鐘)矾睦,然后就會(huì)被系統(tǒng)強(qiáng)制進(jìn)入 Suspended 狀態(tài)晦款。而 iOS 為了在某些情況下提供更好的體驗(yàn),提供了一些選項(xiàng)枚冗,只要滿足這些選項(xiàng)的條件缓溅,就可以在后臺(tái)運(yùn)行很長(zhǎng)的一段時(shí)間,下面我們將重點(diǎn)討論可以使應(yīng)用在后臺(tái)長(zhǎng)時(shí)間運(yùn)行的方法赁温。
iOS 應(yīng)用狀態(tài)切換示意圖
iOS 提供的后臺(tái)運(yùn)行方式
iOS 提供的后臺(tái)運(yùn)行方式列表
上圖為iOS 提供的后臺(tái)運(yùn)行方式列表坛怪,如果需要,可在 Xcode 的項(xiàng)目設(shè)置中開啟對(duì)應(yīng)的選項(xiàng)股囊。App Store 的審核人員會(huì)檢查應(yīng)用中是否有必要開啟該后臺(tái)運(yùn)行模式選項(xiàng)袜匿,如果應(yīng)用中不需要,而又開啟了這個(gè)選項(xiàng)稚疹,可能會(huì)被拒沉帮。
Audio, AirPlay and Picture in Picture
此個(gè)選項(xiàng)包含四種場(chǎng)景,分別是:音頻的播放贫堰,錄音,AirPlay 及畫中畫的視頻播放待牵。
音頻的播放:在播放音頻時(shí)其屏,即使應(yīng)用退到后臺(tái),只要一直有音頻在播放缨该,那應(yīng)用就可以一直在后臺(tái)運(yùn)行偎行。
代碼實(shí)現(xiàn)可參考:http://www.linuxidc.com/Linux/2012-08/68364.htm
錄音:應(yīng)用可以請(qǐng)求使用麥克風(fēng),而當(dāng)開啟了此后臺(tái)選項(xiàng)贰拿,應(yīng)用在使用麥克風(fēng)的時(shí)候蛤袒,即使退到后臺(tái),也可以一直后臺(tái)運(yùn)行膨更,通過查看微信安裝包中的 plist 文件妙真,微信的語(yǔ)音聊天,就是通過這種方式實(shí)現(xiàn)的荚守。而當(dāng)該類應(yīng)用退到后臺(tái)后珍德,iOS 系統(tǒng)的狀態(tài)欄會(huì)變成紅色练般,并在狀態(tài)欄中顯示正在使用麥克風(fēng)的應(yīng)用的名稱,如下圖所示锈候。
正在使用麥克風(fēng)提示
AirPlay:AirPlay 是指將 iOS 設(shè)備薄料,或者 Mac 設(shè)備上的音視頻,同步到另一個(gè)設(shè)備中播放泵琳。舉兩個(gè)例子摄职,第一個(gè)是把 iPhone 上的音樂通過藍(lán)牙的方式在汽車的藍(lán)牙音響播放,第二個(gè)是把 iPhone 上的視頻获列,同步到智能電視屏幕上播放谷市。此功能一般用于多端及多屏的交互。
關(guān)于 AirPlay 的開發(fā)文檔:http://nto.github.io/AirPlay.html
畫中畫的視頻播放:畫中畫是 iPad 版本的 iOS 9 新增加的功能蛛倦,可以在 iOS 的桌面歌懒,或者其他應(yīng)用的界面的上面播放視頻,從而該視頻區(qū)域所屬的應(yīng)用就可以后臺(tái)運(yùn)行了溯壶。此功能現(xiàn)在只在 iPad 應(yīng)用中提供及皂。
代碼實(shí)現(xiàn)可參考:http://www.cocoachina.com/ios/20150714/12558.html
Location updates
一般用于導(dǎo)航應(yīng)用中,開啟此選項(xiàng)后且改,應(yīng)用退到后臺(tái)验烧,還可以得到系統(tǒng)的定位更新,從而使得應(yīng)用可以根據(jù)定位的變化做出不同的反應(yīng)又跛。
代碼實(shí)現(xiàn)可參考:https://github.com/voyage11/Location
Voice over IP
VOIP 類的應(yīng)用允許用戶使用網(wǎng)絡(luò)而不是手機(jī)打電話碍拆,因此這一類的應(yīng)用需要保持同它相關(guān)的服務(wù)的網(wǎng)絡(luò)連接,用以收到來(lái)電事件和其他數(shù)據(jù)慨蓝。iOS 不是通過一直讓該應(yīng)用處于激活狀態(tài)來(lái)達(dá)到這個(gè)目的感混,而是同樣也會(huì)將這類的應(yīng)用掛起,但同時(shí)會(huì)在應(yīng)用被掛起期間由系統(tǒng)接管它的 VOIP 的 Socket礼烈,當(dāng)這個(gè) Socket 有數(shù)據(jù)通信時(shí)弧满,系統(tǒng)會(huì)再次喚醒處于掛起狀態(tài)的應(yīng)用,同時(shí)將 Socket 的控制權(quán)交還給該應(yīng)用此熬,以讓其正常的處理來(lái)電事件和其他數(shù)據(jù)庭呜。
Newsstand downloads
在 iOS 開發(fā)中,有一類叫報(bào)刊雜志類應(yīng)用比較特別犀忱,在 iOS 9 之前的系統(tǒng)中募谎,此類應(yīng)用會(huì)統(tǒng)一收在系統(tǒng)內(nèi)置的「報(bào)刊雜志」應(yīng)用中,在 iOS 9 中則去掉了內(nèi)置的「報(bào)刊雜志」應(yīng)用阴汇,此類應(yīng)用得以以單獨(dú)的圖標(biāo)入口出現(xiàn)在桌面中数冬。
此后臺(tái)運(yùn)行的選項(xiàng)就是提供給報(bào)刊雜志類應(yīng)用可以在后臺(tái)下載及處理報(bào)刊雜志內(nèi)容,而下載的過程需要使用 NewsstandKit 中的 NKAssetDownload 進(jìn)行下載搀庶。需要注意的是吉执,下載的過程中疯淫,應(yīng)用可能還是會(huì)被掛起,甚至應(yīng)用被退出戳玫,而 iOS 會(huì)在 Wi-Fi 環(huán)境下繼續(xù)下載熙掺,直到下載完成。而一旦下載完成咕宿,如果應(yīng)用只是被掛起币绩,則iOS 會(huì)喚醒對(duì)應(yīng)的應(yīng)用,回調(diào)對(duì)應(yīng)的事件府阀;如果應(yīng)用已經(jīng)退出缆镣,則會(huì)啟動(dòng)應(yīng)用,在啟動(dòng)參數(shù)中會(huì)帶上對(duì)應(yīng)的標(biāo)識(shí)表示這次啟動(dòng)是因?yàn)橄螺d報(bào)刊雜志內(nèi)容完成试浙。
代碼實(shí)現(xiàn)可參考:http://www.viggiosoft.com/blog/blog/2011/10/17/ios-newsstand-tutorial/
External Accessory communication
此選項(xiàng)提供給一些 MFi 外設(shè)通過藍(lán)牙董瞻,或者 Lightning 接頭等方式與 iOS 設(shè)備連接,從而可在外設(shè)發(fā)送消息時(shí)田巴,喚醒已經(jīng)被掛起的應(yīng)用钠糊。而一旦被喚醒,一般情況下壹哺, 應(yīng)用只有最多 10 秒鐘的執(zhí)行時(shí)間抄伍。
MFi 外設(shè):是指通過蘋果 MFi 認(rèn)證的設(shè)備,而 MFi 認(rèn)證是對(duì)其授權(quán)配件廠商生產(chǎn)的外置配件的一種標(biāo)識(shí)使用許可管宵,是 Made for iOS 的英文縮寫截珍。
Uses Bluetooth LE accessories
此選項(xiàng)與 External Accessory communication 類似,只是此選項(xiàng)無(wú)需限制 MFi 外設(shè)箩朴,而需要的是 Bluetooth LE 設(shè)備岗喉。
Acts as a Bluetooth LE accessory
此選項(xiàng)是指 iOS 設(shè)備作為一個(gè)藍(lán)牙外設(shè)連接時(shí),對(duì)應(yīng)的應(yīng)用可以后臺(tái)運(yùn)行炸庞,但是使用此模式需要用戶進(jìn)行授權(quán)認(rèn)證钱床。
Background fetch
iOS 7 新增加的一個(gè)選項(xiàng),用于即使在后臺(tái)燕雁,也需要頻繁更新數(shù)據(jù)的應(yīng)用。例如一個(gè) PM2.5 的應(yīng)用鲸拥,需要幾個(gè)小時(shí)更新一次數(shù)據(jù)拐格,那么可以開啟此選項(xiàng),設(shè)置一個(gè)時(shí)間間隔刑赶,從而讓 iOS 在間隔時(shí)間內(nèi)在后臺(tái)啟動(dòng)該應(yīng)用捏浊,執(zhí)行指定數(shù)據(jù)的獲取工作,而此過程最多只能執(zhí)行 30 秒鐘撞叨。
代碼實(shí)現(xiàn)可參考:http://objccn.io/issue-5-5/
Remote notifications
iOS 7 新增加的一個(gè)選項(xiàng)金踪,是一種靜默推送浊洞,它有別于一般的推送,應(yīng)用收到此類推送后胡岔,不會(huì)有任何的界面提示法希,而當(dāng)應(yīng)用退出或者掛起時(shí)收到此類推送,iOS 也會(huì)啟動(dòng)或者喚醒對(duì)應(yīng)的應(yīng)用靶瘸。
例如一個(gè)閱讀應(yīng)用苫亦,用戶訂閱的博客更新了,那么可以先發(fā)一個(gè)靜默推送怨咪,應(yīng)用收到此種推送后屋剑,可以先把用戶訂閱的博客內(nèi)容都下載好,再通知用戶诗眨,這樣用戶一打開應(yīng)用就可以馬上開始閱讀唉匾。
收到靜默推送,會(huì)回調(diào)對(duì)應(yīng)的回調(diào)方法匠楚,而此回調(diào)方法最多只能執(zhí)行 30 秒鐘巍膘。
代碼實(shí)現(xiàn)可參考:http://objccn.io/issue-5-5/
基于 NSURLSession 的后臺(tái)傳輸
此為 iOS 7 新增加的特性,用于在后臺(tái)下載或者上傳大文件油啤,步驟如下:創(chuàng)建后臺(tái)傳輸用的 NSURLSession 對(duì)象典徘;向這個(gè)對(duì)象中加入對(duì)應(yīng)的傳輸?shù)?NSURLSessionTask,并開始傳輸益咬;在實(shí)現(xiàn) AppDelegate 里實(shí)現(xiàn) -application:handleEventsForBackgroundURLSession:completionHandler: 方法逮诲,以刷新 UI 及通知系統(tǒng)傳輸結(jié)束。
一旦后臺(tái)傳輸?shù)臓顟B(tài)發(fā)生變化(包括正常結(jié)束和失斢母妗)的時(shí)候梅鹦,應(yīng)用將被喚醒并運(yùn)行 AppDelegate 中的回調(diào)。
但是也有一些限制冗锁,后臺(tái)傳輸只會(huì)通過 Wi-Fi 來(lái)進(jìn)行齐唆。后臺(tái)下載的時(shí)間與以前的關(guān)閉應(yīng)用后X分鐘的模式不一樣,而是為了節(jié)省電力變?yōu)殡x散式的下載冻河。
代碼實(shí)現(xiàn)可以參考:http://onevcat.com/2013/08/ios7-background-multitask/
其他后臺(tái)運(yùn)行黑魔法
一直循環(huán)播放一段沒聲音的音頻
可以在后臺(tái)選項(xiàng)中選擇「Audio, AirPlay and Picture in Picture」箍邮,而開始循環(huán)播放一段是沒聲音的音頻,即在 Audio Unit 回調(diào)函數(shù)中使用 kAudioUnitRenderAction_OutputIsSilence 標(biāo)志位叨叙,但是這種方式兩個(gè)大的缺點(diǎn):
1. 蘋果的審核人員如果發(fā)現(xiàn)锭弊,會(huì)被拒;
2. 應(yīng)用程序的 Audio Session 不能被打斷擂错。當(dāng)應(yīng)用執(zhí)行在后臺(tái)時(shí)味滞,只要另一個(gè)應(yīng)用使用 kAudioSessionCategory_RecordAndPlay (比如 Skype)或者 kAudioSessionCategory_SoloAmbientSound,那么該應(yīng)用就會(huì)被立即打斷。
代碼實(shí)現(xiàn)可參考:https://github.com/marcop/MMPDeepSleepPreventer
越獄下開發(fā) System 級(jí)別的應(yīng)用
一般的應(yīng)用都是 Mobile 級(jí)別的剑鞍,在越獄的情況下昨凡,可以開發(fā)一個(gè) System 級(jí)別的應(yīng)用,從而使得應(yīng)用不受 iOS 一般應(yīng)用的限制蚁署,實(shí)現(xiàn)真正的后臺(tái)運(yùn)行便脊,但是缺點(diǎn)就是應(yīng)用只能運(yùn)行在越獄設(shè)備上,也不能上 App Store形用。
代碼實(shí)現(xiàn)可參考:http://www.cnblogs.com/doudouyoutang/p/4712331.html