iOS常駐後臺執行實現
最近重新看iOS的開發,確實有一些新的發現:
1、短時間常駐(3分鐘):
比較簡單,在AppDelegate裡進行後臺任務申請
var backgroundTask:UIBackgroundTaskIdentifier! = nil
申請一個任務ID
func applicationDidEnterBackground(_ application: UIApplication) {}
該方法在進入後臺時響應
//如果已存在後臺任務,先將其設為完成
if self.backgroundTask != nil {
application.endBackgroundTask(self.backgroundTask)
self.backgroundTask = UIBackgroundTaskInvalid
}
//註冊後臺任務
self.backgroundTask = application.beginBackgroundTask(expirationHandler: {
() -> Void in
//如果沒有呼叫endBackgroundTask,時間耗盡時應用程式將被終止
application.endBackgroundTask(self.backgroundTask)
self.backgroundTask = UIBackgroundTaskInvalid
})
runBackgroundTask() //要進行的後臺任務
缺陷是隻能執行180秒
2、後臺常駐的時間
一般有重新整理定位和播放音樂兩種方式,這裡試驗了播放音樂方式
tips:不需要1中的註冊任務方法
var audioPlayer:AVAudioPlayer!
宣告player
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// 註冊後臺播放
let session = AVAudioSession.sharedInstance()
do {
try session.setActive(true)
try session.setCategory(AVAudioSessionCategoryPlayback)
} catch {
print(error)
}
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
playMusic()
//定時任務主要是列印剩餘時間
var timer:Timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: {
(timer) in
let timeRemaining = UIApplication.shared.backgroundTimeRemaining
print("time left: \(timeRemaining)")
})
}
func playMusic(){
print("play music")
do{
try self.audioPlayer = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: Bundle.main.path(forResource: "MAMI", ofType: "mp3")!) as URL)
}catch let error as NSError{
print(error.localizedDescription)
}
//audioPlayer.volume = 0
//-1無限迴圈播放
//audioPlayer.numberOfLoops = -1
audioPlayer.play()
}
說明: playMusic() 執行後,進入後臺不會中止定時器,因此可以在APP啟動的時候就 playMusic(),那麼定時器無論處於前臺還是後臺,都會正常執行!
----------------------
在APP啟動時播放音樂和啟動定時器,長時間執行後存在這樣的問題:定時器的網路請求程式碼會被暫停,直到轉入前臺後才執行,也就是造成延遲