Every time I submit an achievement to Game Center on macOS, using Mac Catalyst, my game crashes with this:
-[GKAchievementInternal showBanner]: unrecognized selector sent to instance 0x600002616ca0
No call stack. I set a break point for all the Obj-C exceptions but it's just stopped in the AppDelegate.
Everything is fine on iOS and iPadOS, and the rest of the Game Center behaviour on macOS seems to be fine.
For reference, this is how I submit the achievements:
private func submitAchievements(_ aList: [Achievement]) {
if !isGameCenterEnabled {
return
}
var achievements : [GKAchievement] = []
for kvp in AchievementFromId {
if aList.contains(kvp.1) {
let achievement = GKAchievement(identifier: kvp.0)
achievement.showsCompletionBanner = true
achievement.percentComplete = 100.0
achievements.append(achievement)
}
}
if achievements.count > 0 {
GKAchievement.report(achievements, withCompletionHandler: { (error: Error?) -> Void in
if let err = error {
NSLog("submitAchievements: \(err.localizedDescription)")
}
})
}
}
That function uses these data structures:
enum Achievement : Int {
case
clearTutorial = 0x00000001,
clearLevel1 = 0x00000002,
clearLevel2 = 0x00000004,
}
let AchievementFromId : [String : Achievement] = [
"Tutorial": .clearTutorial,
"Level1": .clearLevel1,
"Level2": .clearLevel2,
]
Edit:
I filed a feedback with the Feedback Assistant. In the meantime, the only workaround I found is disabling the completion banners on macOS:
#if targetEnvironment(macCatalyst)
achievement.showsCompletionBanner = false
#else
achievement.showsCompletionBanner = true
#endif
Also, to reset the achievements and test this, I use this function:
GKAchievement.resetAchievements() { error in
if let error = error {
NSLog("resetAchievements: \(error.localizedDescription)")
} else if let fn = onCompletion {
syncAchievements() // function that resubmits all the achievements again
}
}
This was a bug in macOS Catalina. Apple has resolved this in macOS 11 Big Sur (Feedback reference: FB7847659)
They don't have plans to fix this on Catalina.
For Catalina, just avoid showing banners with achievement.showsCompletionBanner = false
. This looks a bit ugly, but I did this:
#if targetEnvironment(macCatalyst)
let os = ProcessInfo().operatingSystemVersion
achievement.showsCompletionBanner = os.majorVersion >= 11
#else
achievement.showsCompletionBanner = true
#endif
Note that I use ProcessInfo()
because for some reason if #available(macOS 11.0, *)
returns true in Catalina as well.
User contributions licensed under CC BY-SA 3.0