下面說一下background modes
最近開發(fā)的時候在 background modes 遇到的一些問題先簡單街道一個background modes
iOS 后臺運行的規(guī)則
應(yīng)用的運行狀態(tài)分為以下五種:
Not running:應(yīng)用還沒有啟動,或者應(yīng)用正在運行但是途中被系統(tǒng)停止。
Inactive:當(dāng)前應(yīng)用正在前臺運行强经,但是并不接收事件(當(dāng)前或許正在執(zhí)行其它代碼)。一般每當(dāng)應(yīng)用要從一個狀態(tài)切換到另一個不同的狀態(tài)時赏僧,中途過渡會短暫停留在此狀態(tài)。唯一在此狀態(tài)停留時間比較長的情況是:當(dāng)用戶鎖屏?xí)r扭倾,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來電淀零、有未讀短信等)事件的時候。
Active:當(dāng)前應(yīng)用正在前臺運行膛壹,并且接收事件驾中。這是應(yīng)用正在前臺運行時所處的正常狀態(tài)
Suspended:應(yīng)用處在后臺唉堪,并且已停止執(zhí)行代碼。系統(tǒng)自動的將應(yīng)用移入此狀態(tài)肩民,且在此舉之前不會對應(yīng)用做任何通知唠亚。當(dāng)處在此狀態(tài)時,應(yīng)用依然駐留內(nèi)存但不執(zhí)行任何程序代碼持痰。當(dāng)系統(tǒng)發(fā)生低內(nèi)存告警時灶搜,系統(tǒng)將會將處于 Suspended 狀態(tài)的應(yīng)用清除出內(nèi)存以為正在前臺運行的應(yīng)用提供足夠的內(nèi)存。
Background:應(yīng)用處在后臺工窍,并且還在執(zhí)行代碼割卖。一般的應(yīng)用,都只會在這個狀態(tài)短暫停留(最多十分鐘)移剪,然后就會被系統(tǒng)強制進(jìn)入 Suspended 狀態(tài)究珊。而 iOS 為了在某些情況下提供更好的體驗薪者,提供了一些選項纵苛,只要滿足這些選項的條件,就可以在后臺運行很長的一段時間言津,下面我們將重點討論可以使應(yīng)用在后臺長時間運行的方法攻人。
iOS 提供的后臺運行方式
上圖為 iOS 提供的后臺運行方式列表,如果需要悬槽,可在 Xcode 的項目設(shè)置中開啟對應(yīng)的選項怀吻。App Store 的審核人員會檢查應(yīng)用中是否有必要開啟該后臺運行模式選項,如果應(yīng)用中不需要初婆,而又開啟了這個選項蓬坡,可能會被拒.
Audio, AirPlay and Picture in Picture
此個選項包含四種場景,分別是:音頻的播放磅叛,錄音弊琴,AirPlay 及畫中畫的視頻播放紫皇。
音頻的播放:在播放音頻時萄窜,即使應(yīng)用退到后臺番宁,只要一直有音頻在播放踱蠢,那應(yīng)用就可以一直在后臺運行。代碼實現(xiàn)可參考:http://www.reibang.com/p/348e0f9ffde9
** Audio**:應(yīng)用可以請求使用麥克風(fēng),而當(dāng)開啟了此后臺選項,應(yīng)用在使用麥克風(fēng)的時候,即使退到后臺擦俐,也可以一直后臺運行品擎,通過查看微信安裝包中的 plist 文件饥悴,微信的語音聊天答朋,就是通過這種方式實現(xiàn)的禽绪。而當(dāng)該類應(yīng)用退到后臺后,iOS 系統(tǒng)的狀態(tài)欄會變成紅色,并在狀態(tài)欄中顯示正在使用麥克風(fēng)的應(yīng)用的名稱,如下圖所示。
AirPlay:AirPlay 是指將 iOS 設(shè)備履怯,或者 Mac 設(shè)備上的音視頻工禾,同步到另一個設(shè)備中播放槽畔。舉兩個例子,第一個是把 iPhone 上的音樂通過藍(lán)牙的方式在汽車的藍(lán)牙音響播放寥假,第二個是把 iPhone 上的視頻,同步到智能電視屏幕上播放霞扬。此功能一般用于多端及多屏的交互糕韧。
關(guān)于 AirPlay 的開發(fā)文檔:http://nto.github.io/AirPlay.html
Picture in Picture:畫中畫是 iPad 版本的 iOS 9 新增加的功能枫振,可以在 iOS 的桌面,或者其他應(yīng)用的界面的上面播放視頻萤彩,從而該視頻區(qū)域所屬的應(yīng)用就可以后臺運行了粪滤。此功能現(xiàn)在只在 iPad 應(yīng)用中提供。
代碼實現(xiàn)可參考:http://www.reibang.com/p/27ce4ada48da
Location updates
一般用于導(dǎo)航應(yīng)用中雀扶,開啟此選項后额衙,應(yīng)用退到后臺,還可以得到系統(tǒng)的定位更新怕吴,從而使得應(yīng)用可以根據(jù)定位的變化做出不同的反應(yīng)窍侧。
代碼實現(xiàn)可參考:https://github.com/W-King/Location
Voice over IP
VOIP 類的應(yīng)用允許用戶使用網(wǎng)絡(luò)而不是手機打電話,因此這一類的應(yīng)用需要保持同它相關(guān)的服務(wù)的網(wǎng)絡(luò)連接转绷,用以收到來電事件和其他數(shù)據(jù)伟件。iOS 不是通過一直讓該應(yīng)用處于激活狀態(tài)來達(dá)到這個目的,而是同樣也會將這類的應(yīng)用掛起议经,但同時會在應(yīng)用被掛起期間由系統(tǒng)接管它的 VOIP 的 Socket斧账,當(dāng)這個 Socket 有數(shù)據(jù)通信時,系統(tǒng)會再次喚醒處于掛起狀態(tài)的應(yīng)用煞肾,同時將 Socket 的控制權(quán)交還給該應(yīng)用咧织,以讓其正常的處理來電事件和其他數(shù)據(jù)。
Newsstand downloads
在 iOS 開發(fā)中籍救,有一類叫報刊雜志類應(yīng)用比較特別习绢,在 iOS 9 之前的系統(tǒng)中,此類應(yīng)用會統(tǒng)一收在系統(tǒng)內(nèi)置的「報刊雜志」應(yīng)用中蝙昙,在 iOS 9 中則去掉了內(nèi)置的「報刊雜志」應(yīng)用闪萄,此類應(yīng)用得以以單獨的圖標(biāo)入口出現(xiàn)在桌面中。此后臺運行的選項就是提供給報刊雜志類應(yīng)用可以在后臺下載及處理報刊雜志內(nèi)容奇颠,而下載的過程需要使用 NewsstandKit 中的 NKAssetDownload 進(jìn)行下載败去。需要注意的是,下載的過程中烈拒,應(yīng)用可能還是會被掛起圆裕,甚至應(yīng)用被退出,而 iOS 會在 Wi-Fi 環(huán)境下繼續(xù)下載荆几,直到下載完成吓妆。而一旦下載完成,如果應(yīng)用只是被掛起伴郁,則** iOS 會喚醒對應(yīng)的應(yīng)用耿战,回調(diào)對應(yīng)的事件;如果應(yīng)用已經(jīng)退出焊傅,則會啟動應(yīng)用**剂陡,在啟動參數(shù)中會帶上對應(yīng)的標(biāo)識表示這次啟動是因為下載報刊雜志內(nèi)容完成狈涮。
代碼實現(xiàn)可參考:http://www.viggiosoft.com/blog/blog/2011/10/17/ios-newsstand-tutorial/
External Accessory communication
此選項提供給一些 MFi 外設(shè)通過藍(lán)牙,或者 Lightning 接頭等方式與 iOS 設(shè)備連接鸭栖,從而可在外設(shè)發(fā)送消息時歌馍,喚醒已經(jīng)被掛起的應(yīng)用。而一旦被喚醒晕鹊,一般情況下松却, 應(yīng)用只有最多 10 秒鐘的執(zhí)行時間。MFi 外設(shè):是指通過蘋果 MFi 認(rèn)證的設(shè)備溅话,而 MFi 認(rèn)證是對其授權(quán)配件廠商生產(chǎn)的外置配件的一種標(biāo)識使用許可晓锻,是 Made for iOS 的英文縮寫。
Uses Bluetooth LE accessories
此選項與 External Accessory communication 類似飞几,只是此選項無需限制 MFi 外設(shè)砚哆,而需要的是 Bluetooth LE 設(shè)備。
Acts as a Bluetooth LE accessory
此選項是指 iOS 設(shè)備作為一個藍(lán)牙外設(shè)連接時屑墨,對應(yīng)的應(yīng)用可以后臺運行躁锁,但是使用此模式需要用戶進(jìn)行授權(quán)認(rèn)證。
Background fetch
iOS 7 新增加的一個選項卵史,用于即使在后臺战转,也需要頻繁更新數(shù)據(jù)的應(yīng)用。例如一個 PM2.5 的應(yīng)用以躯,需要幾個小時更新一次數(shù)據(jù)槐秧,那么可以開啟此選項,設(shè)置一個時間間隔寸潦,從而讓 iOS 在間隔時間內(nèi)在后臺啟動該應(yīng)用色鸳,執(zhí)行指定數(shù)據(jù)的獲取工作,而此過程最多只能執(zhí)行 30 秒鐘见转。
代碼實現(xiàn)可參考:http://www.reibang.com/p/82f639012f3e
Remote notifications
iOS 7 新增加的一個選項,是一種靜默推送蒜哀,它有別于一般的推送斩箫,應(yīng)用收到此類推送后,不會有任何的界面提示撵儿,而當(dāng)應(yīng)用退出或者掛起時收到此類推送乘客,iOS 也會啟動或者喚醒對應(yīng)的應(yīng)用。例如一個閱讀應(yīng)用淀歇,用戶訂閱的博客更新了易核,那么可以先發(fā)一個靜默推送,應(yīng)用收到此種推送后浪默,可以先把用戶訂閱的博客內(nèi)容都下載好牡直,再通知用戶缀匕,這樣用戶一打開應(yīng)用就可以馬上開始閱讀。收到靜默推送碰逸,會回調(diào)對應(yīng)的回調(diào)方法乡小,而此回調(diào)方法最多只能執(zhí)行 30 秒鐘。
代碼實現(xiàn)可參考:http://www.reibang.com/p/82f639012f3e
基于 NSURLSession 的后臺傳輸
此為 iOS 7 新增加的特性饵史,用于在后臺下載或者上傳大文件满钟,步驟如下:創(chuàng)建后臺傳輸用的 NSURLSession 對象;向這個對象中加入對應(yīng)的傳輸?shù)?NSURLSessionTask胳喷,并開始傳輸湃番;在實現(xiàn) AppDelegate 里實現(xiàn) -application:handleEventsForBackgroundURLSession:completionHandler: 方法,以刷新 UI 及通知系統(tǒng)傳輸結(jié)束吭露。一旦后臺傳輸?shù)臓顟B(tài)發(fā)生變化(包括正常結(jié)束和失斍@薄)的時候,應(yīng)用將被喚醒并運行 AppDelegate 中的回調(diào)奴饮。但是也有一些限制纬向,后臺傳輸只會通過 Wi-Fi 來進(jìn)行。后臺下載的時間與以前的關(guān)閉應(yīng)用后X分鐘的模式不一樣戴卜,而是為了節(jié)省電力變?yōu)殡x散式的下載逾条。
代碼實現(xiàn)可以參考:http://onevcat.com/2013/08/ios7-background-multitask/
其他后臺運行黑魔法
一直循環(huán)播放一段沒聲音的音頻
可以在后臺選項中選擇「Audio, AirPlay and Picture in Picture」,而開始循環(huán)播放一段是沒聲音的音頻投剥,即在 Audio Unit 回調(diào)函數(shù)中使用 kAudioUnitRenderAction_OutputIsSilence 標(biāo)志位师脂,但是這種方式兩個大的缺點:
- 蘋果的審核人員如果發(fā)現(xiàn),會被拒江锨;
- 應(yīng)用程序的 Audio Session 不能被打斷吃警。當(dāng)應(yīng)用執(zhí)行在后臺時,只要另一個應(yīng)用使用 kAudioSessionCategory_RecordAndPlay (比如 Skype)或者 kAudioSessionCategory_SoloAmbientSound啄育,那么該應(yīng)用就會被立即打斷酌心。
代碼實現(xiàn)可參考:https://github.com/marcop/MMPDeepSleepPreventer
越獄下開發(fā) System 級別的應(yīng)用
一般的應(yīng)用都是 Mobile 級別的,在越獄的情況下挑豌,可以開發(fā)一個 System 級別的應(yīng)用安券,從而使得應(yīng)用不受 iOS 一般應(yīng)用的限制,實現(xiàn)真正的后臺運行氓英,但是缺點就是應(yīng)用只能運行在越獄設(shè)備上侯勉,也不能上 App Store。
代碼實現(xiàn)可參考:http://www.reibang.com/p/50b7b27ba828
推送一般大家只需要鉤Remote notifications
騰訊的隨心播需要鉤Audio, AirPlay and Picture in Picture 也就是退出后會出現(xiàn)那個紅條條