適用于iOS的應用程序編程指南(三)

后臺執行

當用戶沒有主動使用您的應用程序時,系統將其移動到后臺狀態。對于許多應用程序,后臺狀態只是暫停應用程序的一個短暫停留。暫停應用程序是提高電池壽命的一種方式,它還允許系統將重要的系統資源投入到引起用戶關注的新前臺應用程序中。

大多數應用程序可以輕松變換到暫停狀態,但是還有合理原因讓應用程序在后臺繼續運行。遠足應用程序可能希望跟蹤用戶的位置,以便它可以在遠足地圖上顯示該課程。音頻應用程序可能需要在鎖定屏幕上繼續播放音樂。其他應用程序可能希望在后臺下載內容,以便最大限度地減少將內容呈現給用戶的延遲。當您發現有必要使您的應用程序在后臺運行時,iOS可以有效地執行,而不會耗盡系統資源或用戶的電量。iOS提供的技術分為三類:

當應用程序切換到后臺時,應用程序可以在前臺啟動一個簡短的任務。

在前臺啟動下載的應用程序可以將這些下載的管理權交給系統,從而允許在下載過程中暫停或終止該應用。

需要在后臺運行以支持特定類型任務的應用程序可以聲明對一個或多個后臺執行模式的支持。

始終盡量避免做任何后臺工作,除非這樣做改善了整體用戶體驗。由于用戶啟動了不同的應用程序,或者因為用戶鎖定了設備,而且目前還沒有使用它,應用程序可能會移動到后臺。在這兩種情況下,用戶都在指示您的應用程序現在不需要做任何有意義的工作。繼續在這樣的條件下運行,只會耗盡設備的電池,并可能導致用戶強制退出您的應用程序。所以要注意你在后臺做的工作,避免這種情況。

執行有限長度任務

移動到后臺的應用程序預計將盡可能快地進入靜態狀態,以便系統可以暫停。如果您的應用程序在任務的中間,并且需要一些額外的時間才能完成該任務,那么可以調用UIApplication對象的beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法來請求一些額外的執行時間。調用這些方法之一會暫時延遲您的應用程序的暫停,給它一些額外的時間來完成它的工作。完成該工作后,您的應用程序必須調用endBackgroundTask:方法讓系統知道它已經完成并可以被掛起。

每次調用beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法生成一個與相應任務關聯的唯一標記。當您的應用程序完成任務時,它必須使用相應的令牌調用endBackgroundTask:方法,以使系統知道該任務已完成。如果沒有為后臺任務調用endBackgroundTask:方法將導致您的應用程序終止。如果您在啟動任務時提供了一個到期處理程序,系統將調用該處理程序給你最后一次機會結束任務并避免直接終止任務。

您不需要等到您的應用程序移動到后臺來指定后臺任務。一個更有用的設計是在開始任務之前調用beginBackgroundTaskWithName:expirationHandler:或beginBackgroundTaskWithExpirationHandler:方法,一旦完成就調用endBackgroundTask:方法。您甚至可以在應用程序在前臺執行時遵循此模式。

清單3-1顯示了當應用程序轉換到后臺時如何啟動長時間運行的任務。在此示例中,啟動后臺任務的請求包括一個到期處理程序,以防任務耗時太長。然后將任務本身提交給一個調度隊列進行異步執行,以便applicationDidEnterBackground:方法可以正常返回。使用blocks簡化了維護對任何重要變量(例如后臺任務標識符)的引用所需的代碼。bgTask變量是存儲指向當前后臺任務標識符的指針的類的成員變量,并在此方法使用之前初始化它。

清單3-1退出時啟動后臺任務

-(void)applicationDidEnterBackground:(UIApplication *)application

{

bgTask = [applicationbeginBackgroundTaskWithName:@"MyTask" expirationHandler:^{

// Clean up anyunfinished task business by marking where you

// stopped orending the task outright.

[applicationendBackgroundTask:bgTask];

bgTask =UIBackgroundTaskInvalid;

}];

// Start the long-running taskand return immediately.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

// Do the workassociated with the task, preferably in chunks.

[applicationendBackgroundTask:bgTask];

bgTask =UIBackgroundTaskInvalid;

});

}

