Envoc / envoc-stripe-binding

Xamarin / Maui binding for Stripe SDK
MIT License
5 stars 2 forks source link

3.4 Bindings #6

Open chris-oswald opened 6 months ago

chris-oswald commented 6 months ago

@svaldetero do you have plans to implement the 3.4 bindings soon? They have taken away the required dependency on NFC, which was lowering my device count.

svaldetero commented 6 months ago

Thanks for bringing this to my attention. Its probably a good idea for me to keep them relatively up to date so I don't fall too far behind. My biggest pain point is having to manually do the android maven dependency chain. That's the section you see here: https://github.com/Envoc/envoc-stripe-binding/blob/bd6f695991046d264df125abb063df2bf3e80c3b/src/StripeTerminal/Envoc.Stripe.Terminal.Android/Envoc.Stripe.Terminal.Android.csproj#L112. I'll add it to my backlog and probably start working on it in the next few weeks.

chris-oswald commented 6 months ago

Here is my best stab for you. There is something weird going on with Dagger though since 2.50. I think it's related to them removing an obsolete tag on a method in DoubleCheck

        <TargetFramework>net8.0-android</TargetFramework>
        <SupportedOSPlatformVersion>26.0</SupportedOSPlatformVersion>
        <StripeVersion>3.4.0</StripeVersion>
        <KtorVersion>2.3.8</KtorVersion>

