Emm
Emm

Reputation: 1603

How to fix a fatal error on iOS Application, using Swift?

I made a game using SpriteKit and Xcode 7 beta with swift. I tried to add GameCenter and Leaderboard but the problem is that when I run app (simulator) then when I press on leaderboard button the simulator stops running and It show error on run. I don't know how to fix it. I'm using 2 different files: GameViewController.swift, and PointsLabel.swift

There is an Error in file GameViewController.swift:

fatal error: unexpectedly found nil while unwrapping an Optional value

on code:

@IBAction func leaderboard(sender: UIButton) {
    saveHighscore(score.score) //<- Xcode say Here is Error but error shows on run
    showLeader()
}

enter image description here

GameViewController.swift:

import GameKit

class GameViewController: UIViewController,UIGestureRecognizerDelegate, GKGameCenterControllerDelegate {

var score: PointsLabel!

override func viewDidLoad() {
    super.viewDidLoad()

    //initiate gamecenter
func authenticateLocalPlayer(){

    let localPlayer = GKLocalPlayer.localPlayer()

    localPlayer.authenticateHandler = {(GameViewController, error) -> Void in

        if (GameViewController != nil) {
            self.presentViewController(GameViewController!, animated: true, completion: nil)
        }

        else {
            print((GKLocalPlayer.localPlayer().authenticated))
        }
     }
  }
}

@IBAction func leaderboard(sender: UIButton) {

    saveHighscore(score.score)

    showLeader()

}



//send high score to leaderboard
func saveHighscore(score:Int) {

    //check if user is signed in
    if GKLocalPlayer.localPlayer().authenticated {

        let scoreReporter = GKScore(leaderboardIdentifier: "Leaderboard_01")

        scoreReporter.value = Int64(score)

        let scoreArray: [GKScore] = [scoreReporter]

        GKScore.reportScores(scoreArray, withCompletionHandler: {error -> Void in
            if error != nil {
                print("error")
            }
        })
    }
}


    //shows leaderboard screen
    func showLeader() {
        let vc = self.view?.window?.rootViewController
        let gc = GKGameCenterViewController()
        gc.gameCenterDelegate = self
        vc?.presentViewController(gc, animated: true, completion: nil)
    }
}

//hides leaderboard screen
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController)
{
    gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)

}

PointsLabel.swift:

import Foundation
import UIKit
import SpriteKit

class PointsLabel: SKLabelNode {

var score:Int = 0

init(num: Int) {
    super.init()

    fontColor = UIColor.blackColor()
    fontSize = 30.0

    score = num
    text = "\(num)"
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func increment() {
    score++
    text = "\(score)"
}

func setTo(num: Int) {
    self.score = num
    text = "\(self.score)"
 }
}

I hope You can help me because I don't know how to fix it!

Upvotes: 0

Views: 1543

Answers (1)

Eric Aya
Eric Aya

Reputation: 70097

As I suggested for your previous question, start by making the variables names less ambiguous.

The score handler object, var score: PointsLabel!, should become, for example, scoreManager.

Next: I don't see in your example any instanciation of this class. So when you tap your button, you ask for the implicitly unwrapped score object and its score property, but the score object doesnt exist.

An actual solution depends on your application logic, I can't provide magic code for you, but try replacing var score: PointsLabel! with this:

 let scoreManager = PointsLabel(num: 0)

Now you have a valid score holder. Then you can use its score property:

saveHighscore(scoreManager.score)

And use its methods to update the score:

scoreManager.increment()

Etc.

Upvotes: 3

Related Questions