注意:始終在啟動任務時提供一個到期處理程序,但是如果您想知道應用程序運行多少時間,請獲取UIApplication的backgroundTimeRemaining屬性的值。

在您自己的過期處理程序中,您可以包括關閉任務所需的其他代碼。但是,您所包含的任何代碼都不能太長時間執行,因為在調用過期處理程序時,您的應用程序已經非常接近其時間限制。因此,只執行最少的清除狀態信息并結束任務。

在后臺下載內容

當下載文件時,應用程序應使用NSURLSession對象來開始下載,以便系統可以控制下載過程,以防應用程序被暫停或終止。當您配置NSURLSession對象進行后臺傳輸時,系統會在單獨的進程中管理這些傳輸,并以常規方式將狀態報告回您的應用程序。如果您的應用程序在傳輸正在進行時終止,系統會在后臺繼續傳輸,并在傳輸完成或一個或多個任務需要您的應用程序注意時啟動應用程序(如appropriate)。

要支持后臺傳輸,您必須適當地配置您的NSURLSession對象。要配置會話,必須先創建一個NSURLSessionConfiguration對象,并將幾個屬性設置為適當的值。然后,在創建會話時,將該配置對象傳遞給NSURLSession的適當初始化方法。

創建支持后臺下載的配置對象的過程如下:

1 使用NSURLSessionConfiguration的backgroundSessionConfigurationWithIdentifier:方法創建配置對象。

2 將配置對象的sessionSendLaunchEvents屬性的值設置為YES。

3 如果您的應用程序在前臺進行轉移,建議您將配置對象的自由屬性設置為YES。

4 根據需要配置配置對象的任何其他屬性。

5 使用配置對象創建您的NSURLSession對象。

一旦配置,您的NSURLSession對象無縫地在適當的時候將上傳和下載任務交給系統。如果任務在您的應用程序仍在運行(在前臺或后臺)中完成,則會話對象以通常的方式通知其代理。如果任務尚未完成,并且系統終止您的應用程序,系統將自動繼續在后臺管理任務。如果用戶終止您的應用程序,系統將取消任何掛起的任務。

當與后臺會話相關聯的所有任務完成時,系統重新啟動終止的應用程序(假定sessionSendLaunchEvents屬性設置為YES,用戶沒有強制退出該應用程序),并調用應用程序委托應用程序:handleEventsForBackgroundURLSession:completionHandler: 方法。 (系統還可以重新啟動應用程序來處理需要您的應用程序注意的身份驗證檢驗或其他與任務相關的事件。)在執行該委托方法時,請使用提供的標識符創建新的NSURLSessionConfiguration和NSURLSession對象,其配置與之前相同。系統會將您的新會話對象重新連接到先前的任務,并將其狀態報告給會話對象的委托。

實施長時間運行的任務

對于需要執行更多執行時間的任務,您必須請求特定的權限才能在后臺運行它們,而不會被掛起。在iOS中,只有特定的應用類型才能在后臺運行:

在背景中向用戶播放音頻內容的應用程序,如音樂播放器應用程序

在后臺記錄音頻內容的應用程序

隨時讓用戶了解其位置的應用程序,例如導航應用程序

支持互聯網語音協議(VoIP)的應用程序

需要定期下載和處理新內容的應用程序

從外部配件接收定期更新的應用程序

實施這些服務的應用程序必須聲明其支持的服務,并使用系統框架來實現這些服務的相關方面。聲明服務允許系統知道您使用哪些服務,但在某些情況下,系統框架實際上阻止您的應用程序被暫停。

聲明您的應用程序支持的后臺任務

某些類型的后臺執行的支持必須由使用它們的應用程序提前聲明。在Xcode 5及更高版本中,您可以從項目設置的“功能”選項卡中聲明應用程序支持的后臺模式。啟用后臺模式選項將UIBackgroundModes鍵添加到應用程序的Info.plist文件中。選擇一個或多個復選框將相應的背景模式值添加到該鍵。表3-1列出了您可以指定的背景模式以及Xcode在應用程序的Info.plist文件中分配給UIBackgroundModes鍵的值。

