文一
我從蘋果文檔中得知,一般的應用在進入后臺的時候可以獲取一定時間來運行相關任務,也就是說可以在后臺運行一小段時間崩溪。
還有三種類型的可以運行在后以父款,
1.音樂
2.location
3.voip
文二
在IOS后臺執(zhí)行是本文要介紹的內容溢谤,大多數(shù)應用程序進入后臺狀態(tài)不久后轉入暫停狀態(tài)。在這種狀態(tài)下憨攒,應用程序不執(zhí)行任何代碼世杀,并有可能在任意時候從內存中刪除。應用程序提供特定的服務肝集,用戶可以請求后臺執(zhí)行時間瞻坝,以提供這些服務。
判斷是否支持多線程
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
backgroundSupported = device.multitaskingSupported;
聲明你需要的后臺任務
Info.plist中添加UIBackgroundModes鍵值杏瞻,它包含一個或多個string的值所刀,包括
audio:在后臺提供聲音播放功能,包括音頻流和播放視頻時的聲音
location:在后臺可以保持用戶的位置信息
voip:在后臺使用VOIP功能
前面的每個value讓系統(tǒng)知道你的應用程序應該在適當?shù)臅r候被喚醒捞挥。例如浮创,一個應用程序,開始播放音樂砌函,然后移動到后臺仍然需要執(zhí)行時間蒸矛,以填補音頻輸出緩沖區(qū)。添加audio鍵用來告訴系統(tǒng)框架,需要繼續(xù)播放音頻雏掠,并且可以在合適的時間間隔下回調應用程序斩祭;如果應用程序不包括此項询刹,任何音頻播放在移到后臺后將停止運行铁瞒。
除了添加鍵值的方法,IOS還提供了兩種途徑使應用程序在后臺工作:
Task completion—應用程序可以向系統(tǒng)申請額外的時間去完成給定的任務
Local notifications—應用程序可以預先安排時間執(zhí)行l(wèi)ocal notifications 傳遞
文三
如何讓程序后臺播放音樂
http://developer.apple.com/library/ios/#qa/qa1668/_index.html
文四
如果你的應用程序需要后臺運行衅斩,可以使用以下方法:
1绑青。應用程序可以請求一個有限的時間內完成一些重要任務诬像。
2。應用程序可以聲明為支持特定服務需要定期后臺執(zhí)行時間闸婴。
3坏挠。應用程序可以使用本地生成用戶在指定的時間的警報,應用程序正在運行與否的通知邪乍。
原文地址:http://blog.csdn.net/diyagoanyhacker/article/details/7071055
作者:禚來強
聲明:此文一部分來自網(wǎng)絡降狠,一部分來自官方文檔(翻譯),還有一部分是作者的總結
文五
后臺運行被第一次提到
文六
后臺運行官方文檔
在IOS后臺執(zhí)行是本文要介紹的內容庇楞,大多數(shù)應用程序進入后臺狀態(tài)不久后轉入暫停狀態(tài)榜配。在這種狀態(tài)下,應用程序不執(zhí)行任何代碼吕晌,并有可能在任意時候從內存中刪除蛋褥。應用程序提供特定的服務,用戶可以請求后臺執(zhí)行時間睛驳,以提供這些服務烙心。
判斷是否支持多線程
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:@selector(isMultitaskingSupported)])
backgroundSupported = device.multitaskingSupported;
聲明你需要的后臺任務
Info.plist中添加UIBackgroundModes鍵值,它包含一個或多個string的值乏沸,包括
audio:在后臺提供聲音播放功能淫茵,包括音頻流和播放視頻時的聲音
location:在后臺可以保持用戶的位置信息
voip:在后臺使用VOIP功能
前面的每個value讓系統(tǒng)知道你的應用程序應該在適當?shù)臅r候被喚醒。例如屎蜓,一個應用程序痘昌,開始播放音樂钥勋,然后移動到后臺仍然需要執(zhí)行時間炬转,以填補音頻輸出緩沖區(qū)。添加audio鍵用來告訴系統(tǒng)框架算灸,需要繼續(xù)播放音頻扼劈,并且可以在合適的時間間隔下回調應用程序;如果應用程序不包括此項菲驴,任何音頻播放在移到后臺后將停止運行荐吵。
除了添加鍵值的方法,IOS還提供了兩種途徑使應用程序在后臺工作:
Task completion—應用程序可以向系統(tǒng)申請額外的時間去完成給定的任務
Local notifications—應用程序可以預先安排時間執(zhí)行l(wèi)ocal notifications 傳遞
實現(xiàn)長時間的后臺任務
應用程序可以請求在后臺運行以實現(xiàn)特殊的服務。這些應用程序并不連續(xù)的運行先煎,但是會被系統(tǒng)框架在合適的時間喚醒贼涩,以實現(xiàn)這些服務
1、??追蹤用戶位置:略
2薯蝎、在后臺播放音頻:
添加UIBackgroundModes中audio值遥倦,注冊后臺音頻應用。這個值使得應用程序可以在后臺使用可聽的背景占锯,如音樂播放或者音頻流應用袒哥。對于支持音頻和視頻功能的應用程序也可以添加該值以保證可以繼續(xù)持續(xù)的運行流。
當audio值設置后消略,當你的應用程序進入后臺后堡称,系統(tǒng)的多媒體框架會自動阻止它被掛斷,但是艺演,如果應用程序停止播放音頻或者視頻却紧,系統(tǒng)將掛斷應用程序。
當你的應用程序在后臺時钞艇,你可以執(zhí)行任意的系統(tǒng)音頻框架去初始化后臺音頻啄寡。你的應用程序在后臺時應該限制自身,使其執(zhí)行與工作相關的代碼哩照,不能執(zhí)行任何與播放內容無關的任務
由于有多個應用程序支持音頻挺物,前臺的應用程序始終允許播放音頻,后臺的應用程序也被允許播放一些音頻內容飘弧,這取決于audio session object的設置识藤。應用程序應該始終設置它們的audio session object,并小心的處理其他類型的音頻相關notifications和中斷次伶。詳見audio session programming guide痴昧。
3、實現(xiàn)VOIP應用:
VOIP程序需要穩(wěn)定的網(wǎng)絡去連接和它相關的服務冠王,這樣它才能接到來電和其他相關的數(shù)據(jù)赶撰。系統(tǒng)允許VOIP程序被掛斷并提供組件去監(jiān)聽它們的sockets,而不是在任意時候都處于喚醒狀態(tài)柱彻。設置VOIP應用程序如下:
A豪娜、 添加UIBackgroundModes中的VOIP鍵值
B、 為VOIP設置一個應用程序socket
C哟楷、 在移出后臺之前瘤载,調用setKeepAliveTimeout:handler:方法去建立一個定期執(zhí)行的handler,你的應用程序可以運行這個handler來保持服務的連接卖擅。
D鸣奔、 設置你的audio session去處理這種切換
釋義:
A墨技、大多數(shù)VOIP應用需要設置后臺audio 應用去傳遞音頻,因此你應該設置audio 和voip兩個鍵值挎狸。
B扣汪、為了使應用程序在后臺時保持穩(wěn)定的連接,你必須tag你的主通訊socket專門應用于VOIP锨匆,tagging這個socket來告訴系統(tǒng)私痹,它必須在你的應用程序中斷時接管這個socket。這個切換本身對于你的應用程序時透明的统刮,當新的數(shù)據(jù)到達socket的時候紊遵,系統(tǒng)會喚醒應用程序,并將socket的控制權返回給應用程序侥蒙,這樣應用程序就可以處理新來的數(shù)據(jù)暗膜。
你只需要tag用于voip服務的socket,這個socket用來接收來電或者其他相關的數(shù)據(jù)來保持你的VOIP服務的連接鞭衩。根據(jù)收到的信息学搜,這個socket要決定下一步的動作。比如一個來電论衍,你會想彈出一個本地的通知來告知用戶瑞佩;對于其他不是那么關鍵的數(shù)據(jù),你可能會想悄悄的處理這些數(shù)據(jù)并讓系統(tǒng)將應用程序重新中斷坯台。
在IOS中炬丸,sockets是用流或者更高級的結構,設置一個VOIP的socket蜒蕾,你只需要在通常的設置中添加一個特殊的key來標明這個接口是用于連接VOIP服務的稠炬,下表列出了流的接口和設置:
設置流接口用于voip
接口
設置
NSInputStream 和NSOutputStream
對于 Cocoa streams, 使用 setProperty:forKey: 方法添加
NSStreamNetworkServiceType
屬性給
stream.
改屬性的值設為
NSStreamNetworkServiceTypeVoIP.
NSURLRequest
對于 URL loading system, 使用 setNetworkServiceType:
method of your NSMutableURLRequest object to set the network service
type of the request. The service type should be set to
NSURLNetworkServiceTypeVoIP.
CFReadStreamRef和CFWriteStreamRef
For Core Foundation streams, use the CFReadStreamSetProperty or
CFWriteStreamSetProperty function to add the kCFStreamNetwork-
ServiceType property to the stream. The value for this property should be
set to kCFStreamNetworkServiceTypeVoIP.
(注意:當設置socket的時候,你需要在你的主信號通道中設置合適的service type key。當設置聲道時咪啡,不需要設置這個key)
由于首启,VOIP應用程序需要一直運行以確保收到來電,所以如果程序通過一個非零的exitcode退出撤摸,系統(tǒng)將自動重啟這個應用程序(這種退出方式可以發(fā)生在內存壓力大時終止程序運行)毅桃。盡管如此,中斷應用程序會release所有的sockets准夷,包括那個用于連接voip 服務的socket钥飞。因此,當程序運行時冕象,它需要一直從頭創(chuàng)建socket代承。
C汁蝶、 為了防止斷連渐扮,voip程序需要定期被喚醒去檢查它的服務论悴。為了容易實現(xiàn)這個行為,IOS通過使用(UIApplication setKeepAliveTimeout:handler:)方法建立一個特殊的句柄墓律。你可以在applicationDidEnterBackground方法中建立該句柄膀估。一旦建立,系統(tǒng)至少會在超時之前調用該句柄一次耻讽,來喚醒你的應用程序察纯。
這個keep-alive handler在后臺執(zhí)行,必須盡快的返回參數(shù)针肥,它有最多30秒的時間來執(zhí)行所需的任務饼记,如果這段時間內句柄沒有返回,那么系統(tǒng)將終止應用程序慰枕。
當你建立了handler之后具则,確定應用程序所需的最大超時。系統(tǒng)保證會在最大超時之前調用handler具帮,但是這個時間是不確定的博肋,所以你的handler必須在你申明的超時之前做好執(zhí)行程序的準備。
D蜂厅、設置audio session匪凡,詳見Audio Session Programming Guide.
在后臺完成有限長度的任務
在被終止之前的任意時間,應用程序會調用beginBackgroundTaskWithExpirationHandler:方法讓系統(tǒng)給出額外的時間來完成一些需要在后臺長時間執(zhí)行的任務。(UIApplication的backgroundTimeRemaining屬性包含程序運行的總時間)
可以使用task completion去保證那些比較重要但是需要長時間運行的程序不會由于用戶切入后臺而突然關閉掘猿。比如病游,你可以用這項功能來將用戶的信息保存到disk上或者從網(wǎng)絡下載一個重要的文件。有兩種方式來初始化這樣的任務:
1稠通、將長時間運行的重要任務用beginBackgroundTaskWithExpirationHandler:和endBackgroundTask:包裝礁遵。這樣就在程序突然切入后臺的時候保護了這些任務不被中斷。
2采记、當你的應用程序委托applicationDidEnterBackground:方法被調用時再啟動任務
中的兩個方法必須是一一對應的佣耐,endBackgroundTask:方法告訴系統(tǒng)任務已經(jīng)完成,程序在此時可以被終止唧龄。由于應用程序只有有限的時間去完成后臺任務兼砖,你必須在超時或系統(tǒng)將要終止這個程序之前調用這個方法。為了避免被終止既棺,你也可以在一個任務開始的時候提供一個expiration handler和endBackgroundTask:方法讽挟。(可以查看backgroundTimeRemaining屬性來確定還剩多少時間)。
一個程序可以同時提供多個任務丸冕,每當你啟動一個任務的時候耽梅,beginBackgroundTaskWithExpirationHandler:方法將返回一個獨一無二的handler去識別這個任務。你必須在endBackgroundTask:方法中傳遞相同的handler來終止該任務胖烛。
Listing 4-2 Starting a background task at quit time
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication*app= [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0), ^{
// Do the work associated with the task.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
上述例子中眼姐,bgTask變量是一個類的成員變量诅迷,存儲著指向該后臺任務標示的指針。
在expriation handler中众旗,可以添加關閉任務所需的代碼罢杉。盡管如此,加入的代碼不能執(zhí)行太長的時間贡歧,當expriation handler被調用的時候滩租,該程序已經(jīng)非常接近被關閉,所以只有極短的時間來清除狀態(tài)信息并終止任務利朵。
安排Local Notification的傳遞
UILocalNotification類提供了一種方法來傳遞local notifications律想。和push notifications需要設置remote server不同,local notifications 在程序中安排并在當前的設備上執(zhí)行绍弟。滿足如下條件可以使用該能力:
1蜘欲、一個基于時間的程序,可以在將來特定的時間讓程序post 一個alert晌柬,比如鬧鐘
2姥份、一個在后臺運行的程序,post 一個local notification去引起用戶的注意
為了安排local notification 的傳遞年碘,需要創(chuàng)建一個UILocalNotification的實例澈歉,并設置它,使用UIApplication類方法來安排它屿衅。Local notification對象包含了所要傳遞的類型(sound埃难,alert,或者badge)和時間何時呈現(xiàn)) 涤久。UIApplication類方法提供選項去確定是立即傳遞還是在指定的時間傳遞涡尘。
Listing 4-3 Scheduling an alarm notification
- (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] autorelease];
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];
}
}
(可以最多包含128個 local notifications active at any given time, any of which can be configured to repeat at a specified interval.)如果在調用該notification的時候,程序已經(jīng)處于前臺响迂,那么application:didReceiveLocalNotification:方法將取而代之考抄。