iPhone などの iOS アプリ で Game Center と連携する際に、ログインが済んだ後のタイミングで、Leaderboard に保存してあるスコア値を取得・表示するコードを紹介する。
筆者のマシン | |
---|---|
Mac | mac mini (M1, 2020) |
OS | Monterey バージョン 12.4 |
XCode | バージョン 13.4 |
Swift | バージョン 5.6.1 |
ここでは次の手順で説明する。
- はじめに
- Game Centerログイン状態の変更を受信する Observer をセットする
- Observer 処理で、Leaderboard からスコア値を取得し画面へ表示
はじめに
以前こちらの記事(Apple の Game Center スコア値を取得する)で、Game Center にログインした後、ボタンをタップすることで Leaderboard からスコア値を取得し表示する方法を紹介した。
実際のゲームアプリでは、スコアを表示させるために、いちいちボタンをタップするのは煩わしい。そこで、Notification Center を用いて、Game Center にログイン処理後に、自動的にスコアを読み込み表示する方法を紹介する。
尚、本記事で紹介するコード全体(XCodeプロジェクト)は、GitHubで公開している。
Game Centerログイン状態の変更を受信する Observer をセットする
アプリが Game Center と連携する際、GKLocalPlayer.local.authenticateHandlerを呼び出すことで、Game Center へログインしていなければログイン画面を提示しログインを促す。これについてはこちらの記事(Apple の Game Center スコア値を取得する)でコードを紹介している。
GKLocalPlayer には、static な定数 GKPlayerAuthenticationDidChangeNotificationName がある。ドキュメントより、ローカルプレイヤー(アプリ起動時に Game Center にログインしているユーザ)の認証後に、この通知が送信されることがわかる。
ここでは、認証が済んだら Game Center の Leaderboard にあるスコアを取得するために、次のように認証ステータス変更通知を受信する Observer として、自作のメソッド authenticationChanged を実行させるようにする。NotificationCenter.default.addObserver(
forName: .GKPlayerAuthenticationDidChangeNotificationName,
object: nil,
queue: OperationQueue.main,
using: { _ in
// this block is called whether authentication succeeds or fails.
self.authenticationChanged()
}
)
こうすることで、Game Center へのログイン状態が変更になった場合に、authenticationChanged メソッドが実行される。
ここで、GKPlayerAuthenticationDidChangeNotificationName は、ログインした時とログアウトした時のいずれの場合も通知される点が注意点である。
Observer 処理で、Leaderboard からスコア値を取得し画面へ表示
ログイン状態変更時の Observer である自作メソッドauthenticationChanged は下記である。ログイン済みであれば Leaderboard からスコアを取得するように 下記3行目の if GKLocalPlayer.local.isAuthenticated で認証済みかをチェックしている。
19行目で、予め定義済みの変数に、Leaderboard から取得した全世界のトップスコアをセットしている。
また23行目で、予め定義済みの変数に、Leaderboard から取得したローカルプレイヤーのスコアをセットしている。
補足として、このコードでは、デフォルトの Leaderboard を使用している。
private func authenticationChanged() {
if GKLocalPlayer.local.isAuthenticated {
print("You are logged in. Start to load scores from Game Center.")
// Get the Leaderboard ID of this app that you have previously registered in App Store Connect
// (only one ID is registered here).
GKLocalPlayer.local.loadDefaultLeaderboardIdentifier(completionHandler: { (leaderboardIdentifer, error) in
if error != nil { // Error occured
print(error!.localizedDescription)
} else { // Got the loaderBoarderIdentifier for this app.
// Load scores
if let leaderboarderId = leaderboardIdentifer {
print("Default leaderboardIdentifer is \(leaderboarderId).")
GKLeaderboard.loadLeaderboards(IDs: [leaderboarderId]) { (boards, _) in
boards?.first?.loadEntries(for: .global, timeScope: .allTime, range: NSRange(location: 1, length: 1), completionHandler: {(local, entries, _, _) in
// If entries are loaded, set the value to worldHighScore
if let entries = entries,
entries.isEmpty == false {
self.autoLoadScore.worldScore = entries[0].score
}
// If local is loaded, set the value to yourHighScore
if let local = local {
self.autoLoadScore.yourScore = local.score
}
})
}
}
}
})
}
}
これらによる画面の動きを下記の画面キャプチャで説明する。
左側の Game Center のログイン前の画面では、Leaderboared から値 worldScore(全世界のトップスコア)およびmyScore(ローカルプレイヤーのスコア)が取得されていないため、赤色の下線部分はデフォルトの 0 を表示している。
赤枠のサインインより Game Center へログインすることで、右側の画面のように、ログイン後に自動的に、Leaderboard のスコア読み込みと表示ができる。
尚、画面の下側の青枠部分は、ボタンをタップしたら Leaderboard からスコアを取得し表示するものである。これについては以前の記事(Apple の Game Center スコア値を取得する)で紹介している。
以上