Files
SideStore/Sources/SideStoreAppKit/Components/BackgroundTaskManager.swift

90 lines
2.5 KiB
Swift
Raw Normal View History

//
// BackgroundTaskManager.swift
// AltStore
//
// Created by Riley Testut on 6/19/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import AVFoundation
2023-03-01 19:09:33 -05:00
public final class BackgroundTaskManager {
public static let shared = BackgroundTaskManager()
2023-03-01 00:48:36 -05:00
private var isPlaying = false
2023-03-01 00:48:36 -05:00
private let audioEngine: AVAudioEngine
private let player: AVAudioPlayerNode
private let audioFile: AVAudioFile
2023-03-01 00:48:36 -05:00
private let audioEngineQueue: DispatchQueue
2023-03-01 00:48:36 -05:00
private init() {
audioEngine = AVAudioEngine()
audioEngine.mainMixerNode.outputVolume = 0.0
player = AVAudioPlayerNode()
audioEngine.attach(player)
do {
let audioFileURL = Bundle.main.url(forResource: "Silence", withExtension: "m4a")!
2023-03-01 00:48:36 -05:00
audioFile = try AVAudioFile(forReading: audioFileURL)
audioEngine.connect(player, to: audioEngine.mainMixerNode, format: audioFile.processingFormat)
} catch {
fatalError("Error. \(error)")
}
2023-03-01 00:48:36 -05:00
audioEngineQueue = DispatchQueue(label: "com.altstore.BackgroundTaskManager")
}
}
2023-03-01 19:09:33 -05:00
public extension BackgroundTaskManager {
2023-03-01 00:48:36 -05:00
func performExtendedBackgroundTask(taskHandler: @escaping ((Result<Void, Error>, @escaping () -> Void) -> Void)) {
func finish() {
player.stop()
audioEngine.stop()
isPlaying = false
}
2023-03-01 00:48:36 -05:00
audioEngineQueue.sync {
do {
try AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true)
2023-03-01 00:48:36 -05:00
// Schedule audio file buffers.
self.scheduleAudioFile()
self.scheduleAudioFile()
2023-03-01 00:48:36 -05:00
let outputFormat = self.audioEngine.outputNode.outputFormat(forBus: 0)
self.audioEngine.connect(self.audioEngine.mainMixerNode, to: self.audioEngine.outputNode, format: outputFormat)
2023-03-01 00:48:36 -05:00
try self.audioEngine.start()
self.player.play()
2023-03-01 00:48:36 -05:00
self.isPlaying = true
2023-03-01 00:48:36 -05:00
taskHandler(.success(())) {
finish()
}
2023-03-01 00:48:36 -05:00
} catch {
taskHandler(.failure(error)) {
finish()
}
}
}
}
}
2023-03-01 00:48:36 -05:00
private extension BackgroundTaskManager {
func scheduleAudioFile() {
player.scheduleFile(audioFile, at: nil) {
self.audioEngineQueue.async {
guard self.isPlaying else { return }
self.scheduleAudioFile()
}
}
}
}