NSInvalidArgumentException trying to use Game Center

I’m using Multi-OS Engine with LibGDX, and so far it seems to work fine with my game code, but when i’m trying to implement Game Center on it it throws this error when trying to update a leaderboard score:

2017-03-02 10:42:12.788 ios-moe[1814:276290] -[GKScore setValue:]: unrecognized selector sent to instance 0x17e32100
2017-03-02 10:42:12.834 ios-moe[1814:276290] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GKScore setValue:]: unrecognized selector sent to instance 0x17e32100'
*** First throw call stack:
(0x250e391b 0x2487ee17 0x250e92b5 0x250e6ee1 0x25012238 0x3b4901c 0x3b4b2d5 0x3b4427f 0x3b441af 0x3b4191f 0x3b4b619 0x3b490a4)
libc++abi.dylib: terminating with uncaught exception of type NSException

Here’s the method that reports the score:

public void reportScore (String identifier, long score) {
        // If player is not authenticated, do nothing
        if (!GKLocalPlayer.localPlayer().isAuthenticated()) {
            listener.scoreReportFailed(buildUnauthenticatedPlayerError());
            return;
        }

        GKScore scoreReporter = GKScore.alloc();
        NSNumber scoreNumber = NSNumber.numberWithLong(score);
        scoreReporter.setValue(scoreNumber.longValue());

        // If iOS version is 7 or more we use the new method
        if (getIosVersion() >= IOS_7) {
            scoreReporter.setLeaderboardIdentifier(identifier);
            NSArray<GKScore> scores = (NSArray<GKScore>) NSArray.alloc();
            scores.add(scoreReporter);

            GKScore.reportScoresWithCompletionHandler(scores, new GKScore.Block_reportScoresWithCompletionHandler() {
                @Override
                public void call_reportScoresWithCompletionHandler(NSError error) {
                    if (error != null) {
                        listener.scoreReportFailed(error);
                    } else {
                        listener.scoreReportCompleted();
                    }
                }
            });
        }
    }

So, i think the problem is in the GKScore class in MOE. Here’s my current configuration:

  • libGDX version: 1.9.5
  • MOE version: 1.2.5
  • Xcode version: 8.2.1
  • Android Studio version: 2.2.3

Dear Andres,

could you please test your app with MOE 1.3.0-beta-2 and LibGDX 1.9.6-SNAPSHOT? I recall that there were a few Game Center related fixes that went into MOE 1.3 / GDX 1.9.6 but not in MOE 1.2 / GDX 1.9.5.

Best Regards,
Gergely

Thanks for the response. I updated LibGDX to 1.9.6-SNAPSHOT and MOE to 1.3.0-beta-2, but the error still occurs, although it shows a shortened error trace:

2017-03-02 16:14:04.821 ios-moe[3515:352240] -[GKScore setValue:]: unrecognized selector sent to instance 0x176013f0

Regards.

Which version of iOS are you using? MOE is currently only tested with iOS 9 or later.

I’m testing with an Ipod Touch using iOS version 9.3.5

Could you provide a test project for us that reproduces the problem? This would make it easier for us to reproduce and possibly fix the issue.

Best Regards,
Gergely

I created a blank LibGDX project from scratch and added the minimum steps to report a score and the problem still occurs.

I’m attaching the IOSMoeLauncher class that contains the codeIOSMoeLauncher.java.zip (1.0 KB)

The login process seems to be doing OK but then it crashes the moment i set the value to the GKScore.

Regards.

Hi!

This code is working for me:

GKLocalPlayer.localPlayer().setAuthenticateHandler(new GKLocalPlayer.Block_setAuthenticateHandler() {
            @Override
            public void call_setAuthenticateHandler(UIViewController viewController, NSError error) {
                if (viewController != null) {
                    UIApplication.sharedApplication().keyWindow().rootViewController().presentViewControllerAnimatedCompletion(viewController, true, null);
                }
                // If the viewController is null and the player is authenticated, the login is completed
                else if (GKLocalPlayer.localPlayer().isAuthenticated()) {
                    GKLocalPlayer.localPlayer().generateIdentityVerificationSignatureWithCompletionHandler(new GKLocalPlayer.Block_generateIdentityVerificationSignatureWithCompletionHandler() {
                        @Override
                        public void call_generateIdentityVerificationSignatureWithCompletionHandler(NSURL arg0, NSData arg1, NSData arg2, long arg3, NSError arg4) {
                            System.out.println("#####login successful :)");
                            GKScore scoreReporter = GKScore.alloc().initWithLeaderboardIdentifier("leaderboard_puzzlerama_player_level");
                            scoreReporter.setValue(45);
                            NSArray<GKScore> scores = (NSArray<GKScore>) NSArray.arrayWithObject(scoreReporter);
                            GKScore.reportScoresWithCompletionHandler(scores, new GKScore.Block_reportScoresWithCompletionHandler() {
                                @Override
                                public void call_reportScoresWithCompletionHandler(NSError error) {
                                    if (error != null) {
                                        System.out.println("#####score report error :'( " + error.localizedDescription());
                                    } else {
                                        System.out.println("#####score report successful :)");
                                    }
                                }
                            });
                        }
                    });
                }
            }
        });

Best Regards,
Roland

Hello.

You mean it´s working for you?

Then, the problem could be on some of my configurations?

Regards.

The differences are:

  • You did not initialize the GKScore correctly, need to call init* as well:
 GKScore scoreReporter = GKScore.alloc().initWithLeaderboardIdentifier("leaderboard_puzzlerama_player_level");
                            scoreReporter.setValue(45);
  • You did not initialize the NSArray correctly, need to call a factory method:
NSArray<GKScore> scores = (NSArray<GKScore>) NSArray.arrayWithObject(scoreReporter);

That worked!

Thank you so much, i didn’t saw that differences.

Regards.