// removed some other sections for brevity....

 <ItemGroup>
     <PackageReference Include="XamPrototype.Android.MavenBinding.Tasks" Version="0.0.11" />

     <!-- Android nugets-->
     <PackageReference Include="Xamarin.Android.ReactiveX.RxAndroid" Version="2.1.1.5" JavaArtifact="io.reactivex.rxjava3:rxandroid" JavaVersion="3.0.2" />
     <PackageReference Include="Xamarin.Android.ReactiveX.RxJava3.RxJava" Version="3.1.8.3" />
     <PackageReference Include="Xamarin.AndroidX.Annotation" Version="1.7.1.1" />
     <PackageReference Include="Xamarin.AndroidX.ConstraintLayout" Version="2.1.4.10" />
     <PackageReference Include="Xamarin.AndroidX.Core.Core.Ktx" Version="1.12.0.4" />
     <PackageReference Include="Xamarin.AndroidX.DataBinding.ViewBinding" Version="8.2.2" />
     <PackageReference Include="Xamarin.AndroidX.Fragment.Ktx" Version="1.6.2" />
     <PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData.Ktx" Version="2.7.0.1" />
     <PackageReference Include="Xamarin.AndroidX.Lifecycle.Process" Version="2.7.0.1" />
     <PackageReference Include="Xamarin.AndroidX.Lifecycle.ViewModel.Ktx" Version="2.7.0.1" />
     <PackageReference Include="Xamarin.AndroidX.Room.Room.Ktx" Version="2.6.1" />
     <PackageReference Include="Xamarin.AndroidX.Room.Runtime" Version="2.6.1" />
     <PackageReference Include="Xamarin.AndroidX.Security.SecurityCrypto" Version="1.1.0-alpha03" />

     <!-- Google nugets-->
     <PackageReference Include="Xamarin.Google.Android.Play.Integrity" Version="1.1.0" JavaArtifact="com.google.android.play:integrity" JavaVersion="1.1.0" />
     <PackageReference Include="Xamarin.Google.Android.Material" Version="1.10.0.3" JavaArtifact="com.google.android.material:material" JavaVersion="1.11.0" />
     <PackageReference Include="Xamarin.Google.Code.FindBugs.JSR305" Version="3.0.2" JavaArtifact="com.google.code.findbugs:jsr305" JavaVersion="3.0.2" />
     <PackageReference Include="Xamarin.Google.Dagger" Version="2.48.1.1" JavaArtifact="com.google.dagger:dagger" JavaVersion="2.50.0" />
     <PackageReference Include="Xamarin.Google.ErrorProne.Annotations" Version="2.23.0.1" JavaArtifact="com.google.errorprone:error_prone_annotations" JavaVersion="2.23.0.1" />
     <PackageReference Include="Xamarin.Google.Guava.FailureAccess" Version="1.0.1" JavaArtifact="com.google.guava:failureaccess" JavaVersion="1.0.1" />
     <PackageReference Include="Xamarin.Google.Guava.ListenableFuture" Version="1.0.0.18" JavaArtifact="com.google.guava:listenablefuture" JavaVersion="9999.0-empty-to-avoid-conflict-with-guava" />
     <PackageReference Include="Xamarin.Google.J2Objc.Annotations " Version="2.8" JavaArtifact="com.google.j2objc:j2objc-annotations" JavaVersion="2.8" />
     <PackageReference Include="Xamarin.GooglePlayServices.SafetyNet" Version="118.0.1" />
     <PackageReference Include="Xamarin.CheckerFramework.CheckerQual" Version="3.33.0" JavaArtifact="org.checkerframework:checker-qual" JavaVersion="3.33.0" />
     <PackageReference Include="GoogleGson" Version="2.10.1" JavaArtifact="com.google.code.gson:gson" JavaVersion="2.10.1" />
     <!--<PackageReference Include="Xamarin.Google.Guava" Version="31.1.0.8" JavaArtifact="com.google.guava:guava" JavaVersion="31.1-android" />-->

     <!-- Kotlin nugets-->
     <PackageReference Include="Xamarin.Kotlin.StdLib" Version="1.9.22.1" JavaArtifact="org.jetbrains.kotlin:kotlin-stdlib" JavaVersion="1.9.22" />
     <PackageReference Include="Xamarin.Kotlin.StdLib.Common" Version="1.9.22.1" JavaArtifact="org.jetbrains.kotlin:kotlin-stdlib-common" JavaVersion="1.9.22" />
     <PackageReference Include="Xamarin.Kotlin.StdLib.Jdk7" Version="1.9.22.1" JavaArtifact="org.jetbrains.kotlin:kotlin-stdlib-jdk7" JavaVersion="1.9.22" />
     <PackageReference Include="Xamarin.Kotlin.StdLib.Jdk8" Version="1.9.22.1" JavaArtifact="org.jetbrains.kotlin:kotlin-stdlib-jdk8" JavaVersion="1.9.22" />
     <PackageReference Include="Xamarin.KotlinX.Coroutines.Android" Version="1.8.0.1" JavaArtifact="org.jetbrains.kotlinx:kotlinx-coroutines-android" JavaVersion="1.8.0.1" />
     <PackageReference Include="Xamarin.KotlinX.Coroutines.Core" Version="1.8.0.1" JavaArtifact="org.jetbrains.kotlinx:kotlinx-coroutines-core" JavaVersion="1.8.0.1" />
     <PackageReference Include="Xamarin.KotlinX.Coroutines.Core.Jvm" Version="1.8.0.1" JavaArtifact="org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm" JavaVersion="1.8.0.1" />
     <PackageReference Include="Xamarin.KotlinX.Coroutines.Jdk8" Version="1.8.0.1" JavaArtifact="org.jetbrains.kotlinx:kotlinx-coroutines-jdk8" JavaVersion="1.8.0.1" />
     <PackageReference Include="Xamarin.KotlinX.Coroutines.Rx3" Version="1.8.0.1" JavaArtifact="org.jetbrains.kotlinx:kotlinx-coroutines-rx3" JavaVersion="1.8.0.1" />

     <!-- Square nugets-->
     <PackageReference Include="Square.Moshi.Adapters" Version="1.13.0" JavaArtifact="com.squareup.moshi:moshi-adapters" JavaVersion="1.15.1" />
     <PackageReference Include="Square.Moshi" Version="1.13.0" JavaArtifact="com.squareup.moshi:moshi" JavaVersion="1.15.1" />
     <PackageReference Include="Square.OkHttp3" Version="4.12.0" JavaArtifact="com.squareup.okhttp3:okhttp" JavaVersion="4.12.0" />
     <PackageReference Include="Square.OkIO" Version="3.6.0.1" JavaArtifact="com.squareup.okio:okio" JavaVersion="3.7.0" />
     <PackageReference Include="Square.OkIO.Jvm" Version="3.6.0.1" JavaArtifact="com.squareup.okio:okio-jvm" JavaVersion="3.7.0" />

 </ItemGroup>

 <PropertyGroup>
     <!-- https://github.com/jpobst/Prototype.Android.MavenBindings/blob/37da8d5ea14a87a754b28620bde12a9799079a99/src/Microsoft.Android.MavenBinding.Tasks/XamPrototype.Android.MavenBinding.Tasks.targets#L11C1-L13C162 -->
     <CacheDirectory Condition="'$(OS)'=='Unix'">$(HOME)\Library\Caches\MavenCacheDirectory\</CacheDirectory>
     <CacheDirectory Condition="'$(OS)'!='Unix'">$(LocalAppData)\MavenCacheDirectory\</CacheDirectory>
 </PropertyGroup>

 <ItemGroup>
     <!-- Stripe files -->
     <!--<AndroidMavenLibrary Include="com.stripe:stripeterminal" Version="$(StripeVersion)" Pack="True" />-->
     <AndroidMavenLibrary Include="com.stripe:stripeterminal-core" Version="$(StripeVersion)" Pack="True" />
     <AndroidMavenLibrary Include="com.stripe:stripeterminal-external" Version="$(StripeVersion)" Pack="True" />
     <AndroidMavenLibrary Include="com.stripe:stripeterminal-handoffclient" Version="$(StripeVersion)" Pack="True" />
     <AndroidMavenLibrary Include="com.stripe:stripeterminal-localmobile" Version="$(StripeVersion)" Pack="True" />
     <AndroidMavenLibrary Include="com.stripe:stripeterminal-internal-common" Version="$(StripeVersion)" Bind="False" />
     <AndroidMavenLibrary Include="com.stripe:stripeterminal-internal-models" Version="$(StripeVersion)" Bind="False" />

     <!-- Workaround to force nuget to include necessary aars in the package, https://github.com/xamarin/xamarin-android/issues/8308#issuecomment-1701616581-->
     <None Include="$(CacheDirectory)/central/com.stripe/stripeterminal-internal-common/$(StripeVersion)/com.stripe_stripeterminal-internal-common.aar" Pack="True" CopyToOutputDirectory="PreserveNewest" PackagePath="lib/net8.0-android34.0" />

     <None Include="$(CacheDirectory)/central/com.stripe/stripeterminal-internal-models/$(StripeVersion)/com.stripe_stripeterminal-internal-models.aar" Pack="True" CopyToOutputDirectory="PreserveNewest" PackagePath="lib/net8.0-android34.0" />
 </ItemGroup>
 <ItemGroup>
     <!-- Manually added dependencies without nugets -->
     <AndroidMavenLibrary Include="com.squareup.tape2:tape" Version="2.0.0-beta1" Bind="False" />
     <AndroidMavenLibrary Include="com.squareup.wire:wire-moshi-adapter" Version="4.9.7" Bind="False" />
     <AndroidMavenLibrary Include="com.squareup.wire:wire-runtime" Version="4.9.7" Bind="False" />
     <AndroidMavenLibrary Include="com.squareup.wire:wire-runtime-jvm" Version="4.9.7" Bind="False" />

     <AndroidMavenLibrary Include="org.jetbrains.kotlin:kotlin-parcelize-runtime" Version="1.9.10" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlin:kotlin-android-extensions-runtime" Version="1.9.10" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:atomicfu" Version="0.19.0" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:atomicfu-jvm" Version="0.19.0" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-datetime" Version="0.5.0" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-datetime-jvm" Version="0.5.0" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-serialization-core" Version="1.6.2" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-serialization-core-jvm" Version="1.6.2" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-serialization-json" Version="1.6.2" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-serialization-json-jvm" Version="1.6.2" Bind="False" />
     <AndroidMavenLibrary Include="org.jetbrains.kotlinx:kotlinx-coroutines-slf4j" Version="1.7.2" Bind="False" />

     <AndroidMavenLibrary Include="com.github.luben:zstd-jni" Version="1.5.2-5" Bind="False" />
     <AndroidMavenLibrary Include="com.jaredrummler:android-device-names" Version="1.1.9" Bind="False" />
     <AndroidMavenLibrary Include="com.neovisionaries:nv-i18n" Version="1.29" Bind="False" />
     <AndroidMavenLibrary Include="com.scottyab:rootbeer-lib" Version="0.1.0" Bind="False" />
     <AndroidMavenLibrary Include="org.apache.commons:commons-compress" Version="1.22" Bind="False" />
     <AndroidMavenLibrary Include="org.brotli:dec" Version="0.1.2" Bind="False" />
     <AndroidMavenLibrary Include="org.ow2.asm:asm" Version="9.4" Bind="False" />
     <AndroidMavenLibrary Include="org.kamranzafar:jtar" Version="2.3" Bind="False" />
     <AndroidMavenLibrary Include="org.slf4j:slf4j-api" Version="1.7.36" Bind="False" />
     <AndroidMavenLibrary Include="org.tukaani:xz" Version="1.9" Bind="False" />
     <AndroidMavenLibrary Include="com.fasterxml.jackson.core:jackson-annotations" Version="2.16.1" Bind="False" />
     <AndroidMavenLibrary Include="com.fasterxml.jackson.core:jackson-core" Version="2.16.1" Bind="False" />
     <AndroidMavenLibrary Include="com.fasterxml.jackson.core:jackson-databind" Version="2.16.1" Bind="False" />
     <AndroidMavenLibrary Include="dev.zacsweers.redacted:redacted-compiler-plugin-annotations" Version="1.7.1" Bind="False" />

     <AndroidMavenLibrary Include="io.ktor:ktor-io" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-io-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-http" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-http-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-utils" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-utils-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-events" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-events-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-websocket-serialization" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-websocket-serialization-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-websockets" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-websockets-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-serialization" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-serialization-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-serialization-kotlinx" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-serialization-kotlinx-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-serialization-kotlinx-json" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-serialization-kotlinx-json-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-core" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-core-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-json" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-json-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-content-negotiation" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-content-negotiation-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-serialization" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-serialization-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-okhttp" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-okhttp-jvm" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-plugins" Version="$(KtorVersion)" Bind="False" />
     <AndroidMavenLibrary Include="io.ktor:ktor-client-plugins-jvm" Version="$(KtorVersion)" Bind="False" />

     <None Include="$(CacheDirectory)/central/com.jaredrummler/android-device-names/1.1.9/com.jaredrummler_android-device-names.aar" Pack="True" CopyToOutputDirectory="PreserveNewest" PackagePath="lib/net8.0-android34.0" />
     <None Include="$(CacheDirectory)/central/com.scottyab/rootbeer-lib/0.0.9/com.scottyab_rootbeer-lib.aar" Pack="True" CopyToOutputDirectory="PreserveNewest" PackagePath="lib/net8.0-android34.0" />
 </ItemGroup>

 <ItemGroup>
     <!-- Have to have these instead of Xamarin nugets or I get class not found exceptions -->
     <!-- like: java.lang.NoClassDefFoundError: Failed resolution of: Lio/reactivex/rxjava3/kotlin/DisposableKt -->
     <AndroidMavenLibrary Include="com.google.guava:guava" Version="32.0.1-android" Bind="False" />
     <None Include="$(CacheDirectory)/central/com.google.guava/guava/32.0.1-android/com.google.guava_guava.jar" Pack="True" CopyToOutputDirectory="PreserveNewest" PackagePath="lib/net8.0-android34.0" />

     <AndroidMavenLibrary Include="io.reactivex.rxjava3:rxkotlin" Version="3.0.1" Bind="False" />
     <None Include="$(CacheDirectory)/central/io.reactivex.rxjava3/rxkotlin/3.0.1/io.reactivex.rxjava3_rxkotlin.jar" Pack="True" CopyToOutputDirectory="PreserveNewest" PackagePath="lib/net8.0-android34.0" />
 </ItemGroup>
