Developing Game Center Achievements System (iOS)
Game Center is Apple's built-in platform for gamification: achievements, leaderboards, matchmaking. Integrating achievements takes less than a day — provided correct setup in App Store Connect and proper local player authentication.
Setup and Basic Integration
In App Store Connect, create achievements with unique identifiers like com.yourapp.achievement.first_win. For each, set an icon 512×512, title, description, and point value (1–100). Achievements can be one-time or progressive — progressive ones have maximumPoints, and you can report intermediate progress (50%, 75%, 100%).
Local player authentication is a mandatory step, without it all Game Center calls fail with an error:
import GameKit
func authenticatePlayer() {
GKLocalPlayer.local.authenticateHandler = { [weak self] viewController, error in
if let vc = viewController {
// Show Game Center authorization UI
self?.present(vc, animated: true)
} else if GKLocalPlayer.local.isAuthenticated {
// Player is authenticated, can report achievements
self?.loadAchievements()
} else if let error = error {
// Game Center unavailable (Screen Time restrictions, no account)
print("GC auth error: \(error.localizedDescription)")
}
}
}
authenticateHandler needs to be set once at launch. Calling it again with a new handler is normal when transitioning between scenes. Game Center itself caches authentication status.
Reporting an achievement:
func reportAchievement(identifier: String, percentComplete: Double = 100.0) {
guard GKLocalPlayer.local.isAuthenticated else { return }
let achievement = GKAchievement(identifier: identifier)
achievement.percentComplete = percentComplete
achievement.showsCompletionBanner = true // Apple's native banner
GKAchievement.report([achievement]) { error in
if let error = error {
// Save to queue for retry
print("Achievement report failed: \(error)")
}
}
}
showsCompletionBanner = true shows a system banner in Game Center style at 100%. You can disable it and show custom UI, but the native banner doesn't require extra layout work and meets iOS user expectations.
Local Progress Caching
If GKAchievement.report fails with an error (no network, Game Center unavailable) — progress is lost. Solution: save unreported achievements locally via UserDefaults or CoreData and retry on next successful connection.
// On startup, after authentication — load already earned achievements from server
func loadAchievements() {
GKAchievement.loadAchievements { achievements, error in
// Sync with local game state
let earned = Set(achievements?.compactMap { $0.percentComplete >= 100 ? $0.identifier : nil } ?? [])
AchievementManager.shared.syncWithGameCenter(earned: earned)
}
}
Timeline Benchmarks
App Store Connect setup + basic integration (authentication, reporting, caching) — 1 day. Progressive achievements with local progress tracking — within 2–3 days if game logic is ready.







