Cannot use unarchiveFromFile to set GameScene in SpriteKit
Asked Answered
M

1

0

I'm using Xcode 7 beta 2 and following raywenderlich.com's Breakout tutorial to learn SpriteKit. Here's the error I get when I try to load GameScene using unarchiveFromFile.

GameScene.type does not have a member named unarchiveFromFile.

Here's the code:

func didBeginContact(contact: SKPhysicsContact) {
    // 1. Create local variables for two physics bodies
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    // 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    // 3. react to the contact between ball and bottom
    if firstBody.categoryBitMask == BallCategory && secondBody.categoryBitMask == BottomCategory {
        //TODO: Replace the log statement with display of Game Over Scene

        if let mainView = view {
            let gameOverScene = GameOverScene.unarchiveFromFile("GameOverScene") as! GameOverScene
            gameOverScene.gameWon = false
            mainView.presentScene(gameOverScene)
        }
    }
}
Margheritamargi answered 28/6, 2015 at 10:43 Comment(1)
class func unarchiveFromFile is defined in a custom extension SKNode in GameViewController.swift of the sample project. Did you convert the project to "Last Swift syntax" ?Alexio
E
5

You should use the init(fileNamed:) initialiser, which is available from iOS 8 onwards. For example:

if let gameOverScene = GameOverScene(fileNamed: "GameOverScene") {
    // ...
}

It's important to note that init(fileNamed:) is a convenience initialiser on SKNode:

convenience init?(fileNamed filename: String)

Therefore, for GameOverScene to automatically inherit init(fileNamed:), GameOverScene must adhere to the following rules from The Swift Programming Language: Initialisation (rule 2 especially):

Assuming that you provide default values for any new properties you introduce in a subclass, the following two rules apply:

Rule 1 If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2 If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

Embranchment answered 28/6, 2015 at 11:1 Comment(4)
There is a unarchiveFromFile method in Ray Wenderlich's sample project which uses NSKeyedUnarchiver to instantiate a (subclass) instance of SKNode from a .sks file, and that worked without problem with Xcode 7 in my quick test.Alexio
In that case there's something else wrong with the OP's code and so my answer doesn't address the actual problem. However, unarchiveFromFile no longer seems to be used; it's not included in the default Sprite Kit project and init(fileNamed: "...") is used instead.Embranchment
You are right, init(fileNamed:) was added in the iOS 8 SDK, so this would be the better solution if your deployment target is iOS 8 (or later). However, the original problem is still unclear to me, I could download the sample project and convert it to Swift 2 with a few clicks :)Alexio
And what is the analog for init(fileNamed:) in Objective-C?Minter

© 2022 - 2024 — McMap. All rights reserved.