John Harding II
John Harding II

Reputation: 614

App Hanging on "let SKView as! SKView" (Swift)

I am trying to create a SpriteKit based game, and am trying to establish basic bluetooth connectivity before I continue, however my game is crashing while segueing from the menu to the GameScene, and I am getting a "Could not cast value of type 'UIView' to 'SKView'" error. My Game Menu is as follows:

import UIKit
import MultipeerConnectivity

class TitleScreenViewController: UIViewController, MCBrowserViewControllerDelegate {


@IBOutlet weak var TitleLabel: UILabel!
@IBOutlet weak var PlayLocallyButton: UIButton!
@IBOutlet weak var PlayOnlineButton: UIButton!
@IBOutlet weak var SettingsButton: UIButton!
@IBOutlet weak var GameCenterButton: UIButton!
var appDelegate:AppDelegate!

override func viewDidLoad() {
    super.viewDidLoad()

    PlayLocallyButton.layer.borderColor = UIColor.blackColor().CGColor
    PlayLocallyButton.layer.cornerRadius = 10
    PlayLocallyButton.layer.borderWidth = 1

    PlayOnlineButton.layer.borderColor = UIColor.blackColor().CGColor
    PlayOnlineButton.layer.cornerRadius = 10
    PlayOnlineButton.layer.borderWidth = 1

    SettingsButton.layer.borderColor = UIColor.blackColor().CGColor
    SettingsButton.layer.cornerRadius = 10
    SettingsButton.layer.borderWidth = 1

    GameCenterButton.layer.borderColor = UIColor.blackColor().CGColor
    GameCenterButton.layer.cornerRadius = 10
    GameCenterButton.layer.borderWidth = 1

    appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.mpcHandler.setupPeerWithDisplayName(UIDevice.currentDevice().name)
    appDelegate.mpcHandler.setupSession()
    appDelegate.mpcHandler.selfAdvertise(true)


}

@IBAction func ConnectWithPlayer(sender: AnyObject) {

    if appDelegate.mpcHandler.session != nil {
        appDelegate.mpcHandler.setupBrowser()
        appDelegate.mpcHandler.browser.delegate = self
        self.presentViewController(appDelegate.mpcHandler.browser, animated: true, completion: nil)


    }

}

func browserViewControllerDidFinish(browserViewController: MCBrowserViewController!) {

    appDelegate.mpcHandler.browser.dismissViewControllerAnimated(true, completion: nil)
    self.performSegueWithIdentifier("OverToGame", sender: self)
}


func browserViewControllerWasCancelled(browserViewController: MCBrowserViewController!) {

    appDelegate.mpcHandler.browser.dismissViewControllerAnimated(true, completion: nil)

}

My GameViewController, which the menu segues to and should present the GameScene is as follows. This contains the line where it hangs

import UIKit
import SpriteKit
import MultipeerConnectivity

extension SKNode {
class func unarchiveFromFile(file : NSString) -> SKNode? {
    if let path = NSBundle.mainBundle().pathForResource(file as String, ofType: "sks") {
        var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
        var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

        archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
        let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene
        archiver.finishDecoding()
        return scene
    } else {
        return nil
    }
  }
}

class GameViewController: UIViewController {

var appDelegate:AppDelegate!

override func viewDidLoad() {

    super.viewDidLoad()

    appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    appDelegate.mpcHandler.setupPeerWithDisplayName(UIDevice.currentDevice().name)
    appDelegate.mpcHandler.setupSession()
    appDelegate.mpcHandler.selfAdvertise(true)

}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let skView = self.view as! SKView

    if skView.scene == nil {

        skView.showsFPS = true
        skView.showsNodeCount = true

        let gameScene = GameScene(size: skView.bounds.size)
        gameScene.scaleMode = SKSceneScaleMode.AspectFill

        skView.presentScene(gameScene)

    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.
}

override func prefersStatusBarHidden() -> Bool {
    return true
  }
}

Am I even presenting the Scene in the correct fashion?

Upvotes: 0

Views: 1235

Answers (1)

Frankie
Frankie

Reputation: 11928

Your class GameViewController is of class UIViewController. UIViewController's view property is of class UIView, not SKView.

So when you write let skView = self.view as! SKView you are saying, hey, I know for sure that my self.view is supposed to be of SKView type, as indicated by the as!. But it's not, so luckily the compiler stops you before you can run your app and crash it.

SKView is the class for the view property of SKScene

To write games with Sprite Kit you have to know the differences between UIViewController and SKScene Good luck!

SKScene class reference

UIViewController class reference

Upvotes: 1

Related Questions