表3-1應用程序的背景模式

Xcode背景模式

UIBackgroundMode值

描述


音頻和AirPlay

音頻

該應用程序播放聲音內容給用戶或在后臺記錄音頻。 (此內容包括使用AirPlay流式傳輸音頻或視頻內容。)

在第一次使用之前,用戶必須授權應用程序使用麥克風;有關詳細信息,請參閱支持用戶隱私。Supporting User Privacy


位置更新

位置

該應用程序即使在后臺運行時也會將用戶通知他們的位置。


IP語音通話

VOIP

該應用程序提供用戶使用Internet連接撥打電話的功能。


報攤下載

報攤內容

該應用程序是一個報亭應用程序,可在后臺下載和處理雜志或報紙內容。


外部附件通訊

外部附件

該應用程序與需要通過外部附件框架定期提供更新的硬件配件配合使用。


使用藍牙LE配件

藍牙中心

該應用程序與藍牙配件配合使用,需要通過核心藍牙框架定期提供更新。


充當藍牙LE附件

藍牙外設

該應用程序通過核心藍牙框架支持外設模式下的藍牙通信。

使用此模式需要用戶授權;有關詳細信息,請參閱支持用戶隱私。Supporting User Privacy.


后臺抓取

該應用程序定期從網絡下載和處理少量內容。


遠程通知

遠程通知

該應用程序想要在推送通知到達時開始下載內容。使用此通知來最小化顯示與推送通知相關的內容的延遲。


以上每種模式都可讓系統知道您的應用程序應該在適當的時間喚醒或啟動,以響應相關事件。例如,開始播放音樂然后移動到背景的應用程序仍然需要執行時間來填充音頻輸出緩沖器。啟用音頻模式會告訴系統框架,他們應該繼續以適當的時間間隔對應用進行必要的回調。如果應用程序沒有選擇此模式,則當應用程序移動到背景時,應用程序播放或記錄的任何音頻都會停止。

跟蹤用戶的位置

有幾種方法可以在后臺跟蹤用戶的位置,其中大部分實際上不需要您的應用在后臺連續運行:

重大變更位置服務(推薦)

前景專屬定位服務

背景定位服務

強烈建議對不需要高精度位置數據的應用進行重大改變位置服務。使用此服務,只有當用戶位置發生明顯變化時才會生成位置更新;因此,它是為用戶提供非關鍵的位置相關信息的社交應用程序或應用程序的理想選擇。如果應用程序在發生更新時被暫停,系統將在后臺喚醒以處理更新。如果應用程序啟動此服務,然后終止,則系統會在新位置可用時自動重新啟動應用程序。此服務可在iOS4及更高版本中使用,并且僅在包含蜂窩網廣播的設備上可用。

僅前臺和后臺位置服務都使用標準位置的Core Location服務來檢索位置數據。唯一的區別是,如果應用程序被暫停,則前臺專用位置服務停止傳遞更新,如果應用程序不支持其他后臺服務或任務,則可能會發生更新。前景專用位置服務適用于在前臺只需要位置數據的應用程序。

您可以從Xcode項目的“功能”選項卡的“后臺”模式部分啟用位置支持。 (您也可以通過在應用程序的Info.plist文件中包含UIBackgroundModes鍵和位置值來啟用此支持。)啟用此模式不會阻止系統掛起應用程序,但它會告訴系統它應該喚醒每當有新的位置數據傳遞時,應用程序。因此,該密鑰有效地使應用程序在后臺運行,以便在發生時處理位置更新。

重要提示:建議您謹慎使用標準服務或改用重要的位置更改服務。位置服務需要積極使用iOS設備的板載無線電硬件。連續運行這個硬件可以消耗大量的電量。如果您的應用程序不需要向用戶提供精確且連續的位置信息,最好盡量減少使用位置服務。

