5
votes

I am not sure if it is a bug or not, but even when I set a Custom Class name on one of the Sprite, it seems to be completely ignored.

enter image description here

I tried with a dragged asset, and then with a empty node, both completely ignores the Monkey class association and just create a raw SKSpriteNode.

The Monkey Node code is as follow.

import Foundation
import SpriteKit

class Monkey: SKSpriteNode{

    let monkeyWalkAtlas = SKTextureAtlas(named: "MonkeyWalk")

    override init(texture: SKTexture?, color: NSColor, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
        print("Monkey.init debug")
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

Note: Custom class on .sks node are new in xcode7.

Edited June 21st 2015

I simplified the setup, but still the issue whe compiling/running in the iOS9 simulator. I created a project with the default SpriteKit template, chnage the GameSence to just have the following (and the empty Monkey class)

import SpriteKit

class GameScene: SKScene {

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("touch down")
       /* Called when a touch begins */
        for node in self.children {
            print(node)
        }
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
}

public class Monkey: SKSpriteNode {}

Dragged an Empty node on the GameScene.sks, set the custom class to Monkey, but when I touch down to print the sub nodes, I get again:

touch down
<SKSpriteNode> name:'SKNode_0' texture:['nil'] position:{753.5, 333.5} scale:{1.00, 1.00} size:{0, 0} anchor:{0, 0} rotation:0.00
2
I fear this might not be working right for Swift namespaced class names. Have you tried it with a ObjC class (or a Swift class with an @objc(name) name)? Either way, it's probably worth filing a bug. - rickster
Haven't bumped up to xcode7, but it might be that you haven't implemented the init( coder: ) method. Presumably, anything you modify in the Xcode builder would be using the coder init method to do its work, so if you haven't implemented it, it wouldn't be able to work with it. - cc.
You did, but it wouldn't return a usable object. If Xcode uses coders to save the object and then re-load it, your object can't participate because it fatalErrors()'s its way out of it. - cc.
Sorry to hear that doesn't resolve your issue. Still, it's probably a good thing that you did a "proper" implementation of init(coder:). Even if something else is causing your issue, a correct implementation of init(coder:) will probably still be required. - cc.
I cannot reproduce; I made an empty class Monkey: SKSpriteNode {}, created a scene, added an empty node, linked it and then instantiated it with this code: let c = SKScene(fileNamed: "MyScene")!; print(c.children.first! as! Monkey). This did not crash. Have you tried cleaning the project? Creating a new scene, class? Remember to first create the class before you try to link it. Xcode needs an existing class to successfully link. - vrwim

2 Answers

5
votes

In Swift you always have to add the module name before the class name. You can find the module name in the build settings in the field "Product Module Name". If you use a "-" in your project name the module name converts the "-" to a "_".(In my test project called "Test-Game" the module name is "Test_Game" so I would have to use the "Test_Game.Monkey" as a custom class which works for me in the current Xcode Beta)

0
votes

For anyone who is having this problem with newer versions of XCode: @Nightmare_82's solution is correct, but Product Module Name is no longer an available setting. Later versions of XCode use Product Name as the Module Name. I had development builds with my Product Name set to "My App (Dev)" and I switched it to "My App Dev" and all is well.