svaldetero commented 4 months ago

@chris-oswald Thanks for doing the leg work. Starting off of yours saved some time. Unfortunately, 3+ cannot be bound right now since it requires Google.Dagger 2.5 but xamarin only has nugets for 2.48.x. I tried including dagger as an embedded jar/aar but then I had duplicate class names because some other nuget has a dependency on Google.Dagger. I'm not sure what to do in the mean time. I do have branches for android-3.5 and ios-3.5. I have verified that ios runs correctly. I cant get past the Dagger error so I don't know if there are any other runtime errors for android. If it is worthwhile to have only one platform out, I can publish iOS. Otherwise, I plan on waiting until I can guarantee it is working for both platforms.

chris-oswald commented 4 months ago

I got stuck on dagger too...

ggbtvs commented 2 months ago

Any movement on this as I notice Xamarin has 2.50 for Dagger now? I am really stuck on this and need urgent help @chris-oswald @svaldetero

ggbtvs commented 2 months ago

I am trying to get 3.7.0 bound. Also, I am using .net 8 and cannot get the 3.5.0 solution file to compile.

svaldetero commented 2 months ago

I paused on this since I couldn't get around the Dagger issue for Android. Since Stripe is using a new method that was added in 2.50, there's no way around it.

Looking at Maven Central StripeTerminal Core dependencies:

It looks like this line will work now for binding Stripe 3.4.0: <PackageReference Include="Xamarin.Google.Dagger" Version="2.50.0" JavaArtifact="com.google.dagger:dagger" JavaVersion="2.50.0" />. If Stripe isn't using anything added after 2.50, then we could possibly jump even farther: <PackageReference Include="Xamarin.Google.Dagger" Version="2.50.0" JavaArtifact="com.google.dagger:dagger" JavaVersion="2.51.1" /> and bind the latest Stripe.

@ggbtvs Thanks for informing me of the Xamarin.Google.Dagger update, I was unaware. This is still on my backlog to do, but it's not on my immediate agenda. What feature of Stripe are you using that you need urgent help but can't still use Stripe 3.2.1?

ggbtvs commented 2 months ago

@svaldetero . Thanks for replying. I am trying to get Stripe Working on Android from the very beginning. I have 3.2.1 working fine on IOS. I am NOT using Maui, but Mvvmcross and native screens (storyboards / Android layout xml files). The issue is I can't even get 3.2.1 working and I've tried updating you code to use .net 8 (Android 34) but I get lot's of either' defined multiple times' errors. I the problem I have its I have never working on creating Android bindings before so I don't really know how to get around any issues I came across. Have you ever been able to get 3.2.1 working on Android ? The branch 3.2.0 if yours is for .net 7. Do you have .net 8 version that works?