有關如何在應用程序中使用每個不同位置服務的信息,請參閱位置和地圖編程指南。Location and Maps Programming Guide

播放和錄制背景音頻

連續播放或記錄音頻的應用程序(即使應用程序在后臺運行)也可以注冊以在后臺執行這些任務。您可以從Xcode項目中的“功能”選項卡的“后臺”模式部分啟用音頻支持。(您也可以通過在應用的Info.plist文件中包含UIBackgroundModes鍵和音頻值來啟用此支持。)在后臺播放音頻內容的應用程序必須播放聲音內容,而不是靜音。

背景音頻應用程序的典型示例包括:

音樂播放器應用程序

錄音應用程式

支持通過AirPlay播放音頻或視頻的應用程序

VoIP應用程序

當UIBackgroundModes鍵包含音頻值時,系統的媒體框架會自動阻止相應的應用程序在移動到后臺時被暫停。只要播放音頻或視頻內容或錄制音頻內容,該應用程序將繼續在后臺運行。但是,如果錄制或播放停止,系統將暫停該應用程序。

您可以使用任何系統音頻框架來處理背景音頻內容,并且使用這些框架的過程不變。 (對于通過AirPlay進行視頻播放,您可以使用媒體播放器或AVFoundation框架來呈現您的視頻。)由于您的應用程序在播放媒體文件時未被暫停,所以回調在您的應用程序處于后臺時正常運行。但是,在回調中,您只需要提供數據進行播放所需的工作。例如,流式音頻應用程序將需要從其服務器下載音樂流數據,并將當前音頻樣本推出以進行播放。應用程序不應執行與播放無關的任何無關的任務。

由于多個應用程序可能支持音頻,系統會確定在任何給定時間允許哪個應用程序播放或錄制音頻。前臺應用程序始終具有音頻操作的優先級。允許多個后臺應用程序播放音頻,這樣的確定是基于每個應用程序的音頻會話對象的配置。您應該始終配置您的應用程序的音頻會話對象,并與系統框架仔細配合,以處理中斷和其他類型的音頻相關通知。有關如何配置音頻會話對象以進行后臺執行的信息,請參閱音頻會話編程指南。Audio Session Programming Guide

實施VoIP應用

互聯網語音協議(VoIP)應用允許用戶使用因特網連接而不是設備的蜂窩服務進行電話呼叫。這樣的應用程序需要維護與其相關服務的持續網絡連接,以便它可以接收來電和其他相關數據。而不是一直保持VoIP應用程序清醒,系統允許它們被暫停,并提供監控他們的套接字的設施。當檢測到傳入流量時,系統喚醒VoIP應用程序,并將其套接字的控制權返回給它。

要配置VoIP應用程序,您必須執行以下操作:

1 在Xcode項目的“功能”選項卡的“后臺模式”部分啟用對IP語音的支持。 (您還可以通過在應用程序的Info.plist文件中包含帶有voip值的UIBackgroundModes鍵來啟用此支持。)

2 配置一個應用程序的套接字用于VoIP使用。

3 在移動到后臺之前,調用setKeepAliveTimeout:handler:方法來安裝要定期執行的處理程序。您的應用程序可以使用此處理程序來維護其服務連接。

4 配置您的音頻會話以處理到和使用的轉換。

在UIBackgroundModes鍵中包含voip值可以讓系統知道它應該允許應用程序根據需要在后臺運行來管理其網絡套接字。系統啟動后立即重新啟動具有該密鑰的應用程序,以確保VoIP服務始終可用。

大多數VoIP應用程序還需要配置為背景音頻應用程序,以便在后臺傳送音頻。因此,您應該將音頻和voip值都包含在UIBackgroundModes鍵中。如果您不這樣做,您的應用程序在后臺無法播放或錄制音頻。有關UIBackgroundModes鍵的更多信息,請參閱信息屬性列表鍵參考。Information Property List Key Reference

有關實現VoIP應用程序必須采取的步驟的具體信息,請參閱開發VoIP應用程序的提示。Tips for Developing a VoIP App.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容