Unable to use SpriteKit with Swift Playground Books

All our custom Playground Books using SpriteKit stopped working after upgrading to SwiftPlaygrounds version 4.4

To reproduce the issue, simply create a new book by clicking the top right hand icon and in the book add two lines of code.

import SpriteKit

let circle = SKShapeNode(circleOfRadius: 100.0)

The second line produces an error. I tried with other classes. SKAction seems to work. SKSpriteNode, SKTexture etc have the same issue. Please help. Our students are stuck!

  • This issue is now fixed in v4.4.1. Thank, Apple. Please improve the stability of this app as it's crashing on a regular basis after v4.4

Add a Comment

Replies

Here is complete code that works on an Xcode Playground but not on an iPad. Is Apple moving away from using UIKit on Swift Playgrounds? Many other Apple Playground Books Stopped working too. However, Playground Books like Shapes still work. Based on this, it does seem to be a bug.

When run on iPad

let node = SKShapeNode(circleOfRadius: 100.0) 

throws an error.

import PlaygroundSupport
import SpriteKit

class GameScene: SKScene {
    
    private var label : SKLabelNode!
    private var spinnyNode : SKShapeNode!
    
    override func didMove(to view: SKView) {
        scene?.backgroundColor = .blue
        let node = SKShapeNode(circleOfRadius: 100.0)
        node.position = CGPoint(x: 100, y: 200)
        scene?.addChild(node)
    }
    
    @objc static override var supportsSecureCoding: Bool {
        // SKNode conforms to NSSecureCoding, so any subclass going
        // through the decoding process must support secure coding
        get {
            return true
        }
    }
    
    func touchDown(atPoint pos : CGPoint) {
       
    }
    
    func touchMoved(toPoint pos : CGPoint) {
        
    }
    
    func touchUp(atPoint pos : CGPoint) {
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { touchDown(atPoint: t.location(in: self)) }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { touchMoved(toPoint: t.location(in: self)) }
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { touchUp(atPoint: t.location(in: self)) }
    }
    
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { touchUp(atPoint: t.location(in: self)) }
    }
    
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

// Load the SKScene from 'GameScene.sks'
let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
let scene = GameScene(size: CGSize(width: 600, height: 600))
    // Set the scale mode to scale to fit the window
    scene.scaleMode = .aspectFill
    
    // Present the scene
    sceneView.presentScene(scene)


PlaygroundSupport.PlaygroundPage.current.liveView = sceneView