Game Center achievements are not saving or marking as completed.

I'm trying to implement Game Center in a SpriteKit game I am working on.

Leaderboards started working easily, but all the tutorials I could find online are either written in objc or are from 2015 or earlier I am using Swift 5 and Xcode 11.5. The achievements are set up on App Store Connect and everything works properly, except the achievements do not load and aren't getting marked as completed. Most of my Game Center code is in the GameScene.swift file, but the Game Center page is shown with the GameViewController file.


Here is my main Game Center code.

// MARK: Game Center
    func authenticateLocalPlayer() {
        let localPlayer: GKLocalPlayer = GKLocalPlayer.local
             
        localPlayer.authenticateHandler = {(ViewController, error) -> Void in
            if((ViewController) != nil) {
                // 1. Show login if player is not logged in
                GVC.present(ViewController!, animated: true, completion: nil)
            } else if (localPlayer.isAuthenticated) {
                // 2. Player is already authenticated & logged in, load game center
                self.gcEnabled = true
                     
                // Get the default leaderboard ID
                localPlayer.loadDefaultLeaderboardIdentifier(completionHandler: { (leaderboardIdentifer, error) in
                    if error != nil { print(error as Any)
                    } else { self.gcDefaultLeaderBoard = leaderboardIdentifer! }
                })
                 
            } else {
                // 3. Game center is not enabled on the users device
                self.gcEnabled = false
                print("Local player could not be authenticated!")
                print(error as Any)
            }
        }
    }
    func addPoints(pts: Int64) {
        // Add a point.
        score += pts
        // Submit score to Game Center leaderboard
        let bestScoreInt = GKScore(leaderboardIdentifier: LEADERBOARD_ID)
        bestScoreInt.value = score
        GKScore.report([bestScoreInt]) { (error) in
            if error != nil {
                print(error!.localizedDescription)
            } else {
                print("Best Score submitted to the leaderboard!")
            }
        }
    }
    func reportAchievements() {
        print(achievements)
        guard gcEnabled else {
            print("Game Center Not Enabled")
            return
        }
        GKAchievement.report(achievements) {
            error in guard error == nil else {
                print("""
                    
                    GKAchievement Error:
                    \(error as Any)
                     
                    """)
                return
            }
        }
    }
    var gcAchievements:[String:GKAchievement]? = nil
    func loadAchievements() {
        var allAchievements = [GKAchievement]()
        GKAchievement.loadAchievements(completionHandler: { (allAchievements, error: Error?) -> Void in
            if error != nil {
                print("Game Center: could not load achievements, error: \(String(describing: error))")
            } else {
                for anAchievement in allAchievements!  {
                    if let oneAchievement = anAchievement as? GKAchievement {
                        self.gcAchievements?[oneAchievement.identifier] = oneAchievement
                    }
                }
            }
        })
    }

This is called from elsewhere in GameScene.swift as:

achievements = []
achievements.append(AchievementName)
print(achievements)
print(AchievementName.isCompleted)
if A_leaveNosund.percentComplete == 0 {
     print("Rewarding for achievement completion...")
     A_leaveNosund.percentComplete = 100
     reportAchievements()
     addPoints(pts: 1)
}

(AchievementName represents my achievement's name, and is declared in the same class, earlier in the file).


Does anyone know what needs to be modified to make achievements load and get marked as completed in Swift 5?

Any help would be appreciated.

Thanks,

ajldev

Replies

Update:

The problem seems to be that achievements do not report properly. They are recognized as being completed, but they don't save to Game Center.


All the code except for the reportAchievements function seems to work properly. I changed some parts of the function to make debugging easier, I do not believe that that has changed anything. The achievements claim to have reported, as

One achievement recognized. (report)

gets printed off when the achievement is achieved.


func reportAchievements() {

        print(achievements)

        guard gcEnabled else {

            print("Game Center Not Enabled")

            return

        }

        GKAchievement.report(achievements, withCompletionHandler: { (error: Error!) -> Void in

                if error != nil {

                    print("Game Center: could not report achievements, error: \(String(describing: error))")

                } else {

                    for _ in self.achievements {

                        print("One achievement recognized. (report)")

                    }

                }

            })

    }


I can't seem to find a problem in my code. Is this a bug in Game Center, or if not, does anyone know where my mistake is?

I would appreciate any help with this issue.

Thanks,

ajldev

Update:

The error does not seem to be in the code. I have successfully built other working projects, and they've had the same issue with achievements when I run them. Could it be an issue with my developer ID or TestFlight?

Thanks for your report ajldev. It's hard for us to diagnose an issue such as this with only a snippet of code.

Are you able to make a report via feedback assistant ( https://developer.apple.com/bug-reporting/ ) and attach a sample project which demonstrates the issue?

If not we have lab sessions running this week and you could schedule a 1:1 appointment. More information is here: https://developer.apple.com/news/?id=hmgl2i3w 

Facing the same issue in 2022, and the fact that Apple hasn't done anything to fix this is disappointing.