Reputation: 1603
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()
}
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
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