前言:確保App切換到后臺(tái)時(shí)纵穿,有足夠的時(shí)間完成重要的任務(wù)
當(dāng)App切換到后臺(tái),系統(tǒng)會(huì)調(diào)用applicationDidEnterBackground:
,該方法有5秒去處理任務(wù)以及返回結(jié)果贤笆,返回后,很快App就會(huì)被系統(tǒng)掛起。對(duì)于大多數(shù)App围辙,5秒已經(jīng)足夠吉捶。但如果你需要更多的時(shí)間夺鲜,你可以請(qǐng)求UIKit
去延長時(shí)間。
通過beginBackgroundTaskWithName:expirationHandler:
,調(diào)用這個(gè)方法可以讓你的應(yīng)用程序增多30秒的時(shí)間來完成一項(xiàng)任務(wù)呐舔。(應(yīng)用程序?qū)嶋H接收的CPU時(shí)間通常要少得多币励。)使用額外的時(shí)間完成任務(wù),并在完成后立即調(diào)用endBackgroundTask(_:)
方法珊拼。如果應(yīng)用程序不能及時(shí)完成任務(wù)食呻,系統(tǒng)就會(huì)終止它。
注意:你不必等到應(yīng)用程序移動(dòng)到后臺(tái)調(diào)用beginBackgroundTaskWithName:expirationHandler:
方法澎现。即是--在執(zhí)行任何長時(shí)間運(yùn)行的任務(wù)之前都可調(diào)用該方法仅胞。如果你的應(yīng)用在任務(wù)處于活動(dòng)狀態(tài)時(shí)移動(dòng)到后臺(tái),系統(tǒng)會(huì)給你30多秒的時(shí)間來完成任務(wù)剑辫。
beginBackgroundTaskWithName:expirationHandler:
方法可以讓你的應(yīng)用程序在轉(zhuǎn)換到后臺(tái)之后繼續(xù)運(yùn)行一段時(shí)間干旧。你應(yīng)該在任務(wù)未完成時(shí)調(diào)用此方法,這可能不利于應(yīng)用程序的用戶體驗(yàn)妹蔽。例如椎眯,你的應(yīng)用程序可以調(diào)用此方法以確保有足夠的時(shí)間將重要文件傳輸?shù)竭h(yuǎn)程服務(wù)器挠将,或者至少嘗試進(jìn)行傳輸并注意任何錯(cuò)誤。你不應(yīng)該僅僅為了讓你的應(yīng)用在后臺(tái)運(yùn)行而使用這個(gè)方法盅视。
下面該示例配置一個(gè)后臺(tái)任務(wù)捐名,以便應(yīng)用程序可以將數(shù)據(jù)保存到服務(wù)器上,這將花費(fèi)超過5秒的時(shí)間闹击。方法返回必須保存的標(biāo)識(shí)符镶蹋,并將其傳遞給endBackgroundTask(_:)
方法。
func sendDataToServer( data : NSData ) {
// 在后臺(tái)隊(duì)列運(yùn)行一個(gè)任務(wù)
DispatchQueue.global().async {
// 請(qǐng)求聲明任務(wù)以及保存ID
self.backgroundTaskID = UIApplication.shared.
beginBackgroundTask (withName: "Finish Network Tasks") {
// 時(shí)間過期時(shí)停止任務(wù)
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = UIBackgroundTaskInvalid
}
// 同步發(fā)送數(shù)據(jù).
self.sendAppDataToServer( data: data)
// 結(jié)束任務(wù)
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = UIBackgroundTaskInvalid
}
}
beginBackgroundTaskWithName:expirationHandler:
可以在非主線程上安全地調(diào)用赏半。如果時(shí)間還不夠贺归,請(qǐng)使用NSProcessInfo
中的performExpiringActivityWithReason:usingBlock:
方法(異步執(zhí)行指定的塊并在進(jìn)程即將被掛起時(shí)通知你)來代替