jasells commented 2 months ago

Do you have .net 8 version that works?

net 7 lib/NuGet package will work with a .Net8 (Maui 8) app, if all other dependencies are resolved.

I've been meaning to post on this repo, as I have an internal Stripe.Terminal XForms binding that I recently ported to .Net 7/Maui.

This issue with the multiple definitions is complicated, but due to directly including all the native .jar/.aar libs in this NuGet. If some other NuGet package also includes a dependency to the same native lib (.jar/.aar), NuGet isn't able to track it and thus includes 2x versions of the .jar/.aar in the build directory for the java-compile step to use, and it is the Java-compiler detecting 2x definitions from the duplicate native lib that NuGet accidentally included 2x: once from this NuGet, and once from another NuGet.

I'll post some more later today... but in the mean time, I started this Open source project to help this situation before I founf this repo.

I've just been very busy working to port my main project from XForms -> Maui 8, but would be very interested in trying to see if we can't work together long term to support a single Stripe.Terminal.Net wrapper package.

If you're interested, take a look at the packages I've already created, and am using for my private Terminal v2.20.0/2.23.3 wrapper. https://xdevapps.visualstudio.com/Android%20bindings

chris-oswald commented 2 months ago

@ggbtvs There is probably a dependency mismatch that you're not accounting for on 3.2.1. Every time stripe updates a lib, it usually means they updated a dependency, and thus, all that dependency's children. It's a spider web you have to unravel every time, which is why you don't see us update these on every minor revision. I'm running the last published version here on MAUI .Net 8 Android just fine.

ggbtvs commented 2 months ago

Thanks so much for your help. I am definitely interesting in working together to support a single Stripe.Terminal.Net wrapper.

jasells commented 2 months ago

Before I forget, this package is one that I know would cause the duplicate definition issue, if both this package (Envoc.Stripe) and the ImageCropper package were included in a Maui app. This was the issue that kicked off the creation of the independent Android NuGet repos I linked; my application was using the XForms image cropper package, but updating to this one to migrate to Maui exposed the conflict with my private Stripe.Terminal wrapper.

https://github.com/jmbowman1107/ImageCropper.Maui

It defines a dependency NuGet for Kotlin.Parcelize.Runtime.Maui https://www.nuget.org/packages/Kotlin.Parcelize.Runtime.Maui#usedby-body-tab

Which is also embedded in this NuGet. https://github.com/Envoc/envoc-stripe-binding/blob/bd6f695991046d264df125abb063df2bf3e80c3b/src/StripeTerminal/Envoc.Stripe.Terminal.Android/Envoc.Stripe.Terminal.Android.csproj#L119 My Terminal v 2.20 NuGet was using the Parcelize package from this repo, but for 2.23, we needed to update, so now we're using the independent package from https://xdevapps.visualstudio.com/Android%20bindings.

This issue could be resolved by updating ImageCropper.Maui to use the independent package, or getting the image cropper repo to update that package and publish to Nuget.org.

Our current plan to resolve this in our App that uses Stripe.Terminal is to replace ImageCropper.Maui with a new Maui-first, X-Platform implementation that has no native-Android dependencies, or open a ticket to see if ImageCropper.Maui will use the independent package.

ggbtvs commented 2 months ago

@jasells Do you have a public line to the repo for the internal Stripe.Terminal XForms binding. I've tried using the nuget from Envoc and in a blank Android .net 8 app, it won't compile, complains about google.gms or something not being installed. If I try to install GooglePlayServices.Base, I then get multiple definitions for Guava etc.

ggbtvs commented 2 months ago

Screenshot 2024-07-08 at 23 41 30 This is errors I get if I just add the nugget package in Android. latest version or 3.2.0. Both do the same

chris-oswald commented 2 months ago

@ggbtvs I don't run many 3rd party dependencies, so you might have some conflicts with the packages you are referencing. I can help with a few of your errors though. Here are my android imports in my csproj

