android
android copied to clipboard
Many issues using Kotlin library from plugin
Environment
Provide version numbers for the following components (information can be retrieved by running tns info
in your project folder or by inspecting the package.json
of the project):
- CLI: 6.5.0
- Cross-platform modules: 6.5.1
- Android Runtime: 6.5.0
- iOS Runtime (if applicable): N/A
- Plugin(s): nativescript-stripe
Describe the bug
I am a primary contributor for the nativescript-stripe plugin and am attempting to upgrade it to the latest Stripe Android SDK. When Stripe updated their Android SDK from v12 to v13 they switched from Java to Kotlin. Code in my plugin that used to run without problem on the Java version now fails on the Kotlin version. This report provides the information I've been able to learn on the problems. I have checked my code that exhibits these problems into the nativescript-stripe repository in a branch named update-android-13-bugs
. The files referenced below are in that branch. (I would be ecstatic to learn there's a configuration or versioning problem in my plugin that is responsible for these issues!)
-
When Kotlin fields are annotated with
@JvmField
or@get:
they are not available in NS at runtime. Accessing those fields reports the error:Missing getter method for property
. I have found that the fields are exposed with the namecomponentN()
, where N is the integer sequence the fields are declared in the Kotlin file. See, for example,src/stripe.android.ts
line 430 where I have modified the code to retrieve those fields using thecomponent
methods. -
When a method is annotated with
@JvmStatic
, the first time it is called it reports an error:You are trying to set "Companion" which is a final field! Final fields can only be read.
The app does not crash (in my case) and if I try executing it again, it succeeds. An example of this is the call toSourceParams.createCardParams()
atsrc/stripe.android.ts
line 70. -
When I implement a Kotlin interface (using the "anonymous Java class" technique described in the NS docs), I get the following error when the SDK attempts to use it:
com.tns.NativeScriptException: Cannot find runtime for instance=com.tns.gen.com.stripe.android.PaymentSessionConfig_ShippingInformationValidator@2f3779c
at com.tns.Runtime.callJSMethod(Runtime.java:1157)
You can see the code where I create the implementation at src/standard/standard.android.ts
line 154.
dts-generator
problems:
I use the [dts-generator](https://docs.nativescript.org/core-concepts/android-runtime/metadata/generating-typescript-declarations)
to generate typings from the Stripe Android SDK. I have run into the following problems with the typings generated from Kotlin source files. I can generally fix them, but it's quite a pain.
-
Kotlin elements marked
internal
are generated in the .d.ts file. They shouldn't be. They often cause typescript errors since they frequently use internal-only types. -
If a class is marked
@Parcelize
the generator creates a static field named CREATOR. It is of typeglobalAndroid.os.Parcelable.Creator
and does not include its generic type even thoughParcelable.Creator
is a typed class. It can be fixed by copying the generic type from thestatic class
field. -
Kotlin classes with companions are generated as follows:
class Foo {
static Companion: Foo.Companion;
export module Foo {
export class Companion {
public static class: java.lang.Class<Foo.Companion>;
}
}
}
This, of course, results in a Duplicate identifier 'Companion'
typescript error. I have found I can resolve this by changing the Companion class name from Companion
to companion
. (You can see an example of this in java!Stripe.d.ts
line 2001.) This is an ugly solution but since the class name does not show up in the generated JS code, it works. I can then call the method using Foo.Companion.method()
. An example of where I successfully call such a method is the call to fromCode
at src/standard/standard.android.ts
line 233. (Note that this method, since it was just introduced in the v13 SDK, is a pure Kotlin method, so it is not annotated with @JvmStatic
. The createCardParams
method mentioned above, however, exists in earlier versions, so it was annotated with @JvmStatic
. The call to fromCode
has no problem, while the call to createCardParams
exhibits the behavior mentioned above.)
+1
+1
Does anyone know whether this has been fixed in a later version of NS? (we're still on 6)
I'm facing similar issue, any update?
@AdrianoOP can you try the @alpha
version of the runtime an lmk , thanks.
@triniwiz unfortunately it didn't work, same error. In my case the error is more related to this log message:
JS: ERROR Error: java.lang.Exception: Failed resolving constructor for class 'com.stripe.android.model.CardParams' with 4 parameters. Check the number and type of arguments. JS: Primitive types need to be manually wrapped in their respective Object wrappers. JS: If you are creating an instance of an inner class, make sure to always provide reference to the outer
this
as the first argument.
Interesting , please share which version of the lib are you trying this with because this works fine for me here
Yes... This is exactly where it fails... Do you have the snipet of code where you are creating CardParams?
Mine is:
const cardSession = this.sessionInfoService.getUserSession().creditCard; const card: CardParams = new CardParams( cardSession.cardNumber as string, cardSession.expirationMonth as number, cardSession.expirationYear as number, cardSession.cvc as string );
relevant packages installed:
"@nativescript/android": "8.1.1", "@nativescript/ios": "8.1.0", "@nativescript/types": "~8.1.1", "@nativescript/webpack": "~5.0.0", "@typescript-eslint/parser": "5.3.0", "typescript": "~4.3.5"
"@nativescript/angular": "^12.2.0", "@nativescript/core": "~8.1.1", "@nativescript/firebase": "^11.1.3", "@triniwiz/nativescript-stripe": "^7.0.1",