Ich benutze LibGDX mit RoboPods unter Android Studio für iOS kompilieren. Nachdem ich von RoboVM zu mobideveloped migriert habe, stehe ich nun vor einigen Problemen. Der wichtigste ist, dass ich mich nicht bei Google anmelden kann.libgdx iOS mit Android Studio mit MobiDevelop/robovm-robopods anmelden "keychain error"
bekomme ich folgende Fehlermeldung:
[GPGManager signIn:didSignInForUser:withError:]:[main] FAILED LOGGING INTO GOOGLE PLUS GAMES Error Domain=com.google.GIDSignIn Code=-2 "keychain error" UserInfo={NSLocalizedDescription=keychain error}
Xcode Version 8.2 Android Studio Ich bin mit Version 4.0.0 von Google Log-in SDK für iOS https://developers.google.com/identity/sign-in/ios/sdk/
Ich verstehe, dass Sie ändern können Ihr KeyChain-Parameter in XCode, aber da dies ein LibGDX-Spiel ist, verwende ich keinen XCode.
Ein Projekt Probt das Problem darstellt, ist auf githiub hier: https://github.com/julienvillegas/LibGDX-Google-Play-Game-Services-Integration-Sample
Mein Code ist wie folgt:
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.backends.iosrobovm.IOSApplication;
import com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration;
import com.julienvillegas.CrosswordParty.CrosswordParty;
import com.julienvillegas.CrosswordParty.NearbyGPGSPlayers;
import com.julienvillegas.GameWorld.CrosswordCommon.CrosswordGiftCreate.GiftGridCombinations;
import com.julienvillegas.GameWorld.Global;
import com.julienvillegas.actionResolver.ActionResolver;
import org.robovm.apple.foundation.Foundation;
import org.robovm.apple.foundation.NSArray;
import org.robovm.apple.foundation.NSAutoreleasePool;
import org.robovm.apple.foundation.NSError;
import org.robovm.apple.foundation.NSObject;
import org.robovm.apple.foundation.NSString;
import org.robovm.apple.foundation.NSURL;
import org.robovm.apple.uikit.UIActivityViewController;
import org.robovm.apple.uikit.UIApplication;
import org.robovm.apple.uikit.UIApplicationLaunchOptions;
import org.robovm.apple.uikit.UIViewController;
import org.robovm.objc.block.VoidBlock4;
import org.robovm.pods.google.games.GPGAchievement;
import org.robovm.pods.google.games.GPGAchievementUnlockCallback;
import org.robovm.pods.google.games.GPGLauncherController;
import org.robovm.pods.google.games.GPGLeaderboard;
import org.robovm.pods.google.games.GPGLeaderboardLoadScoresCallback;
import org.robovm.pods.google.games.GPGLeaderboardTimeScope;
import org.robovm.pods.google.games.GPGManager;
import org.robovm.pods.google.games.GPGPlayer;
import org.robovm.pods.google.games.GPGPlayerGetCallback;
import org.robovm.pods.google.games.GPGScore;
import org.robovm.pods.google.games.GPGScoreReport;
import org.robovm.pods.google.games.GPGScoreReportCallback;
import org.robovm.pods.google.games.GPGStatusDelegate;
import org.robovm.pods.google.mobileads.GADInterstitial;
import org.robovm.pods.google.mobileads.GADInterstitialDelegateAdapter;
import org.robovm.pods.google.mobileads.GADMobileAds;
import org.robovm.pods.google.mobileads.GADRequest;
import org.robovm.pods.google.mobileads.GADRequestError;
import org.robovm.pods.google.signin.GIDSignIn;
import org.robovm.pods.google.signin.GIDSignInUIDelegateAdapter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class IOSLauncher extends IOSApplication.Delegate implements ActionResolver,GPGStatusDelegate {
private static NearbyGPGSPlayers nearbyGPGSPlayers;
public static final String CLIENT_ID_FREE = "xxxx.yy.z1";
public static final String CLIENT_ID_NOADS = "xxxx.yy.z2";
public static String CLIENT_ID = "";
private IOSApplication app;
static public GADInterstitial interstitial;
static private GPGPlayer gpgplayer;
private Screen postAdScreen;
GADRequest request;
IOSApplication local_app;
@Override
protected IOSApplication createApplication() {
System.out.println("IOSLauncher:createApplication:start");
if(Global.FREE_EDITION){
CLIENT_ID = CLIENT_ID_FREE;
}
else{
CLIENT_ID = CLIENT_ID_NOADS;
}
System.out.println("IOSLauncher:createApplication:Step1");
IOSApplicationConfiguration config = new IOSApplicationConfiguration();
System.out.println("IOSLauncher:createApplication:Step2");
app = new IOSApplication(CrosswordParty.getInstance(this), config);
local_app = app;
System.out.println("IOSLauncher:createApplication:configuring ads");
GADMobileAds.disableSDKCrashReporting();
createRequest();
interstitial = createAndLoadInterstitial();
System.out.println("IOSLauncher:createApplication:end");
GIDSignIn.getSharedInstance().setUiDelegate(new GIDSignInUIDelegateAdapter() {
private UIViewController libgdxViewController;
@Override
public void willDispatch(GIDSignIn signIn, NSError error) {
Foundation.log("willDispatch()");
}
@Override
public void presentViewController(GIDSignIn signIn, UIViewController viewController) {
Foundation.log("presentViewController()");
libgdxViewController = UIApplication.getSharedApplication().getKeyWindow().getRootViewController();
// .presentViewController(viewController, true, null);
UIApplication.getSharedApplication().getKeyWindow().setRootViewController(viewController);
}
@Override
public void dismissViewController(GIDSignIn signIn, UIViewController viewController) {
Foundation.log("dismissViewController()");
//viewController.dismissViewController(true, null);
UIApplication.getSharedApplication().getKeyWindow().setRootViewController(libgdxViewController);
}
});
return app;
}
public static void main(String[] argv) {
System.out.println("IOSLauncher:main:start");
NSAutoreleasePool pool = new NSAutoreleasePool();
UIApplication.main(argv, null, IOSLauncher.class);
pool.close();
System.out.println("IOSLauncher:main:end");
}
@Override
public boolean didFinishLaunching(UIApplication application, UIApplicationLaunchOptions launchOptions) {
super.didFinishLaunching(application, launchOptions);
Foundation.log("IOSLauncher didFinishLaunching()");
// GIDSignIn.getSharedInstance().setAllowsSignInWithWebView(true);
GPGManager.getSharedInstance().signIn(CLIENT_ID, true);
return true;
}
private GADInterstitial createAndLoadInterstitial() {
System.out.println("IOSLauncher:createAndLoadInterstitial:here");
if(Global.DEV_MODE){
//interstitial = new GADInterstitial(GGLContextMobileAds.getSharedInstance().getAdUnitIDForInterstitialTest());
interstitial = new GADInterstitial("xxxxx");
}
else{
//interstitial = new GADInterstitial(GGLContextMobileAds.getSharedInstance().getConfiguration().getInterstitialAdUnitID());
interstitial = new GADInterstitial("yyyyy");
}
interstitial.setDelegate(new GADInterstitialDelegateAdapter() {
@Override
public void didReceiveAd(GADInterstitial ad) {
System.out.println("IOSLauncher:createAndLoadInterstitial:received ad.");
}
@Override
public void didDismissScreen(GADInterstitial ad) {
System.out.println("IOSLauncher:createAndLoadInterstitial:closed ad");
CrosswordParty.getInstance().setScreen(postAdScreen);
}
@Override
public void didFailToReceiveAd(GADInterstitial ad, GADRequestError error) {
System.out.println("IOSLauncher:createAndLoadInterstitial:error" + error.description());
System.out.println("IOSLauncher:createAndLoadInterstitial:error" + error.getErrorCode());
}
});
interstitial.loadRequest(request);
return interstitial;
}
private GADRequest createRequest() {
System.out.println("IOSLauncher:createRequest:here");
request = new GADRequest();
// To test on your devices, add their UDIDs here:
request.setTestDevices(Arrays.asList(GADRequest.getSimulatorID()));
return request;
}
@Override
public void showOrLoadInterstital(Screen aScreen) {
System.out.println("IOSLauncher:showOrLoadInterstital:here");
if(postAdScreen == null){
postAdScreen = CrosswordParty.crosswordScreen;
}
if (postAdScreen.getClass() == CrosswordParty.crosswordScreen.getClass()) {
postAdScreen = CrosswordParty.scrableScreen;
} else {
postAdScreen = CrosswordParty.crosswordScreen;
}
if (interstitial.isReady()) {
System.out.println("IOSLauncher:showOrLoadInterstital:showing add!");
UIViewController viewController = UIApplication.getSharedApplication().getKeyWindow().getRootViewController();
interstitial.present(viewController);
//interstitial.present(app.getUIViewController());
} else {
System.out.println("IOSLauncher:showOrLoadInterstital:Interstitial not ready!");
CrosswordParty.getInstance().setScreen(postAdScreen);
}
createAndLoadInterstitial();
}
@Override
public boolean getSignedInGPGS() {
System.out.println("IOSLauncher:getSignedInGPGS:is Signed in? " + GPGManager.getSharedInstance().isSignedIn());
return GPGManager.getSharedInstance().isSignedIn();
}
@Override
public void loginGPGSSilently() {
System.out.println("IOSLauncher:loginGPGSSilently:Start");
if(!getSignedInGPGS()){
try {
GPGManager.getSharedInstance().signIn(CLIENT_ID, true);
GPGManager.getSharedInstance().setStatusDelegate(this);
} catch (final Exception ex) {
}
};
}
@Override
public void loginGPGS() {
System.out.println("IOSLauncher:loginGPGS:Start");
if(!getSignedInGPGS()){
try {
GPGManager.getSharedInstance().signIn(CLIENT_ID, false);
GPGManager.getSharedInstance().setStatusDelegate(this);
} catch (final Exception ex) {
}
};
}
@Override
public String getGPGSName() {
if (GPGManager.getSharedInstance().isSignedIn()) {
return gpgplayer.getDisplayName();
} else{
loginGPGS();
return null;
}
}
@Override
public void submitScoreGPGS(int score) {
System.out.println("IOSLauncher:submitScoreGPGS:here");
GPGScore gpgScore = new GPGScore(Global.LEADERBOARD_SCORE);
gpgScore.setValue(score);
GPGScoreReportCallback gpgscoreReportCallback = new GPGScoreReportCallback(){
@Override
public void done(GPGScoreReport report, NSError error) {
if (error != null) {
System.out.println("IOSLauncher:submitScoreGPGS:Error");
}
else{
System.out.println("IOSLauncher:submitScoreGPGS:Done");
}
}
};
gpgScore.submitScore(gpgscoreReportCallback);
}
@Override
public void submitStarChallengeScoreGPGS(int starChallenge) {
System.out.println("IOSLauncher:submitStarChallengeScoreGPGS:here");
GPGScore gpgScore = new GPGScore(Global.LEADERBOARD_STARSTREAK);
gpgScore.setValue(starChallenge);
GPGScoreReportCallback gpgscoreReportCallback = new GPGScoreReportCallback(){
@Override
public void done(GPGScoreReport report, NSError error) {
if (error != null) {
System.out.println("IOSLauncher:submitScoreGPGS:Error");
}
else{
System.out.println("IOSLauncher:submitScoreGPGS:Done");
}
}
};
gpgScore.submitScore(gpgscoreReportCallback);
}
@Override
public void submitCrosswordChallengeScoreGPGS(int crosswordChallenge) {
System.out.println("IOSLauncher:submitCrosswordChallengeScoreGPGS:here");
GPGScore gpgScore = new GPGScore(Global.LEADERBOARD_COMBOS);
gpgScore.setValue(crosswordChallenge);
GPGScoreReportCallback gpgscoreReportCallback = new GPGScoreReportCallback(){
@Override
public void done(GPGScoreReport report, NSError error) {
if (error != null) {
System.out.println("IOSLauncher:submitScoreGPGS:Error");
}
else{
System.out.println("IOSLauncher:submitScoreGPGS:Done");
}
}
};
gpgScore.submitScore(gpgscoreReportCallback);
}
@Override
public void unlockAchievementGPGS(String achievementId) {
System.out.println("IOSLauncher:unlockAchievementGPGS:here");
GPGAchievement gpgachievement = new GPGAchievement(achievementId);
GPGAchievementUnlockCallback gpgachievementUnlockCallback = new GPGAchievementUnlockCallback() {
@Override
public void done(boolean newlyUnlocked, NSError error) {
if (error != null) {
System.out.println("IOSLauncher:unlockAchievementGPGS:Error while unlocking!");
} else {
System.out.println("IOSLauncher:unlockAchievementGPGS:unlock succeeded. newlyUnlocked: " + newlyUnlocked);
}
}
};
gpgachievement.unlock(gpgachievementUnlockCallback);
}
@Override
public void getAllLeaderboardsGPGS() {
System.out.println("IOSLauncher:getAllLeaderboardsGPGS:here");
boolean isSignedInFlag = GPGManager.getSharedInstance().isSignedIn();
System.out.println("IOSLauncher:loginGPGS:is signed in?" + isSignedInFlag);
if (GPGManager.getSharedInstance().isSignedIn()) {
GPGLauncherController.getSharedInstance().presentLeaderboardList();
} else {
loginGPGS();
}
}
@Override
public void getLeaderboardScoreGPGS() {
System.out.println("IOSLauncher:getLeaderboardScoreGPGS:here");
if (GPGManager.getSharedInstance().isSignedIn()) {
GPGLauncherController.getSharedInstance().presentLeaderboard(Global.LEADERBOARD_SCORE);
} else{
loginGPGS();
// loginGPGS();
}
}
@Override
public void getLeaderboardStarChallengeGPGS() {
System.out.println("IOSLauncher:getLeaderboardStarChallengeGPGS:here");
if (GPGManager.getSharedInstance().isSignedIn()) {
GPGLauncherController.getSharedInstance().presentLeaderboard(Global.LEADERBOARD_STARSTREAK);
} else{
loginGPGS();
}
}
@Override
public void getLeaderboardCrosswordChallengeGPGS() {
System.out.println("IOSLauncher:getLeaderboardCrosswordChallengeGPGS:here");
if (GPGManager.getSharedInstance().isSignedIn()) {
GPGLauncherController.getSharedInstance().presentLeaderboard(Global.LEADERBOARD_COMBOS);
} else{
loginGPGS();
}
}
@Override
public void getAchievementsGPGS() {
System.out.println("IOSLauncher:getAchievementsGPGS:here");
if (GPGManager.getSharedInstance().isSignedIn()) {
GPGLauncherController.getSharedInstance().presentAchievementList();
} else{
loginGPGS();
}
}
@Override
public void getNearbyPlayers() {
System.out.println("IOSLauncher:getNearbyPlayers:here");
if (GPGManager.getSharedInstance().isSignedIn()) {
GPGLeaderboard gpgleaderboard = GPGLeaderboard.getLeaderboard(Global.LEADERBOARD_SCORE);
gpgleaderboard.setSocial(true);
gpgleaderboard.setPersonalWindow(true);
gpgleaderboard.setTimeScope(GPGLeaderboardTimeScope.AllTime);
GPGLeaderboardLoadScoresCallback gpgleaderboardLoadScoresCallback = new GPGLeaderboardLoadScoresCallback() {
@Override
public void done(NSArray<GPGScore> scores, NSError error) {
nearbyGPGSPlayers = new NearbyGPGSPlayers(gpgplayer.getPlayerId());
for(int i = 0;i< scores.size();i++){
GPGScore aScore = scores.get(i);
GPGPlayer aScorePlayer = aScore.getPlayer();
System.out.println("IOSLauncher:getNearbyPlayers:Player:" + aScorePlayer.getDisplayName() + "Score:" + aScore.getValue());
nearbyGPGSPlayers.addPlayer(aScorePlayer.getPlayerId(), aScorePlayer.getDisplayName(),aScore.getValue(),aScore.getFormattedRank());
}
nearbyGPGSPlayers.notify_Player();
}
};
gpgleaderboard.loadScores(gpgleaderboardLoadScoresCallback);
}
else{
loginGPGS();
}
}
@Override
public void sendGiftGrid(String textToShare, String subject, String URL) {
NSArray<NSObject> items = new NSArray<>(
new NSString(textToShare),
new NSURL(URL));
UIViewController viewController = UIApplication.getSharedApplication().getKeyWindow().getRootViewController();
UIActivityViewController uiActivityViewController = new UIActivityViewController(items, null);
uiActivityViewController.setCompletionWithItemsHandler(new VoidBlock4<String, Boolean, NSArray<NSObject>, NSError>() {
@Override
public void invoke(String s, Boolean aBoolean, NSArray<NSObject> nsObjects, NSError nsError) {
GiftGridCombinations.getInstance().getSelectedCombination().setShared(true);
}
});
/* ((IOSApplication) Gdx.app).getUIViewController().presentViewController(uiActivityViewController, true, null);
*/
viewController.presentViewController(uiActivityViewController, true, null);
}
@Override
public void didFinishGamesSignIn(NSError error) {
System.out.println("IOSLauncher:didFinishGamesSignIn:here");
GPGPlayerGetCallback gpgplayerGetCallback = new GPGPlayerGetCallback(){
@Override
public void done(GPGPlayer player, NSError error) {
gpgplayer = player;
System.out.println("IOSLauncher:didFinishGamesSignIn:name:"+gpgplayer.getDisplayName()+":id:"+gpgplayer.getPlayerId());
getNearbyPlayers();
}
};
GPGPlayer.getLocalPlayer(gpgplayerGetCallback);
}
@Override
public void didFinishGamesSignOut(NSError error) {
System.out.println("IOSLauncher:didFinishGamesSignOut:here");
}
@Override
public void didFinishGoogleAuth(NSError error) {
System.out.println("IOSLauncher:didFinishGoogleAuth:here");
}
@Override
public boolean shouldReauthenticate(NSError error) {
System.out.println("IOSLauncher:shouldReauthenticate:here");
return false;
}
@Override
public void willReauthenticate(NSError error) {
System.out.println("IOSLauncher:willReauthenticate:here");
}
/*
@Override
public void finished(GTMOAuth2Authentication auth, NSError error) {
System.out.println("IOSLauncher:finished:here");
}
*/
@Override
public void didDisconnect(NSError error) {
System.out.println("IOSLauncher:didDisconnect:here");
}
/*
@Override
public boolean openURL(UIApplication application, NSURL url, String sourceApplication, NSPropertyList annotation) {
System.out.println("IOSLauncher:openURL:here");
boolean canRespond = GIDSignIn.getSharedInstance().handleURL(url, sourceApplication, annotation);
if (canRespond) {
return true;
} else {
// There might be other things you'd want to do here
return false;
}
}
*/
@Override
public String getDateAsString(Date aDate, String format) {
SimpleDateFormat SimpleDateFormat = new SimpleDateFormat(format) ;
//DateTimeFormat dateFormat = DateTimeFormat.getFormat("yyyyMMddHHmmssS");
TimeZone timeZone = TimeZone.getTimeZone("UTC");
SimpleDateFormat.setTimeZone(timeZone);
Calendar cal = Calendar.getInstance(timeZone);
cal.setTime(aDate);
return SimpleDateFormat.format(cal.getTime()).trim();
}
@Override
public Date getStringAsDate(String aDate, String format) {
SimpleDateFormat SimpleDateFormat = new SimpleDateFormat(format) ;
TimeZone timeZone = TimeZone.getTimeZone("UTC");
SimpleDateFormat.setTimeZone(timeZone);
try {
Date date = SimpleDateFormat.parse(aDate);
return date;
}
catch(Exception e){
return null;
}
}
@Override
public void runInBackground(Runnable toBeRun) {
new Thread(toBeRun).start();
}
}
Ich verwende keinen XCode. Dies ist ein LibGDX-Spiel (Java), das mit Android Studio erstellt wurde. Dieses Problem tritt mit dem Simulator auf, sodass ich das Telefon nicht trennen kann. Ich nehme an, es könnte eine Arbeit geben, wenn es eine Möglichkeit gibt, Zielkompatibilitäten direkt in der Konfigurationsdatei hinzuzufügen? – Julien
Es gibt ein ähnliches Problem mit Benutzern auf Xamarin (http://stackoverflow.com/questions/39487368/xamarin-auth-store-keychain-not-working-after-ios10-upgrade/39576798#39576798). Es muss eine andere Lösung geben, als auf eine neue Version zu warten, um das Teilen von Schlüsselbunden mit LibGDX zu ermöglichen. – Julien
XCode 8.2 kam heraus. Das Problem besteht weiter. – Julien