GameKit
Use GameKit for Game Center authentication, competition, matchmaking, social surfaces, and saved-game handoffs; keep rendering, board logic, and full SharePlay group-activity design in their owning framework skills.
Contents
- Authentication
- Access Point
- Dashboard
- Leaderboards
- Achievements
- Real-Time Multiplayer
- Turn-Based Multiplayer
- Common Mistakes
- Review Checklist
- References
Authentication
All GameKit features require the local player to authenticate first. Set the
authenticateHandler on GKLocalPlayer.local early in the app lifecycle.
GameKit calls the handler multiple times during initialization.
Guard on GKLocalPlayer.local.isAuthenticated before calling any GameKit API.
For server-side identity verification, see references/gamekit-patterns.md [blocked].
Access Point
GKAccessPoint displays a Game Center control in a corner of the screen. When
tapped, it opens the Game Center dashboard. Configure it after authentication.
Hide the access point during gameplay and show it on menu screens:
Open the dashboard to a specific state programmatically. Specific leaderboard access-point triggers require iOS 18+.
Dashboard
Present the Game Center dashboard using GKGameCenterViewController. The
presenting object must conform to GKGameCenterControllerDelegate.
Dashboard states include .dashboard, .leaderboards, .achievements, .challenges, .localPlayerProfile, and .localPlayerFriendsList.
Leaderboards
Configure leaderboards in App Store Connect before submitting scores. Supports classic (persistent) and recurring (time-limited, auto-resetting) types.
Submitting Scores
Submit to one or more leaderboards using the class method:
Loading Entries
GKLeaderboard.Entry provides player, rank, score, formattedScore,
context, and date. For recurring leaderboard timing, leaderboard images,
and leaderboard sets, see references/gamekit-patterns.md [blocked].
Achievements
Configure achievements in App Store Connect. Each achievement has a unique identifier, point value, and localized title/description.
Reporting Progress
Set percentComplete from 0...100. The property type is Double, but Apple requires an integer value. GameKit only accepts increases.
Loading Player Achievements
If an achievement is not returned, the player has no progress on it yet. Create
a new GKAchievement(identifier:) to begin reporting. Use
GKAchievement.resetAchievements() to reset all progress during testing.
Real-Time Multiplayer
Real-time multiplayer connects players in a peer-to-peer network for
simultaneous gameplay. Players exchange data directly through GKMatch.
Matchmaking with GameKit UI
Use GKMatchmakerViewController for the standard matchmaking interface:
Implement GKMatchmakerViewControllerDelegate:
Exchanging Data
Send and receive game state through GKMatch and GKMatchDelegate:
Data modes: .reliable sends until delivery succeeds or the connection times out; .unreliable sends once and may arrive out of order. Use .reliable for critical state and .unreliable for small, time-sensitive updates. Treat received match data as untrusted input. Register the local player as a listener (GKLocalPlayer.local.register(self)) to receive invitations. For programmatic matchmaking and custom match UI, see references/gamekit-patterns.md [blocked].
Turn-Based Multiplayer
Turn-based games store match state on Game Center servers. Players take turns asynchronously and do not need to be online simultaneously.
Starting a Match
Taking Turns
Encode game state into Data, end the turn, and specify the next participants:
Ending the Match
Set outcomes for all participants, then end the match:
Listening for Turn Events
Register as a listener. Prefer GKLocalPlayerListener when one object handles multiple Game Center event categories.
Match Data Size
Check the match object's matchDataMaximumSize before ending a turn. Store larger state externally and keep only compact references in match data.
Common Mistakes
Not authenticating before using GameKit APIs
Setting authenticateHandler multiple times
Ignoring multiplayer restrictions
Not setting match delegate immediately
Not calling finishMatchmaking for programmatic matches
Not disconnecting from match
Review Checklist
-
GKLocalPlayer.local.authenticateHandlerset once at app launch -
isAuthenticatedchecked before any GameKit API call - Player restrictions checked (
isUnderage,isMultiplayerGamingRestricted,isPersonalizedCommunicationRestricted) - Game Center capability added in Xcode signing settings
- Leaderboards and achievements configured in App Store Connect
- Access point configured and toggled appropriately during gameplay
-
GKGameCenterControllerDelegatedismisses dashboard ingameCenterViewControllerDidFinish - Match delegate set immediately when match is found
-
finishMatchmaking(for:)called for programmatic matches;disconnect()and nil delegate on exit - Turn-based match data stays under
match.matchDataMaximumSize - Turn-based participants have outcomes set before
endMatchInTurn - Invitation or turn listener registered with
GKLocalPlayer.local.register(_:) - Data mode chosen appropriately:
.reliablefor state,.unreliablefor frequent updates - Error handling for all async GameKit calls
References
- See references/gamekit-patterns.md [blocked] for identity verification, legacy voice chat, saved games, custom match UI, leaderboard images, challenge handling, and rule-based matchmaking.
- GameKit documentation
- GKLocalPlayer
- GKAccessPoint
- GKLeaderboard
- GKAchievement
- GKMatch
- GKTurnBasedMatch