<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
    <PackageReference Include="Envoc.Stripe.Terminal.Handoff.Android" Version="3.2.0" />

    <PackageReference Include="Xamarin.Google.Guava.ListenableFuture" ExcludeAssets="build;buildTransitive">
        <Version>9999.0.0</Version>
    </PackageReference>

    <PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.6.2.1" />
    <PackageReference Include="Xamarin.Google.Android.Material" Version="1.10.0" />
    <PackageReference Include="Xamarin.GooglePlayServices.Location" Version="121.0.1.4" />

    <PackageReference Include="Xamarin.AndroidX.Collection" Version="1.3.0.2" />
    <PackageReference Include="Xamarin.AndroidX.Collection.Ktx" Version="1.3.0.2" />
</ItemGroup>
jasells commented 2 months ago

@ggbtvs I'd look at these package refs first... seems unusual: https://github.com/Envoc/envoc-stripe-binding/blob/bd6f695991046d264df125abb063df2bf3e80c3b/src/StripeTerminal/Envoc.Stripe.Terminal.Android/Envoc.Stripe.Terminal.Android.csproj#L63C1-L65C1

        <PackageReference Include="Xamarin.Google.Guava.FailureAccess" Version="1.0.1" JavaArtifact="com.google.guava:failureaccess" JavaVersion="1.0.1" />
        <PackageReference Include="Xamarin.Google.Guava.ListenableFuture" Version="1.0.0.15" JavaArtifact="com.google.guava:listenablefuture" JavaVersion="9999.0-empty-to-avoid-conflict-with-guava" />

I haven't looked at the dependencies of those, but I'd expect they have some common dependency that may be getting included 2x due to the different versions?

... otherwise I'd trace down exactly which package that ...google.android.gms.common... namespace belongs to. Whatever native package that is, is what is missing.

ggbtvs commented 2 months ago

I am not using Handoff, but the Stripe Terminal. I attach a zip file with a sample app showing the issue. If there is anything anyone can suggest on how to make this control work 'out of the box' I would be very grateful.

This is the compilation error I get

/Users/orderport/Projects/StripePOC3/StripePOC3: Error JAVA0000: Error in /Users/orderport/.nuget/packages/xamarin.androidx.collection.jvm/1.3.0/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-jvm.jar:androidx/collection/ArrayMapKt.class: Type androidx.collection.ArrayMapKt is defined multiple times: /Users/orderport/.nuget/packages/xamarin.androidx.collection.jvm/1.3.0/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-jvm.jar:androidx/collection/ArrayMapKt.class, /Users/orderport/.nuget/packages/xamarin.androidx.collection.ktx/1.2.0.9/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-ktx.jar:androidx/collection/ArrayMapKt.class Compilation failed java.lang.RuntimeException: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: /Users/orderport/.nuget/packages/xamarin.androidx.collection.jvm/1.3.0/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-jvm.jar androidx/collection/ArrayMapKt.class at com.android.tools.r8.internal.Fj.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:98) at com.android.tools.r8.D8.main(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:4) Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: /Users/orderport/.nuget/packages/xamarin.androidx.collection.jvm/1.3.0/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-jvm.jar:androidx/collection/ArrayMapKt.class at Version.fakeStackEntry(Version_3.3.75.java:0) at com.android.tools.r8.internal.Fj.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:75) at com.android.tools.r8.internal.Fj.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:28) at com.android.tools.r8.internal.Fj.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:27) at com.android.tools.r8.internal.Fj.b(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:2) at com.android.tools.r8.D8.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:22) at com.android.tools.r8.D8.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:17) at com.android.tools.r8.internal.Fj.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:85) ... 1 more Caused by: com.android.tools.r8.internal.f: Type androidx.collection.ArrayMapKt is defined multiple times: /Users/orderport/.nuget/packages/xamarin.androidx.collection.jvm/1.3.0/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-jvm.jar:androidx/collection/ArrayMapKt.class, /Users/orderport/.nuget/packages/xamarin.androidx.collection.ktx/1.2.0.9/buildTransitive/net6.0-android31.0/../../jar/androidx.collection.collection-ktx.jar:androidx/collection/ArrayMapKt.class at com.android.tools.r8.internal.JT.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:14) at com.android.tools.r8.internal.JT.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:22) at com.android.tools.r8.internal.HN.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:33) at com.android.tools.r8.internal.HN.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:10) at java.base/java.util.concurrent.ConcurrentHashMap.merge(ConcurrentHashMap.java:2048) at com.android.tools.r8.internal.HN.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:6) at com.android.tools.r8.graph.B2$a.e(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:4) at com.android.tools.r8.dex.b.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:110) at com.android.tools.r8.dex.b.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:28) at com.android.tools.r8.D8.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:25) at com.android.tools.r8.D8.d(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:606) at com.android.tools.r8.D8.c(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:1) at com.android.tools.r8.internal.Fj.a(R8_3.3.75_b7a6ff6b13548611571508fe72282c9167faa649161ca0013edfc92e19bd7e58:24) ... 5 more (JAVA0000) (StripePOC3) java StripePOC3 2.zip

