I have an AVAudioPlayer instance that loads sound in memory with audioPlayer.prepareToPlay()
, and then after a few start playing it. I have a problem that in approximately ten minutes after entering background, it leaks from memory and I is not being prepared. After that fed hours, I don't have an ability to run prepareToPlay()
again. How to leave that preloaded sound in memory for a long term? I am preparing sound to play in applicationDidFinishLaunchingWithOptions
method:
let dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(dispatchQueue, {[weak self] in
var audioSessionError: NSError?
let audioSession = AVAudioSession.sharedInstance()
NSNotificationCenter.defaultCenter().addObserver(self!, selector: "handleInterruption:", name: AVAudioSessionInterruptionNotification, object: nil)
audioSession.setActive(true, error: nil)
if (audioSession.setCategory(AVAudioSessionCategoryPlayback, error: &audioSessionError)) {
println("Successfully set the audio session")
} else {
println("Could not set the audio session")
}
let filePath = NSBundle.mainBundle().pathForResource("sound", ofType:"mp3")
let fileData = NSData(contentsOfFile: filePath!, options: .DataReadingMappedIfSafe, error: nil)
var error:NSError?
self!.audioPlayer = AVAudioPlayer(data: fileData, error: &error)
self!.audioPlayer?.numberOfLoops = -1
self!.audioPlayer?.delegate = self
if (self?.audioPlayer?.prepareToPlay() != false) {
println("Successfully prepared for playing")
} else {
println("Failed to prepare for playing")
}
})
Then in didReceiveRemoteNotification
I am trying to play it in background: self.audioPlayer?.play()
, it returns true
. Probably it works, but after about 10 - 20 minutes it does not work. And note that .play()
now returns false
.
Is there a sense to disable ARC (Automatic Reference Counting) to release and dealloc
audioPlayer
manually?Maybe I need to use lower level APIs such as
OpenAL
? However I won't use it since it is deprecated in iOS 9 and later I will need to rewrite it withoutOpenAL
.Any more ideas? Maybe I need to use
Audio Units
withRemoteIO
? If it will work, provide some examples please.Maybe there are third party frameworks like
ObjectAL
- an easy implementation ofOpenAL
. As I know it is available in iOS 9.
These methods are just my assumptions. But them main question remains the same: Will those methods work from background?
You should just disable ARC. When you enter backgroud, then if you don't use it it is being released. In Swift create AVAudioPlayer as
Unmanaged<T>
object.