SwiftUIでGameKitリーダーボードを実装する方法【6ステップ完全ガイド】
この記事では、アプリにGameCenterのリーダーボード(Leaderboard)を実装すべき理由と、その具体的な実装方法を詳しく解説します。
なぜGameCenterが再び注目されているのか
スコアボードがなくてもiPhoneゲームは作れますが、リーダーボードを導入するとゲームの競争性が高まり、「世界中のプレイヤーと競い合っている」という感覚をユーザーに与えることができます。
自前でバックエンドを構築・管理する代わりに、GameCenterリーダーボードを利用すれば、トラフィックに応じて無限にスケールでき、認証のためのログイン画面を丸ごと省略でき、さらにプレイヤーの画像・名前・同じゲームを遊んでいる友達の情報まで、ユーザーに何も入力させることなく取得できます。
特にiOS 16以降、AppleはGameCenterの改善に積極的に投資しており、友達があなたのスコアを上回ったときにプッシュ通知を送るなど、アプリの利用を促進する機能を強化しています。
筆者自身もSwiftUIを学ぶ過程でアプリを作成・公開してきました。それが最も効果的な学習方法だと考えているからです。しかし、この分野のドキュメントは十分に更新されておらず、特にSwiftUI向けの情報や、Swiftのasync/await登場後の実装例はほとんど存在しませんでした。そこで本記事では、誰もが優れたアプリを作れるよう、情報を整理してシンプルにまとめました。ぜひあなたのアプリのテストにも招待してください!
前提条件
- Apple Developerの有料アカウントが必要です
- Apple Developer Portalのプロビジョニングプロファイルセクションで、アプリのApp IDを作成しておく必要があります
- App Store Connectポータルでアプリを登録しておく必要があります
6ステップでiOSリーダーボードを実装する方法
リーダーボードのコードロジックの大部分はひとつのファイルにまとまっています。コードだけ先に確認したい方は、該当セクションへスキップしてください。手順は以下の通りです。
ステップ1:App Store Connectでリーダーボードを作成する

App Store Connectポータルでアプリの作成が完了したら、アプリの「サービス」タブに移動し、GameCenterページが開いていることを確認します。
次に「+」ボタンで新しいリーダーボードを追加します。タイプは「クラシック」(スコアがリセットされない)または「繰り返し」(設定した頻度でスコアがリセットされる)のどちらかを選択できます。
多くのゲームでは、到達不可能な古いハイスコアでリーダーボードが埋まってしまうのを防ぐため、「繰り返し」タイプが好まれています。
ここで入力するLeaderboardIDは、コード内でIDの指定を求められるすべての場所で使用することになります。忘れずに控えておきましょう。

ステップ2:GameCenter認証をセットアップする
まず、これらの機能を動作させるために、ユーザーをGameCenterに認証させる必要があります。
以下のコードを使用します。GKLocalPlayer.localが認証済みであることを確認し、エラーがあればコンソールに出力する仕組みです:
func authenticateUser() {
GKLocalPlayer.local.authenticateHandler = { vc, error in
guard error == nil else {
print(error?.localizedDescription ?? "")
return
}
}
}
認証に成功すると、UI上に小さなポップアップが表示されます。未認証の場合は、GameCenterアカウントへのログインページへ自動的に遷移します。

ステップ3:リーダーボードの項目をUIに表示する
GameCenterのViewControllerリーダーボード(GKLeaderboard)からデータを取得するには、loadLeaderboardsを使用します。
loadEntries関数の引数を.globalから.friendsに変更すれば、友達のみのランキングを取得することも可能です。
また、各プレイヤーを反復処理してloadPhotoを実行することで、各プレイヤーのプロフィール画像も取得できます。
NSRange(1...5)を使えば、表示するプレイヤーの人数を指定できます。この例ではリーダーボード上位5名のスコアを取得し、該当するユーザーがいない場合(繰り返しリーダーボードのサイクルが更新された直後など)は何も返しません。
async-awaitを活用すると、リーダーボードからのデータ取得は次のように書けます:
func loadLeaderboard() async {
playersList.removeAll()
Task{
var playersListTemp : [Player] = []
let leaderboards = try await GKLeaderboard.loadLeaderboards(IDs: [leaderboardIdentifier])
if let leaderboard = leaderboards.filter ({ $0.baseLeaderboardID == self.leaderboardIdentifier }).first {
let allPlayers = try await leaderboard.loadEntries(for: .global, timeScope: .allTime, range: NSRange(1...5))
if allPlayers.1.count > 0 {
try await allPlayers.1.asyncForEach { leaderboardEntry in
var image = try await leaderboardEntry.player.loadPhoto(for: .small)
playersListTemp.append(Player(name: leaderboardEntry.player.displayName, score:leaderboardEntry.formattedScore, image: image))
print(playersListTemp)
playersListTemp.sort{
$0.score < $1.score
}
}
}
}
playersList = playersListTemp
}
}

