當(dāng)在后臺時引起用戶注意
通知是一種應(yīng)用被掛起泌射、或在后臺運(yùn)行、或沒有運(yùn)行的情況下引起用戶注意的方式鬓照。應(yīng)用可以使用本地通知來顯示警告熔酷、播放聲音、印章化應(yīng)用的圖標(biāo)豺裆、或者三者的組合拒秘。例如,一個鬧鐘應(yīng)用可以使用本地通知來播放鬧鐘聲音并顯示一個警告來關(guān)掉鬧鐘臭猜。當(dāng)一個通知被傳遞給用戶的時候躺酒,用戶必須根據(jù)信息決定是否讓應(yīng)用回到前臺。(如果應(yīng)用已經(jīng)運(yùn)行在前臺蔑歌,本地通知只會安靜的傳遞給應(yīng)用而不會顯示給用戶羹应。)
為了安排本地通知的傳遞,創(chuàng)建一個UILocalNotification類的實例次屠,配置通知參數(shù)园匹,并使用UIApplication類的方法來安排它。本地通知對象包含關(guān)于用來傳遞的通知類型(聲音劫灶、警告裸违、或者徽章)的信息以及發(fā)送它的時間(當(dāng)合適時)。UIApplication類的方法為立刻或在安排的時間傳遞通知提供了選項本昏。
代碼清單3-2顯示了一個使用用戶設(shè)定的日期和時間安排一個單次警告的例子供汛。這個例子只配置了一次警告,并在安排一個新的警告之前取消了之前的警告。(你自己的應(yīng)用可以在任何時刻有不超過128個的本地通知紊馏,其中任何一個都可以配置為以指定間隔重復(fù)料饥。)警告本身由一個警告框和一個聲音文件組成;當(dāng)警告觸發(fā)時朱监,如果應(yīng)用在不運(yùn)行或者在后臺運(yùn)行的時候岸啡,聲音文件會播放。如果應(yīng)用正處于活動狀態(tài)赫编,因此正在前臺運(yùn)行巡蘸,作為替代,應(yīng)用委托的application:didReceiveLocalNotification:方法被調(diào)用
代碼清單3-2 安排警告通知
- (void)scheduleAlarmForDate:(NSDate*)theDate
{
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[UILocalNotification alloc] init];
if (alarm)
{
alarm.fireDate = theDate;
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = @"alarmsound.caf";
alarm.alertBody = @"Time to wake up!";
[app scheduleLocalNotification:alarm];
}
}
用于本地通知的聲音文件和用于推送通知的聲音文件具有相同的要求擂送。自定義的聲音文件必須被放置在應(yīng)用的主束中悦荒,并且支持下面格式中的一種:Linear PCM, MA4, μ-Law, 或 a-Law。你也可以指定UILocalNotificationDefaultSoundName常量來為設(shè)備播放默認(rèn)的聲音嘹吨。當(dāng)這個通知被發(fā)送且聲音被播放時搬味,系統(tǒng)也會在支持震動的設(shè)備上觸發(fā)震動。
你可以使用UIApplication類的方法來取消安排通知蟀拷,或者得到通知的列表碰纬。更多關(guān)于這些方法的信息,參見UIApplication Class Reference问芬。關(guān)于配置本地通知的額外信息悦析,參見Local and Remote Notification Programming Guide。
理解你的應(yīng)用何時在后臺啟動
支持后臺執(zhí)行的應(yīng)用可以通過系統(tǒng)重啟來處理傳入的事件此衅。如果應(yīng)用由于除用戶強(qiáng)退之外的原因而被終止强戴,系統(tǒng)會在下面這些事件發(fā)生的時候重啟應(yīng)用:
- 對于位置應(yīng)用:
- 系統(tǒng)接收到一個與應(yīng)用所配置的傳送標(biāo)準(zhǔn)匹配的位置更新。
- 設(shè)備進(jìn)入或退出一個注冊區(qū)域挡鞍。(區(qū)域可以是地理區(qū)域或iBeacon區(qū)域骑歹。)
- 對于音頻應(yīng)用,音頻框架需要應(yīng)用來處理一些數(shù)據(jù)匕累。(音頻應(yīng)用包括那些播放或使用麥克風(fēng)的應(yīng)用陵刹。)
- 對于藍(lán)牙應(yīng)用:
- 應(yīng)用扮演從連接的外設(shè)獲取數(shù)據(jù)的中心角色默伍。
- 應(yīng)用扮演從連接中心獲取命令的外設(shè)角色欢嘿。
- 對于后臺下載應(yīng)用:
- 應(yīng)用的推送通知到達(dá),它的通知內(nèi)容包含值為1的content-available鍵也糊。
- 系統(tǒng)在有機(jī)會的時刻喚醒應(yīng)用來開始下載新內(nèi)容炼蹦。
- 對于使用NSURLSession類在后臺下載內(nèi)容的應(yīng)用,所有與會話對象關(guān)聯(lián)的任務(wù)都成功完成或接收到一個錯誤狸剃。
- Newsstand應(yīng)用啟動的下載任務(wù)完成掐隐。
在大多數(shù)情況下,系統(tǒng)會不在用戶強(qiáng)退應(yīng)用后重啟應(yīng)用。一個例外是位置應(yīng)用虑省,在iOS 8及更新的版本中匿刮,它能在用戶強(qiáng)退之后被重啟。然而在其它情況下探颈,用戶必須明確啟動應(yīng)用或在應(yīng)用能被系統(tǒng)從后臺自動啟動之前重啟設(shè)備熟丸。當(dāng)設(shè)備啟用密碼保護(hù)時,系統(tǒng)在用戶首次解鎖設(shè)備之前無法從后臺啟動應(yīng)用伪节。
做一個負(fù)責(zé)任的后臺應(yīng)用
在使用系統(tǒng)資源和硬件時光羞,前臺應(yīng)用總是優(yōu)先于后臺應(yīng)用。運(yùn)行在后臺的應(yīng)用需要為這種差異做好準(zhǔn)備怀大,并在它們運(yùn)行在后臺的時候調(diào)整其行為纱兑。具體來說,應(yīng)用在進(jìn)入到后臺的時候應(yīng)該遵循下面的指導(dǎo):
- 不要從代碼進(jìn)行任何OpenGL ES的調(diào)用化借。當(dāng)運(yùn)行在后臺的時候潜慎,你不能創(chuàng)建EAGLContext對象或者發(fā)出任何OpenGL ES繪圖命令。使用這些調(diào)用會導(dǎo)致應(yīng)用被立刻殺死蓖康。應(yīng)用還必須確保任何之前提交的命令在進(jìn)入后臺之前都已完成勘纯。關(guān)于如何在進(jìn)入或移出后臺的時候處理OpenGL ES的信息,參見 OpenGL ES Programming Guide中的Implementing a Multitasking-aware OpenGL ES Application钓瞭。
- 在被掛起前取消所有Bonjour相關(guān)的服務(wù)驳遵。當(dāng)應(yīng)用進(jìn)入后臺,并在被掛起前山涡,它應(yīng)該從Bonjour注銷堤结,并關(guān)閉任何與網(wǎng)絡(luò)服務(wù)相關(guān)的socket監(jiān)聽。掛起的應(yīng)用不能響應(yīng)任何傳入的服務(wù)請求鸭丛。關(guān)閉這些服務(wù)保護(hù)它們在其事實上不可用的時候被顯示為可用竞穷。如果你沒有關(guān)閉Bonjour服務(wù),系統(tǒng)會在應(yīng)用被掛起的時候自動關(guān)閉這些服務(wù)鳞溉。
- 在基于網(wǎng)絡(luò)socket中為處理連接失敗做好準(zhǔn)備瘾带。系統(tǒng)會在應(yīng)用被各種原因掛起的時候拆除socket連接。只要你的基于socket的代碼為其他網(wǎng)絡(luò)失敗的類型做好了準(zhǔn)備熟菲,例如信號丟失或者網(wǎng)絡(luò)轉(zhuǎn)換看政,則不會導(dǎo)致任何異常問題。當(dāng)應(yīng)用恢復(fù)時抄罕,如果在使用socket的時候遇到故障允蚣,值需要重新建立連鍵即可。
- 在進(jìn)入后臺之前保存應(yīng)用的狀態(tài)呆贿。在低內(nèi)存條件下嚷兔,后臺應(yīng)用可以被從內(nèi)存清除以釋放更多空間森渐。掛起的應(yīng)用首先會被清除,而且在被清除之前不會有任何通知冒晰。因此同衣,應(yīng)用應(yīng)該利用iOS 6及更高版本的狀態(tài)保存機(jī)制來保存它們的界面狀態(tài)到磁盤。關(guān)于如何支持這個功能的信息壶运,參見Preserving Your App’s Visual Appearance Across Launches乳怎。
- 在進(jìn)入后臺的時候移除不必要對象的強(qiáng)引用。如果應(yīng)用維持一個占用大量內(nèi)存的對象(特別是圖片)的緩存前弯,那就在進(jìn)入后臺的時候移除所有值像這些緩存的強(qiáng)引用蚪缀。更多信息,參見Reduce Your Memory Footprint恕出。
- 在被掛起之前停止使用共享系統(tǒng)資源询枚。與共享系統(tǒng)資源,例如地址簿或日歷數(shù)據(jù)庫浙巫,進(jìn)行交互的應(yīng)用金蜀,應(yīng)該在被掛起之前停止使用這些資源。這些資源總是優(yōu)先提供給前臺應(yīng)用的畴。當(dāng)應(yīng)用被掛起時渊抄,如果它被發(fā)現(xiàn)正在使用共享資源,應(yīng)用會被殺死丧裁。
- 避免更新你的窗口和視圖护桦。因為當(dāng)應(yīng)用在后臺的時候,它的窗口可視圖不可見煎娇,所以你應(yīng)該避免更新它們二庵。只有在你獲取應(yīng)用快照之前需更更新窗口內(nèi)容的情況下才可以例外。
- 響應(yīng)連接或斷開外部配件的通知缓呛。與外部配件連接的應(yīng)用催享,系統(tǒng)會在應(yīng)用進(jìn)入后臺的時候自動發(fā)送一個斷開連接通知。該應(yīng)用必須注冊這個通知哟绊,以便用它來關(guān)閉當(dāng)前的配件會話因妙。當(dāng)應(yīng)用返回到前臺的時候,一個匹配的連接通知會被發(fā)送票髓,給應(yīng)用一個機(jī)會來重新連接攀涵。更多處理配件連接和斷開通知的信息,參見External Accessory Programming Topics炬称。
- 當(dāng)進(jìn)入后臺的時候清除活動警告的資源汁果。為了在應(yīng)用之間切換的時候保護(hù)內(nèi)容,系統(tǒng)不會在應(yīng)用進(jìn)入后臺的時候自動關(guān)閉操作表單(UIActionSheet)或警告視圖(UIAlertView)玲躯。在進(jìn)入后臺之前,由你提供適當(dāng)?shù)厍謇硇袨椤@珲纬担憧赡芟胪ㄟ^編碼的方式取消活動表單或者警告視圖棘利,或者保存足夠的上下文信息以便稍后恢復(fù)視圖(在應(yīng)用程序被終止的情況下)。
- 在進(jìn)入后臺之前朽缴,刪除視圖上的敏感信息善玫。當(dāng)應(yīng)用轉(zhuǎn)換到后臺,系統(tǒng)得到應(yīng)用主窗口的一張快照密强,然后應(yīng)用轉(zhuǎn)換回到前臺的時候快照會短暫顯示茅郎。在從applicationDidEnterBackground:方法返回之前,你應(yīng)該隱藏或者遮擋密碼以及其它可能被快照捕獲的敏感的個人信息或渤。
- 在后臺運(yùn)行的時候盡可能少做事系冗。給予后臺應(yīng)用的執(zhí)行時間比器前臺應(yīng)用要受到更多的限制。在后臺花費(fèi)很多時間運(yùn)行的應(yīng)用可能會被系統(tǒng)限制或終止薪鹦。
如果你正在后臺執(zhí)行一個音頻應(yīng)用掌敬,或者允許在后臺運(yùn)行的其他類型應(yīng)用,應(yīng)用可以照常的響應(yīng)傳入消息池磁。換句話說奔害,系統(tǒng)可能會在發(fā)生低內(nèi)存警告的時候通知應(yīng)用。在這種情況下系統(tǒng)需要終止應(yīng)用來釋放更多的內(nèi)存地熄,該應(yīng)用會調(diào)用它的applicationWillTerminate:委托方法來執(zhí)行退出前的最后任務(wù)华临。
選擇不在后臺執(zhí)行
如果你不想讓應(yīng)用在后臺執(zhí)行,你可以通過將UIApplicationExitsOnSuspend鍵(值為YES)添加到在Info.plist 文件來明確的選擇不進(jìn)入后臺端考。當(dāng)應(yīng)用選擇不進(jìn)入時银舱,應(yīng)用會在不運(yùn)行、非活動跛梗、以及活動狀態(tài)之間循環(huán)寻馏,而不會進(jìn)入到后臺或者掛起狀態(tài)。當(dāng)應(yīng)用按下Home按鈕退出應(yīng)用的時候核偿,applicationWillTerminate:方法會被調(diào)用诚欠,并且在應(yīng)用終止并進(jìn)入不運(yùn)行狀態(tài)之前,有大約5秒鐘的時間來清理及退出漾岳。
強(qiáng)烈不推薦選擇不進(jìn)入后臺執(zhí)行轰绵,但是在某些特定情況下可能是首選。具體來說尼荆,如果為后臺執(zhí)行的編碼增加了應(yīng)用很大的復(fù)雜性左腔,終止應(yīng)用或許是一個更簡便的方案。此外捅儒,如果你的應(yīng)用消耗大量的內(nèi)存并且無法輕松釋放它液样,系統(tǒng)會迅速的殺死你的應(yīng)用來為其他應(yīng)用騰出空間振亮。因此,選擇終止鞭莽,而不是切換到后臺坊秸,可能會產(chǎn)生相同的結(jié)果,并節(jié)省開發(fā)的時間和精力澎怒。
更過關(guān)于能包含到Info.plist文件中的鍵的信息褒搔,參見Information Property List Key Reference。
(本節(jié)結(jié)束)