jotos
jotos

Reputation: 71

How to present SKScene from UIViewController in swift

My SpriteKit app (named CurlShots) is crashing at launch when it is trying to present the first scene (the main menu). Everything works fine in simulator and devices with debug builds but with an archived build that I'm installing with iTunes I'm getting a crash in didMoveToView of the menu scene.

@objc class MenuScene: SKScene {
...
Last Exception Backtrace:
0   CoreFoundation                 0x18673c2d8 __exceptionPreprocess + 132
1   libobjc.A.dylib               0x197be80e4 objc_exception_throw + 60
2   CoreFoundation                  0x186743290 +[NSObject(NSObject) doesNotRecognizeSelector:] + 220
3   CoreFoundation                  0x186740154 ___forwarding___ + 928
4   CoreFoundation                  0x186642ccc _CF_forwarding_prep_0 + 92
5   CurlShots                     0x10011b208 function signature specialization  of CurlShots.MenuScene.didMoveToView (CurlShots.MenuScene)(ObjectiveC.SKView) -> () (MenuScene.swift:71)
6   CurlShots                     0x100116c80 @objc CurlShots.MenuScene.didMoveToView (CurlShots.MenuScene)(ObjectiveC.SKView) -> () (MenuScene.swift:0)
7   SpriteKit                     0x18afd7770 -[SKScene _didMoveToView:] + 88
8   SpriteKit                     0x18afef004 -[SKView presentScene:] + 264
9   CurlShots                     0x10012801c function signature specialization  of CurlShots.GameViewController.viewWillLayoutSubviews (CurlShots.GameViewController)() -> () (GameViewController.swift:70)

I'm using auto layout and viewDidLoad of the VC has no code. Instead, I'm presenting the scene from viewWillLayoutSubviews because I need the device screen size for initializing the scene

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        let skView = self.view as! SKView
        if skView.scene == nil
        {
            skView.showsFPS = false
            skView.showsNodeCount = false
            skView.ignoresSiblingOrder = true

            let mainMenu = MenuScene(size: skView.bounds.size)
            mainMenu.scaleMode = .AspectFill
            skView.presentScene(mainMenu)
        }
    }

I've tried to remove all code from didMoveToView of the menu scene but that has no effect. Also tried commenting out variables in the menu scene although none of them were conditional. I tried to retain the mainMenu scene in a variable to avoid it being released but that did not solve the crash. Also tried overriding the init(size) of the scene to verify that the menu scene actually gets created before it is presented. Don't know what else to try. Because the crash only happens in archived package I cannot debug by setting breakpoints.

Upvotes: 1

Views: 1004

Answers (2)

jotos
jotos

Reputation: 71

I found a solution to the problem by meticulously removing code lines until I found the root cause. This looks more like a bug on the Apple side but anyways changing one code line fixed the crash.

The crash was caused by the scene to be presented. Inside didMoveToView I was checking whether the device is an iPad by using UIUserInterfaceIdiom and for some reason swift did not like that in release build. I'm calculating a scaling factor per the screen width in the code so now I use that info to determine whether the device is an iPad. So, the code change that I did was to replace line

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Pad) {

with a line

if(scaling > 2.0) { // if iPad

Upvotes: 0

bobsim21
bobsim21

Reputation: 21

Did you make sure to set the Main Menu as your first view by going to story board and on the right panel selecting "set view as first view" ( or something like that )? sometimes this throws this error. May not be the overall solution but it is worth checking

Upvotes: 0

Related Questions