Reputation: 464
Can't understand why my app crashes always going background when a sound is playing. If no sound here app won't crash.
I have a SKAction
which plays a sound. I preload this songs with static let
in Actions
class and call static func
which returns SKAction
with sound. So I have completion level sound. When it plays, I hit home button, them come back to app. There app crashes with message "Thread 1: EXC_BAD_ACCESS(code=1, adress=0xff8e9abc)". Has anybody an idea what's going on here?
This is my struct called Actions
:
public struct Actions {
static let completionSound = SKAction.playSoundFileNamed("CompletionSound.mp3", waitForCompletion: false)
static func playCompletionSound() -> SKAction {
return completionSound
}
}
Here in my class called Grid
, I have condition whether level completed or not:
class Grid {
var delegate: GridDelegate?
private var completed: Bool = false
...
...
private func completeLevel() {
if completed {
let waitAction = SKAction.wait(forDuration: 1.5)
let blockAction = SKAction.run {
let groupAction = self.settings.sound ? SKAction.group([Actions.playGridSwishSound(), Actions.removeGridAction()]) : Actions.removeGridAction()
self.gridNode.run(groupAction, completion: {
self.gridNode.removeAllChildren()
self.delegate?.completionLevel()
})
}
let seq = SKAction.sequence([waitAction, blockAction])
run(groupAction)
}
}
There I have a node, which shows SKLabelNode
with "COMPLETED" text.
class CompletionNode: SKNode {
private let completionLabel = SKLabelNode(fontNamed: MainFont)
init(settings: Settings) {
self.settings = settings
super.init()
isUserInteractionEnabled = false
completionLabel.text = Titles.CompletedTitle
completionLabel.fontSize = 46.0
completionLabel.fontColor = GoldenColor
completionLabel.centering()
completionLabel.position = CGPoint(x: 0.0, y: 0.0)
completionLabel.xScale = 0.0
completionLabel.yScale = 0.0
completionLabel.alpha = 0.0
addChild(completionLabel)
}
func animate(completion: @escaping () -> ()) {
let waitAction = Actions.waitAction(duration: 0.2)
let scaleAction = SKAction.scale(to: 1.0, duration: 0.4)
scaleAction.timingMode = .easeInEaseOut
let fadeInAction = Actions.fadeInAction(duration: 0.4)
fadeInAction.timingMode = .easeIn
let groupAction = SKAction.group([scaleAction, fadeInAction])
let llBlock = SKAction.run {
self.completionLabel.run(groupAction)
}
let seq = SKAction.sequence([waitAction, llBlock])
run(seq, completion: completion)
}
}
In gameNode
where I have grid
instance, which is the delegate of last one, I add completionNode to the scene:
class GameScene: SKNode {
var gird: Grid?
let hudNode = HUDNode()
let completionNode = CompletionNode()
var completionOn = false
...
init() {
super.init()
grid = Grid()
grid!.delegate = self
grid!.position = CGPoint(x: 0.0, y: 0.0)
addChild(grid!)
hudNode.position = CGPoint(x: 0.0, y: MainSize.height * 0.44)
hudNode.zPosition = 40.0
hudNode.delegate = self
addChild(hudNode)
completionNode.alpha = 0.0
completionNode.position = CGPoint(x: 0.0, y: 0.0)
completionNode.zPosition = 60.0
addChild(completionNode)
}
internal func completeLevel() {
addCompletionScene()
}
private func addCompletionNode() {
run(Actions.playCompletionSound())
completionNode.alpha = 1.0
completionNode.animate {
self.completionOn = true
self.hudNode.isUserInteractionEnabled = true
}
}
}
When I reach the end of level I press home button, then come back to my game, after what crash happens.
Upvotes: 2
Views: 131
Reputation: 330
It appears playSoundFileNamed has problems preserving the audio session while your app/game transitions between foreground and background mode.
Depending on your implementation, after the app resumes after the interruption you get unpredictable behavior ranging from muted playback to failed loading sound assets to plain crashing as in your case.
Here is a topic that discusses similar problems: SKAction playSoundFileNamed doesn't work after receiving two consecutive phone calls
I would suggest to stop using playSoundFileNamed actions and use AVAudioPlayer for playing sound files instead. It takes more effort into configuring it but it has been around for a long time and works flawlessly.
Upvotes: 1