How to display a Game Center leaderboard in SpriteKit?

195 Views Asked by At

I'm pretty new to Swift and I'm having some trouble implementing a leaderboard into my game.

So far, I'm able to authenticate local player and set up leaderboard in iTunes Connect.

However, I'm unable to display the leaderboard itself, if I run the below code, it will abort when I click on GK Leaderboard button in SKScene. So, the question is how can I display the GK leaderboard from SKScene? Thanks!

GameViewController.swift

 import SpriteKit
 import GameKit

 class GameViewController: UIViewController, GKGameCenterControllerDelegate {

override func viewDidLoad() {
    
    super.viewDidLoad()
    
    let scene = SceneMenu(size: view.frame.size)
    scene.scaleMode = .aspectFill
    scene.backgroundColor = .white
    
    let view = view as! SKView
    view.presentScene(scene)

    view.showsFPS = true
    view.showsNodeCount = true

    authenticateLocalPlayer()

}

func authenticateLocalPlayer() {
    
    GKLocalPlayer.local.authenticateHandler = { viewController, error in
    
    }
    
}

func showLeaderboard() {
    
    let gcVC = GKGameCenterViewController(leaderboardID: "com.generic.leaderboard", playerScope: .global, timeScope: .allTime)
    gcVC.gameCenterDelegate = self
    present(gcVC, animated: true)
    
}

func gameCenterViewControllerDidFinish(_ gameCenterViewController: GKGameCenterViewController) {
    
    gameCenterViewController.dismiss(animated: true)
    
}
}

SceneMenu.swift

import SpriteKit
import GameKit

class SceneMenu: SKScene {

override init(size: CGSize) {
    
    super.init(size: size)
    
    let btnGK = SKLabelNode(text: "GameKit")
    btnGK.name = "btn_gk"
    btnGK.fontSize = 20
    btnGK.fontColor = SKColor.blue
    btnGK.fontName = "Avenir"
    btnGK.position = CGPoint(x: size.width / 2, y: size.height / 2)
    addChild(btnGK)
    
    let btnLeaderboard = SKLabelNode(text: "GK Leaderboard")
    btnLeaderboard.name = "btn_leaderboard"
    btnLeaderboard.fontSize = 20
    btnLeaderboard.fontColor = SKColor.blue
    btnLeaderboard.fontName = "Avenir"
    btnLeaderboard.position = CGPoint(x: size.width / 2, y: size.height / 2 - 50)
    addChild(btnLeaderboard)
    
}

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

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
    if let touch = touches.first {
        
        let location = touch.location(in: self)
        let action = atPoint(location)
        
        switch action.name {
            
        case "btn_gk":
            
            print("btn_gk")
           
            GKLeaderboard.submitScore(10, context: 0, player: GKLocalPlayer.local, leaderboardIDs: ["com.generic.leaderboard"]) { _ in }
          
        case "btn_leaderboard":
            
            print("btn_leaderboard")
            
            GameViewController().showLeaderboard()
  
        default:
            
            print("nothing")
            
        }
        
    }
    
}

}
1

There are 1 best solutions below

6
Fogmeister On

I can’t provide any code right now but what you really should be doing is using something like UIKit to create a UIView for the leader board and then embed that into a SKScene.

There is an interface something like SKView that is backed by a UIView which makes this fairly easy to do.

Keep Sprite Kit for the game stuff. Use UIKit for the UI stuff.