ステップ4:ビューの表示時にSwiftUIで機能を呼び出す
ビューのonAppearライフサイクル関数を利用して、認証とデータ読み込みの呼び出しを行うのが一般的です。もちろん、ボタンのタップをトリガーにしても問題ありません:
.onAppear(){
if !GKLocalPlayer.local.isAuthenticated {
authenticateUser()
} else if playersList.count == 0 {
Task{
await loadLeaderboard()
}
}
}
ステップ5:送信されたスコアを読み込む
スコアを読み込むには、事前にスコアを送信しておく必要があります。その役割を担うのがsubmitScore関数です。
flightsClimbed変数には、送信したいスコアの値を格納します- GameKitは、リーダーボードの存続期間中、自動的にベストスコアのみを表示してくれます
leaderboardIdには、App Store Connectで手動入力した値を指定します:
func leaderboard() async{
Task{
try await GKLeaderboard.submitScore(
flightsClimbed,
context: 0,
player: GKLocalPlayer.local,
leaderboardIDs: ["com.tfp.stairsteppermaster.flights"]
)
}
calculateAchievements()
}ステップ6:GameCenter ViewControllerポータルを表示する
GameCenterにログインすると、画面右上に小さなアイコン(アクセスポイント)が表示されます。これをタップするとGameCenter ViewControllerへ移動します。デザインに馴染まない場合は、GKAccessPoint.shared.isActive = falseを使って非表示にできます。
GameCenterのUIはUIKitのViewControllerであり、単純なSwiftUIのViewではないため、独自のボタンからGameCenterを起動したい場合は、まずUIViewControllerRepresentableを作成する必要があります。
そのファイルをプロジェクトに追加すれば、GameCenterポータルは次のように一行で表示できます:GameCenterView(format: gameCenterViewControllerState)。gameCenterViewControllerStateを指定すれば、GameCenterの詳細ページへ直接遷移させることも可能です。

GameCenterリーダーボード利用時の注意点
- シミュレータでのデバッグ – 理由は不明ですが、シミュレータ上でのGameCenter認証は非常に遅くなることがあります。シミュレータで開発する場合は、モックデータを用意しておくと効率的です。
- チャレンジ – 非推奨(Deprecated)となったため、プログラムからGameKitチャレンジを友達に発行することはできなくなりました。代わりに、ユーザーのGameCenterダッシュボード内で、GameKit実績に対して手動で行う必要があります。また、送信済みのチャレンジを確認する手段もありません。
- 実績(Achievements) – リーダーボードとGameKit実績は別物です。実績は計算・表示の仕組みが異なりますが、実装ははるかに簡単です。実績もアプリ内に取り込むことができます:

まとめ
本記事で紹介した無料のオープンソースアプリ「Stair Master Climber」(iPhone向けヘルス&フィットネスアプリ)をぜひ試してみてください。感想をいただけると嬉しいです。共に学んでいきましょう。
ご質問がある場合は、SNSやメールでお気軽にお問い合わせください。
-
【iOS】iMessageのアプリアイコンを非表示にする方法を解説
iOS 11には魅力的な機能が多数搭載されており、Appleがこれまでにリリースした中でも最大級のソフトウェアアップデートと言えます。刷新されたコントロールセンター、新デザインのApp Store、強化されたSiri対応など、見逃せない要素ばかりです。すでに最新バージョンへアップデート済みの方も多いのではないでしょうか。実は、標準の「メッセージ」アプリにも大きな変更が加えられています。新しいメッセージを開くと、画面下部にiMessage用のアプリへのクイックアクセスメニューが表示されることに気づいた方もいるでしょう。頻繁に使わないユーザーにとっては、このメニューがやや邪魔に感じられることもあり
-
iOS 12のメッセージアプリで写真(フォトライブラリ)にアクセスして送信する方法
iOS 3の登場以来、Appleデバイスでは「メッセージ」アプリを通じて写真や動画を送れるようになりました。カメラアイコンをタップして、送りたい写真や動画を選ぶだけというシンプルな操作でした。しかしiOS 12ではこの仕組みが変更されました。とはいえ、写真へのアクセスが完全に不可能になったわけではありません。iOS 12では、「メッセージ」でカメラアイコンをタップすると、iPhoneのカメラが直接起動し、その場で新しい写真や動画を撮影できる仕様になっています。Appleの多彩なカメラエフェクトを使った撮影や、シェイプやステッカーパックの追加なども楽しめます。ただし、「メッセージ」内からフォトラ