iPhone
 Computer >> コンピューター >  >> スマートフォン >> iPhone

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でリーダーボードを作成する

SwiftUIでGameKitリーダーボードを実装する方法【6ステップ完全ガイド】
Apple iTunes Connectポータルのスクリーンショット

App Store Connectポータルでアプリの作成が完了したら、アプリの「サービス」タブに移動し、GameCenterページが開いていることを確認します。

次に「+」ボタンで新しいリーダーボードを追加します。タイプは「クラシック」(スコアがリセットされない)または「繰り返し」(設定した頻度でスコアがリセットされる)のどちらかを選択できます。

多くのゲームでは、到達不可能な古いハイスコアでリーダーボードが埋まってしまうのを防ぐため、「繰り返し」タイプが好まれています。

ここで入力するLeaderboardIDは、コード内でIDの指定を求められるすべての場所で使用することになります。忘れずに控えておきましょう。

SwiftUIでGameKitリーダーボードを実装する方法【6ステップ完全ガイド】
新しいリーダーボードの作成に必要な項目

ステップ2:GameCenter認証をセットアップする

まず、これらの機能を動作させるために、ユーザーをGameCenterに認証させる必要があります。

以下のコードを使用します。GKLocalPlayer.localが認証済みであることを確認し、エラーがあればコンソールに出力する仕組みです:

func authenticateUser() {
    GKLocalPlayer.local.authenticateHandler = { vc, error in
        guard error == nil else {
            print(error?.localizedDescription ?? "")
            return
        }
    }
}

認証に成功すると、UI上に小さなポップアップが表示されます。未認証の場合は、GameCenterアカウントへのログインページへ自動的に遷移します。

SwiftUIでGameKitリーダーボードを実装する方法【6ステップ完全ガイド】
ユーザーがログインしている際に表示されるサイン

ステップ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            
    }
}
SwiftUIでGameKitリーダーボードを実装する方法【6ステップ完全ガイド】
リーダーボードのデータをアプリ内に取り込める

ステップ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の詳細ページへ直接遷移させることも可能です。

SwiftUIでGameKitリーダーボードを実装する方法【6ステップ完全ガイド】
GameCenterのリーダーボード表示

GameCenterリーダーボード利用時の注意点

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

まとめ

本記事で紹介した無料のオープンソースアプリ「Stair Master Climber」(iPhone向けヘルス&フィットネスアプリ)をぜひ試してみてください。感想をいただけると嬉しいです。共に学んでいきましょう。

ご質問がある場合は、SNSやメールでお気軽にお問い合わせください。

  1. 【iOS】iMessageのアプリアイコンを非表示にする方法を解説

    iOS 11には魅力的な機能が多数搭載されており、Appleがこれまでにリリースした中でも最大級のソフトウェアアップデートと言えます。刷新されたコントロールセンター、新デザインのApp Store、強化されたSiri対応など、見逃せない要素ばかりです。すでに最新バージョンへアップデート済みの方も多いのではないでしょうか。実は、標準の「メッセージ」アプリにも大きな変更が加えられています。新しいメッセージを開くと、画面下部にiMessage用のアプリへのクイックアクセスメニューが表示されることに気づいた方もいるでしょう。頻繁に使わないユーザーにとっては、このメニューがやや邪魔に感じられることもあり

  2. iOS 12のメッセージアプリで写真(フォトライブラリ)にアクセスして送信する方法

    iOS 3の登場以来、Appleデバイスでは「メッセージ」アプリを通じて写真や動画を送れるようになりました。カメラアイコンをタップして、送りたい写真や動画を選ぶだけというシンプルな操作でした。しかしiOS 12ではこの仕組みが変更されました。とはいえ、写真へのアクセスが完全に不可能になったわけではありません。iOS 12では、「メッセージ」でカメラアイコンをタップすると、iPhoneのカメラが直接起動し、その場で新しい写真や動画を撮影できる仕様になっています。Appleの多彩なカメラエフェクトを使った撮影や、シェイプやステッカーパックの追加なども楽しめます。ただし、「メッセージ」内からフォトラ