ในบทความนี้เราจะพูดถึงเหตุผลและวิธีการนำ Leaderboard ของ GameCenter ไปใช้ในแอปของคุณ
ทำไม GameCenter จึงกลับมาฟื้นฟูอย่างใหญ่โต
คุณสามารถทำเกม iPhone ได้โดยไม่ต้องมีกระดานคะแนน แต่ Leaderboard ช่วยทำให้เกมรู้สึกแข่งขันมากขึ้น เหมือนผู้คนแข่งขันกันทั่วโลก
แทนที่จะสร้างและจัดการ Backend ของตัวเอง GameCenter Leaderboard ช่วยให้คุณขยายได้ไม่จำกัดกับトラフィック ข้ามหน้าล็อกอินทั้งหน้าสำหรับการอนุมัติ รับรูปภาพ ชื่อ และเพื่อนที่เล่นเกมเดียวกัน — ทั้งหมดนี้โดยผู้ใช้ไม่ต้องป้อนอะไรเลย
โดยเฉพาะกับ iOS 16 Apple ลงทุนมากขึ้นในการปรับปรุง และขับเคลื่อนการใช้งานแอปมากขึ้น เช่น ผ่าน Push Notifications เมื่อเพื่อนทำคะแนนเกินคุณในเกม
ในเส้นทางการเรียนรู้ SwiftUI ของผม ผมสร้างและเผยแพร่แอป เพราะผมคิดว่านั่นคือวิธีที่ดีที่สุดในการเรียนรู้
ไม่มีเอกสารที่อัปเดตมากนักเกี่ยวกับวิธีทำสิ่งเหล่านี้ โดยเฉพาะไม่มีกับ SwiftUI และไม่มีกับ async/await ใน Swift ผมจึงรวบรวมและลดความซับซ้อนไว้ให้ทุกคนสร้างแอปเก๋ๆ ได้ โปรดเชิญผมทดสอบแอปของคุณด้วย!
ข้อกำหนดเบื้องต้น:
- คุณต้องมีบัญชี Apple Developer แบบชำระเงิน
- คุณต้องสร้าง App ID สำหรับแอปในส่วน Provisioning Profiles ของ Apple Developer Portal
- คุณต้องสร้างแอปในพอร์ทัล iTunes Connect Connect
วิธีนำ Leaderboard iOS ไปใช้ใน 6 ขั้นตอน
ตรรกะโค้ดส่วนใหญ่สำหรับ Leaderboard อยู่ในไฟล์นี้ถ้าคุณอยากข้ามไปข้างหน้า นี่คือขั้นตอน:
1. วิธีสร้าง Leaderboard ใน App Store Connect

เมื่อสร้างแอปในพอร์ทัล App Store Connect สำเร็จ ไปที่แท็บ Services ของแอป -> และตรวจสอบว่าอยู่ในหน้า GameCenter
จากนั้นเพิ่ม Leaderboard ใหม่ด้วยเครื่องหมาย "+" ซึ่งสามารถเป็น "Classic" (คะแนนไม่รีเซ็ต) หรือ "Recurring" (คะแนนรีเซ็ตตามความถี่ที่ตั้ง)
เกมส่วนใหญ่ชอบ Leaderboard แบบ Recurring เพื่อไม่ให้ Leaderboard 混雜 ด้วยคะแนนสูงเก่าที่ไม่อาจทำได้
LeaderboardID ที่คุณป้อนนั่นคือสิ่งที่คุณต้องใช้ในทุกที่ในโค้ดที่ขอ

2. วิธีตั้งค่าการยืนยันตัวตน GameCenter
ก่อนอื่น คุณต้องยืนยันตัวตนผู้ใช้กับ GameCenter เพื่อให้ฟังก์ชันเหล่านี้ทำงาน
เราจะใช้โค้ดนี้ ซึ่งตรวจสอบว่าคุณ (GKLocalPlayer.local) ยืนยันตัวตนแล้ว หรือพิมพ์ข้อผิดพลาดถ้ามี:
func authenticateUser() {
GKLocalPlayer.local.authenticateHandler = { vc, error in
guard error == nil else {
print(error?.localizedDescription ?? "")
return
}
}
}
ถ้าผู้ใช้ยืนยันตัวตนแล้ว คุณจะเห็นป๊อปอัปเล็กๆ ใน UI ถ้าไม่ ผู้ใช้จะถูกนำไปหน้าล็อกอินบัญชี GameCenter

