SwiftUI GKLeaderboard loadEntries

1.3k Views Asked by At

I would like to add leaderboards to my SwiftUI app.
I can't find any examples of using loadEntries to load leaderboard values. I tried the following...

let leaderBoard: GKLeaderboard = GKLeaderboard()
leaderBoard.identifier = "YOUR_LEADERBOARD_ID_HERE"
leaderBoard.timeScope = .allTime
leaderBoard.loadScores { (scores, error) in ...

This results in the following warnings:

  • 'identifier' was deprecated in iOS 14.0: Use loadEntriesForPlayerScope:timeScope:range:completionHandler: instead.
  • 'timeScope' was deprecated in iOS 14.0: Use loadEntriesForPlayerScope:timeScope:range:completionHandler: instead.
  • 'loadScores(completionHandler:)' was deprecated in iOS 14.0: Use loadEntriesForPlayerScope:timeScope:range:completionHandler:.

using loadEntriesForPlayerScope results in the following warning:

  • 'loadEntriesForPlayerScope(_:timeScope:range:completionHandler:)' has been renamed to 'loadEntries(for:timeScope:range:completionHandler:)'

Using loadEntries I don't know how to specify the leaderboard identifier.

2

There are 2 best solutions below

1
Asperi On BEST ANSWER

Here is simple demo of possible approach - put everything in view model and load scores on view appear.

import GameKit

class BoardModel: ObservableObject {
    private var board: GKLeaderboard?
    @Published var localPlayerScore: GKLeaderboard.Entry?
    @Published var topScores: [GKLeaderboard.Entry]?
    
    func load() {
        if nil == board {
            GKLeaderboard.loadLeaderboards(IDs: ["YOUR_LEADERBOARD_ID_HERE"]) { [weak self] (boards, error) in
                self?.board = boards?.first
                self?.updateScores()
            }
        } else {
            self.updateScores()
        }
    }
    
    func updateScores() {
        board?.loadEntries(for: .global, timeScope: .allTime, range: NSRange(location: 1, length: 10),
            completionHandler: { [weak self] (local, entries, count, error) in
            DispatchQueue.main.async {
                self?.localPlayerScore = local
                self?.topScores = entries
            }
        })
    }
}

struct DemoGameboardview: View {
    @StateObject var vm = BoardModel()
    var body: some View {
        List {
            ForEach(vm.topScores ?? [], id: \.self) { item in
                HStack {
                    Text(item.player.displayName)
                    Spacer()
                    Text(item.formattedScore)
                }
            }
        }
        .onAppear {
            vm.load()
        }
    }
}
1
lorem ipsum On

I might be stating the obvious but have you looked at the WWDC20 videos? Usually when there are big changes like this they cover it during WWDC that year.

Tap into Game Center: Leaderboards, Achievements, and Multiplayer

Tap into Game Center: Dashboard, Access Point, and Profile

I haven't looked at the videos but the documentation eludes that identifier might be replaced by var baseLeaderboardID: String