svaldetero commented 1 month ago

Sorry for the silence, but I didn't want to reply until I had something tangible.

I have created bindings for iOS 3.5.0 and 3.8.1. I have updated the cross-platform abstraction with what I have locally and published it with changes for iOS. I recommend pulling the abstraction (Envoc.StripeTerminal) in locally as debugging / tweaking is too hard when it is a nuget package (that's what I did a while back).

I also updated the readme with a few changes that I noticed while updating.

Android is still on my todo, but I am dreading that xml file. Whatever magic syntax I had to generate the nuget last time has been lost as I get (mostly) build errors or the rare chance it builds - I get the same runtime error. I'm not going to push code or publish a nuget unless I get a running binding.

@ggbtvs asked for a NET8.0 version. I multi-targeted iOS for 7 & 8 so you can choose what you want.

svaldetero commented 1 month ago

I was able to do the binding for Android 3.8.0. It requires net8.0-android based on the dependent nuget packages. However, I'm getting a consistent runtime crash 2-5 seconds after my main page loads:

08-08 16:48:51.626  7505  7699 E AndroidRuntime: FATAL EXCEPTION: pool-10-thread-1
08-08 16:48:51.626  7505  7699 E AndroidRuntime: Process: com.appbundle.name, PID: 7505
08-08 16:48:51.626  7505  7699 E AndroidRuntime: java.lang.VerifyError: Verifier rejected class androidx.profileinstaller.ProfileVerifier: com.google.common.util.concurrent.ListenableFuture androidx.profileinstaller.ProfileVerifier.getCompilationStatusAsync() failed to verify: com.google.common.util.concurrent.ListenableFuture androidx.profileinstaller.ProfileVerifier.getCompilationStatusAsync(): [0x2]  can't resolve returned type 'Unresolved Reference: com.google.common.util.concurrent.ListenableFuture' or 'Unresolved Reference: androidx.concurrent.futures.ResolvableFuture' (declaration of 'androidx.profileinstaller.ProfileVerifier' appears in /data/app/~~uWR_avo2MbH1U8x7QEXavA==/com.appbundle.name-Hkayj-U9FRdtVjZssGf-yw==/base.apk)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at androidx.profileinstaller.ProfileVerifier.writeProfileVerification(ProfileVerifier.java:129)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at androidx.profileinstaller.ProfileInstaller.writeProfile(ProfileInstaller.java:577)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at androidx.profileinstaller.ProfileInstaller.writeProfile(ProfileInstaller.java:515)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at androidx.profileinstaller.ProfileInstaller.writeProfile(ProfileInstaller.java:479)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at androidx.profileinstaller.ProfileInstallerInitializer.lambda$writeInBackground$2(ProfileInstallerInitializer.java:145)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at androidx.profileinstaller.ProfileInstallerInitializer$$ExternalSyntheticLambda2.run(Unknown Source:2)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
08-08 16:48:51.626  7505  7699 E AndroidRuntime:    at java.lang.Thread.run(Thread.java:920)

If anyone has any insights into this issue, that would expedite me publishing the nuget package.

ggbtvs commented 1 month ago

Does 3.8.0 add many new dependencies? I put the error in to chat get to see what it came back with. Here is the response. No idea it you've already tried the same, but I know how frustrating it is when you don't get a response to a question asked. So I thought I would try.

The error you're encountering, specifically java.lang.VerifyError, indicates that there's a problem with the bytecode verification of the class androidx.profileinstaller.ProfileVerifier. This issue often arises due to missing or incompatible dependencies, especially when dealing with AndroidX libraries, third-party libraries, or creating bindings for native libraries like Stripe Terminal.

Possible Causes and Solutions

  1. Missing or Incompatible Dependencies:

    • The error suggests that the ListenableFuture class from com.google.common.util.concurrent cannot be resolved. This class is part of the Guava library, which might be missing or incompatible with your project.
    • Ensure that all dependencies required by the Stripe Terminal library are correctly included in your binding project and the consuming app.

    Solution:

    • Make sure you include the necessary Guava dependency. You can add it via Gradle or by manually including the appropriate .jar or .aar files in your Xamarin.Android project.

      For example, you might need to include the Guava library:

      implementation 'com.google.guava:guava:33.2.1.1-android'
  2. AndroidX Compatibility:

    • The error occurs in the androidx.profileinstaller.ProfileVerifier class, which is part of the AndroidX library. There might be a mismatch in the AndroidX libraries being used by your project and the ones expected by the Stripe Terminal library.

    Solution:

    • Ensure that your Xamarin.Android project is using the latest AndroidX libraries. You can update the NuGet packages related to AndroidX in your project.

      Update-Package Xamarin.AndroidX.*
    • Verify that the Stripe Terminal library is compatible with the version of AndroidX you're using.

  3. ProGuard/R8 Configuration:

    • If you're using ProGuard or R8 for code shrinking, it's possible that some necessary classes or methods are being removed or modified incorrectly.

    Solution:

    • Disable ProGuard/R8 temporarily to see if the issue persists. If the issue is resolved, you'll need to add the appropriate ProGuard rules to keep the necessary classes and methods.

      Example of a ProGuard rule to keep all classes and methods in a package:

      -keep class androidx.profileinstaller.** { *; }
      -keep class com.google.common.util.concurrent.** { *; }
  4. Check for Transitive Dependencies:

    • Sometimes, transitive dependencies required by the library might not be automatically included.

    Solution:

    • Use a tool like Gradle to check the dependency tree of the Stripe Terminal library and ensure all transitive dependencies are included in your binding project.

      ./gradlew dependencies

General Steps to Resolve:

  1. Ensure all necessary dependencies are included:

    • Verify that all required dependencies for Stripe Terminal and its transitive dependencies are included in your Xamarin.Android project.
  2. Update your AndroidX libraries:

    • Ensure all AndroidX libraries are up to date and compatible with each other.
  3. Check the ProGuard configuration:

    • Ensure that the ProGuard configuration is not stripping out necessary classes.
  4. Check for missing or incompatible dependencies:

    • Ensure that all the necessary dependencies are available and compatible.
  5. Build and test the app:

    • After making these changes, rebuild your app and see if the issue is resolved.

If the problem persists, you may need to investigate further into the specific versions of dependencies and their compatibility with each other, as well as look into the specific requirements of the Stripe Terminal library.

Apologies if this does not help.

ggbtvs commented 1 month ago

If you want to share your code, I don't mind trying to have a look at some things. I finally managed to create my own 3.4.0 binding working (.net8), again I was running into many runtime errors. The main difference between my approach and yours appears to be, I did not use many Maven repository references , choosing instead to use as many of the nuget packages. It's clunky and the code is probably totally shit, but it works, and for me that was the main thing.

svaldetero commented 1 month ago

New Packages

Square.OkHttp3.OkHttp.TLS v4.12.0 Xamarin.Kotlin.Reflect v2.0.0.1

Converted AndroidMavenLibrary -> PackageReference

org.jetbrains.kotlin:kotlin-parcelize-runtime -> Xamarin.Kotlin.Parcelize.Runtime v2.0.0.1 org.jetbrains.kotlin:kotlin-android-extensions-runtime -> Xamarin.Kotlin.Android.Extensions.Runtime.Library v2.0.0.1 org.jetbrains.kotlinx:kotlinx-datetime -> Org.Jetbrains.Kotlinx.KotlinxDatetime v0.6.0

I already had a nuget reference to Xamarin.Google.Guava.ListenableFuture v1.0.0.18 -> 1.0.0.22

@ggbtvs I tried to use as many nugets a possible, but when I first did this, a lot of nugets didn't exist. I did look at @jasells binding packages and I might try to switch to more nugets over AndroidMavenLibrary.

svaldetero commented 1 month ago

Check out branch https://github.com/Envoc/envoc-stripe-binding/tree/android-3.8.0 for the current code I'm working with

svaldetero commented 1 month ago

Turns out for the java.lang.VerifyError: Verifier rejected class error, I just needed to add the guava package to my Maui app.

<PackageReference Include="Xamarin.Google.Guava" Version="32.0.1" />

Now I have the runtime error that a class isn't found. Going further down the rabbit hole.

jasells commented 3 weeks ago

Something to keep an eye on in .Net9: https://github.com/dotnet/android/pull/9112

This is in direct response to a request I made to improve the existing Prototype.Android.MavenBindings that this repo is using.

https://github.com/dotnet/android/issues/9013

And, I forked that prototype to support .Net7/8 with the feature that was just added to .Net9 here (and I am currently using in my own Stripe.Terminal bindings).