3. วิธีแสดงรายการ Leaderboard ใน UI
เพื่อดึงข้อมูลออกมาจาก ViewController Leaderboard ของ GameCenter (GKLeaderboard) คุณต้องใช้ loadLeaderboards
คุณสามารถสลับฟังก์ชัน loadEntries จาก .global เป็น .friends เพื่อดึงเฉพาะเพื่อน
คุณยังสามารถดึงรูปภาพของแต่ละผู้เล่นโดยวนลูปแต่ละผู้เล่นและทำ loadPhoto
ใช้ NSRang(1...5) คุณสามารถเลือกจำนวนผู้เล่นที่จะแสดง ได้ผู้ใช้ที่มีคะแนนสูงสุด 5 อันดับจาก Leaderboard และคืนค่า none ถ้าไม่มีผู้ใช้ เช่นกรณีที่รอบรีเฟรชสำหรับ Leaderboard แบบ Recurring
นี่คือตัวอย่างการดึงข้อมูลจาก Leaderboard ถ้าคุณใช้ประโยชน์จาก 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 เมื่อ View/Page ปรากฏ
คุณสามารถใช้ประโยชน์จากฟังก์ชัน lifecycle onAppear ของ View เพื่อเรียก authenticate และ load แต่ก็สามารถทำได้เมื่อกดปุ่มถ้าชอบ:
.onAppear(){
if !GKLocalPlayer.local.isAuthenticated {
authenticateUser()
} else if playersList.count == 0 {
Task{
await loadLeaderboard()
}
}
}
5. วิธีโหลดคะแนนที่ส่ง
เพื่อโหลดคะแนน คุณต้องส่งคะแนนด้วย ฟังก์ชัน submitScore ช่วยได้
- ตัวแปร
flightsClimbedควรมีคะแนนที่คุณต้องการส่ง - GameKit รับรองว่าจะแสดงคะแนนสูงสุดของคุณตลอดอายุของ Leaderboard
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
เนื่องจาก UI ของ GameCenter เป็น UIKit ViewController ไม่ใช่ SwiftUI View ธรรมดา คุณต้องสร้าง UIViewControllerRepresentable ก่อน (เห็นได้ที่นี่) เพื่อเปิด GameCenter ด้วยปุ่มอื่น
เมื่อเพิ่มไฟล์นั้นเข้โปรเจกต์ คุณสามารถแสดงพอร์ทัล GameCenter ได้เพียงแค่ใช้: GameCenterView(format: gameCenterViewControllerState) โดย gameCenterViewControllerState ช่วยนำคุณไปหน้ารายละเอียดใน GameCenter

สิ่งที่ควรจำไว้ขณะใช้ Leaderboard ของ GameCenter:
- การดีบัก Simulator – ไม่รู้ว่าทำไม การยืนยันตัวตนกับ GameCenter ช้ามากบน Simulator อาจควรสร้างข้อมูลจำลอง (mock) เมื่อใช้ Simulator
- Challenges – ไม่สามารถส่ง Challenge ของ GameKit ให้เพื่อนทางโปรแกรมได้อีกต่อไป เนื่องจาก Deprecated ต้องทำด้วยตนเองในแดชบอร์ด GameCenter ของผู้ใช้เทียบกับ GameKit Achievements นอกจากนี้ไม่มีทางดู Challenges ที่ส่งไป
- Achievements – Leaderboard ต่างจาก GameKit Achievements ซึ่งคำนวณและแสดงต่างออกไป แต่ง่ายกว่ามาก สามารถดึงเข้าแอปได้เหมือนกัน ดูด้านล่าง:

สรุป
คุณสามารถลองแอป Stair Master Climber iPhone Health & Fitness ฟรีและโอเพนซอร์สที่ผมแชร์ข้างต้น ผมอยากรู้ความคิดเห็นเพื่อเรียนรู้ร่วมกัน
อย่าลังเลติดต่อผมทางโซเชียลมีเดียหรืออีเมลถ้ามีคำถาม