前言:我們公司項(xiàng)目中有需求:當(dāng)鎖屏狀態(tài)下需要監(jiān)聽是否有新的訂單,然后喚醒手機(jī)進(jìn)行一些邏輯,那么就涉及到如何讓app可以在后臺(tái)更久的運(yùn)行。
現(xiàn)在項(xiàng)目通過蘋果審核了,做了總結(jié)方便同學(xué)交流。
【A】iOS App 有5種狀態(tài):
分別是:Not running ,?Inactive , Active , Suspended, Background,
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í)間比較長的情況是:當(dāng)用戶鎖屏?xí)r,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來電、有未讀短信等)事件的時(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)行很長的一段時(shí)間,下面我們將重點(diǎn)討論可以使應(yīng)用在后臺(tái)長時(shí)間運(yùn)行的方法。

【B】iOS App 后臺(tái)執(zhí)行規(guī)則:
iOS為了讓設(shè)備盡量省電,減少不必要的開銷,保持系統(tǒng)流暢,因而對(duì)后臺(tái)機(jī)制采用墓碑式的“假后臺(tái)”。除了系統(tǒng)官方極少數(shù)程序可以真后臺(tái),一般開發(fā)者開發(fā)出來的應(yīng)用程序后臺(tái)受到以下限制:
1.用戶按Home之后,App轉(zhuǎn)入后臺(tái)進(jìn)行運(yùn)行,此時(shí)擁有180s后臺(tái)時(shí)間(iOS7)或者600s(iOS6)運(yùn)行時(shí)間可以處理后臺(tái)操作
2.當(dāng)180S或者600S時(shí)間過去之后,可以告知系統(tǒng)未完成任務(wù),需要申請(qǐng)繼續(xù)完成,系統(tǒng)批準(zhǔn)申請(qǐng)之后,可以繼續(xù)運(yùn)行,但總時(shí)間不會(huì)超過10分鐘。
3.當(dāng)10分鐘時(shí)間到之后,無論怎么向系統(tǒng)申請(qǐng)繼續(xù)后臺(tái),系統(tǒng)會(huì)強(qiáng)制掛起App,掛起所有后臺(tái)操作、線程,直到用戶再次點(diǎn)擊App之后才會(huì)繼續(xù)運(yùn)行。
當(dāng)然iOS為了特殊應(yīng)用也保留了一些可以實(shí)現(xiàn)“真后臺(tái)”的方法,摘取比較常用的:
1.VOIP ? 2.定位服務(wù) ? 3.后臺(tái)下載? ?4.在后臺(tái)一直播放無聲音樂(容易受到電話或者其他程序影響,所以暫未考慮)
【C】代碼解決方案:
使用的是: Long-running background task + 播放無聲音樂 雙重調(diào)起方法。
"長時(shí)間運(yùn)行后臺(tái)任務(wù)",中文應(yīng)該是這個(gè)名字,當(dāng)我們需要進(jìn)入后臺(tái)不暫停程序,就可以給系統(tǒng)說一聲 "我需要在后臺(tái)執(zhí)行任務(wù)了哦~",然后你的 App 就不會(huì)被系統(tǒng)掛起,準(zhǔn)確來說是延遲暫停,注意這是全局的,意思就是 App 里所有東西都將正常執(zhí)行,就跟在前臺(tái)一樣。不過系統(tǒng)給你這個(gè)權(quán)限的時(shí)間是有限的。
1 在info.plist添加如下代碼
<key>UIBackgroundModes</key>
<array>
<string> audio </string>
?</array>
2 在AppDelegate的applicationDidEnterBackground和applicationWillEnterForeground方法添加處理。核心代碼:


3在ViewController里面執(zhí)行播放默認(rèn)語音,核心代碼:

【D】上架審核
這里面是測(cè)試demo,我們五秒執(zhí)行以下彈出本地通知。所以后續(xù)如何操作,大家來處理。上架的時(shí)候蘋果被拒絕了,給出的問題是:

我們拍攝了相關(guān)后臺(tái)的視頻給蘋果,大致意思是:關(guān)閉屏幕之后,有新的訂單,我們會(huì)有一個(gè)通知。最后上架成功了。
Demo 下載地址:?簡書