Localizing SKLabelNodes in .sks files

Most of my first scenes I implemented by code instead of the GUI tool, but eventually I thought it could be quite helpful for certain scenes.

I quickly noticed the issue that it was not so straightforward to localize the SKLabelNode texts anymore.

I tried the default method by clicking ‘Localize…’ button in the tool, but that actually made duplicates of the .sks file that I was supposed to change for localizing the texts. This seemed to have the bad side that if I were to make changes to the layout or add new elements, I would have to do it multiple times.

Instead I implemented this bit of code where I unarchive the .sks files. This is what the default unarchive function more or less looks like:

extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {

        let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks")

        var sceneData = NSData.dataWithContentsOfFile(path!, options: .DataReadingMappedIfSafe, error: nil)
        var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

        archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
        let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKScene
        scene.scaleMode = .AspectFill
        return scene

For this article the interesting bit is the call to localizeLabelNodes. There I do this:

func localizeLabelNodes(scene : SKScene)
    for node in scene.children
        if var labelNodeText = (node as? SKLabelNode)?.text
            var index = advance(labelNodeText.startIndex, 4)
            if labelNodeText.substringToIndex(index) == "L:::"
                var langId = labelNodeText.substringFromIndex(index)
                (node as? SKLabelNode)?.text = NSLocalizedString(langId, comment: langId)

So basically I enumerate the SKLabelNodes of the scene, and if the text matches the pattern “L:::”, I know that this is something to localize. Then I simply the substring as the translation ID.

In .sks file, SKLabelNode.text : “L:::New Game”
In localizable.strings (English): “New Game” = “New Game”;
In localizable.strings (Finnish): “New Game” = “Uusi Peli”;

This way when I want to change translations of .sks SKLabelNodes, I can segregate changes to the strings file like elsewhere.


Now read this

Dealing with large numbers in Swift

Type inference is a handy feature in Swift that makes declaring most variables fun and easy. However, there are cases when you must explicitly define the type of the variable. In this example, the starting point is having 4 big numbers,... Continue →