libgdx / gdx-pay

A libGDX cross-platform API for InApp purchasing.
Apache License 2.0
224 stars 83 forks source link

iOS: SKPayment <init> NoSuchMethodError, problem with create() method? #86

Closed MrPat closed 8 years ago

MrPat commented 8 years ago

This is my first time raising an issue on GitHub, so bear with me. I implemented Gdx-Pay in my libgdx project and had everything working great. I published an update to my app and the Android version works, but the published iOS app doesn't work (just the IAP I mean, the app works fine). The weird thing is that it works just fine if I install directly from Eclipse to my iPhone, and I can make purchases via the Sandbox and Restore Purchases too. When I publish to the App Store or via Ad Hoc the functionality breaks. I have mechanisms in place to alert the user to any problems with the IAP but none of these are triggered. The IAP thread just seems to hang.

I should point out that Apple has approved the latest version of my app and they approved my 'Remove Ads' IAP, and that was 8 days ago so the wait period should have been up by now. I can even retrieve the correct name of the IAP from Apple's server, so they definitely have it out there. It just won't show any visible response when the Remove Ads button is clicked now. It doesn't even prompt the user to sign in with their Apple ID.

I've been working on this problem for days now with no luck. I think I have managed to pin it down to the PurchaseManageriOSApple class at line 173 which is:

SKPayment payment = new SKPayment(product);

Since the IAP all works when I use the debugger, I have to use Ad Hoc publishing to simulate how the app would perform straight from the App Store. Unfortunately this means that the stack traces for exceptions don't print out most of the time, but I have managed to snag the following stack trace of the issue:

java.lang.NoSuchMethodError: org.robovm.apple.storekit.SKPayment.<init>(Lorg/robovm/apple/storekit/SKProduct;)V at com.badlogic.gdx.pay.ios.apple.PurchaseManageriOSApple.purchase(PurchaseManageriOSApple.java:173) at com.example.myapp.IAPHelper.purchase(IAPHelper.java:330) at com.example.myapp.MainApp$70.run(MainApp.java:3427)

The IAPHelper is one of my own classes, and I changed the app name for this snippet but the structure of the error is still the same. This led me to think that something was wrong with the SKPayment class, so I downloaded it and copied it into my project to check it out. I saw that the constructor from the stack trace was:

public SKPayment(SKProduct product) { super(create(product)); retain(getHandle()); }

The super constructor was flagged as being deprecated, so I extended SKPayment with a new class that included a method that would call create(product) directly, and I changed the PurchaseManager code to use this new class. That way I could use the default empty constructor and still be able to call the create method. I ran the code and this time I got a NoSuchMethodError that referred to the create(SKProduct product) method. I didn't save the stack trace for that one, but from what I can tell, something is wrong with the create method in the SKPayment class.

Bear in mind that I followed all the setup instructions regarding force-linking the purchase manager and adding all the .jar files. I'm using the 0.9.0-SNAPSHOT versions of the gdx-pay jars and the latest version of RoboVM (1.12.0). My gradle plugins are also the latest ones. The only thing that's not the latest version is my Libgdx which is version 1.8.0, but I can't see that interfering with native iOS code. I was originally on lower versions of everything except gdx-pay 0.9.0-SNAPSHOT, and I still had this issue. I've verified the problem for both iOS 7 and the latest iOS 9.2.1, and I suspect it's not just those versions that have the issue.

And just to be clear all the iOS functionality is flawless when testing straight to my phone, but something about the publishing process breaks it. I've had a similar problem before with a NSURL constructor that was deprecated. It worked just fine in testing but broke after publishing, so I'm thinking this must have a similar cause.

Anyway I would love to get help from anyone because I've tried everything I know to do and half the things I don't know to do. It really seems like a glitch at this point but I haven't been able to find any other people having problems like this recently so maybe it is something that I'm doing wrong. Let me know if I need to add anything else to clarify my problem. Thanks!

keesvandieren commented 8 years ago

Hi,

Does the issue occur in a TestFlight version?

If so, you can create a minimal project that reproduces the issue, and share it on Github.

MrPat commented 8 years ago

I haven't thought to try it in TestFlight, but I'll do that now. Then I'll upload a project if the issue is still there. Thanks!

MrPat commented 8 years ago

When I was making the minimal project, it worked with Ad Hoc publishing. So I realized something must be off about my app's project setup. After scouring over my project, I found that the problem was the Admob iOS bindings project that my app was referencing. For some reason that project had persisted Gradle dependencies for all of the RoboVM 1.0.0 jars! It also had the updated 1.12.0 jars so I removed the old 1.0.0 jars and built my app and it worked. So I guess the 1.0.0 jars from the referenced Admob bindings project were somehow confusing everything else in my main project that used RoboVM. That's probably why I had other similar problems with RoboVM NSURL's mentioned earlier.

Anyway, this doesn't look like an issue with Gdx-Pay, so is there a way to remove this issue post or am I just supposed to close it? Also, thanks so much for the help @keesvandieren ! Your suggestion is what led me to find the real problem with my setup.

keesvandieren commented 8 years ago

Great it has been resolved!

Maybe it would help to list the dependencies with Gradle tasks?

More here: https://docs.gradle.org/current/userguide/userguide_single.html#sec:listing_dependencies