Search code examples
iosswiftsprite-kitwatchkitwatchos

SKNode's action run completion block does not get called


I have a watchOS 4 app which displays SpriteKit animations (SKActions) on top of the UI. Everything works fine in simulator and also on device first couple of times, then after some time when app is in background, and it is started, animations just freeze and completion block for the most long-lasting animation is not called. Any idea what might be the issue?

This is how I run my actions, caller is waiting for completion closure in order to hide the spritekit scene:

private func runActions(with icon: SKShapeNode?, completion: @escaping () -> Void) {
    if let icon = icon, let scaleAction = scaleAction, let bg = background {
        self.label?.run(fadeInOutAction)
        icon.run(scaleAction)
        icon.run(fadeInOutAction)
        bg.run(backgroundAction, completion: completion)
    } else {
        completion()
    }
}

And yes, I am aware that SKScene is paused when app moves to background. I am doing this in willActivate of my InterfaceController:

if scene.scene?.isPaused == true {
    scene.scene?.isPaused = false
}

I want to emphasize that this works first always. It begins to fail after the app has been backgrounded for some time. Especially if I start the app from complication and try to immediately fire these animations, then this freezing happens.


Solution

  • Can I answer my own question? I guess I can? Here goes:

    I finally solved this. It turns out that the WKInterfaceScene in WatchKit has ALSO an isPaused property that you need to turn false sometimes. So now in willActivate of my InterfaceController I will also check that and turn it false if it is true. Since I made this change, I haven't seen a single hiccup, freeze or anything weird anymore.

    Case closed, I guess. I leave this here for future generations who might face this issue.