Reputation: 1126
I couldn't find any documentation on using RevenueCat bindings in Xamarin Forms, or any examples. How to get started? I think it's supposed to be obvious, but it wasn't for me.
Answering my own question below, I've made a small start, haven't tested any code yet. Please feel free to expand or correct.
This is for Xamarin Forms iOS on Visual Studio 2022 for Mac; MAUI could be similar.
Upvotes: 5
Views: 953
Reputation: 2407
For MAUI I have created a simple wrapper around iOS and Android bindings: https://github.com/Kebechet/Maui.RevenueCat.InAppBilling
you can inspire from the code or simply install it through nuget
Here is the simple example how to get offerings from RevenueCat for Android:
public class RevenueCatBilling
{
private Purchases _purchases = default!;
private static Activity? _currentActivityContext => Platform.CurrentActivity;
public void Initialize(string apiKey)
{
if (_currentActivityContext is null)
{
throw new Exception("You must call this code in App.xaml->OnStart");
}
try
{
_purchases = Purchases.Configure(
new PurchasesConfiguration(
new PurchasesConfiguration.Builder(
_currentActivityContext,
apiKey)
)
);
_isInitialized = true;
}
catch
{
throw;
}
}
public async Task<List<Offering>> LoadOfferings(CancellationToken cancellationToken)
{
try
{
using var offerings = await Purchases.SharedInstance.GetOfferingsAsync(cancellationToken);
if (offerings is null)
{
return new();
}
using var currentOffering = offerings.Current;
if (currentOffering is null)
{
return new();
}
return currentOffering.AvailablePackages.ToList();
}
catch
{
return new();
}
}
public static Task<Offerings> GetOfferingsAsync(this Purchases purchases,
CancellationToken cancellationToken = default)
{
var listener = new DelegatingReceiveOfferingsCallback(cancellationToken);
purchases.GetOfferings(listener);
return listener.Task;
}
}
internal sealed class DelegatingReceiveOfferingsCallback : DelegatingListenerBase<Offerings>, IReceiveOfferingsCallback
{
public DelegatingReceiveOfferingsCallback(CancellationToken cancellationToken) : base(cancellationToken)
{
}
public void OnError(PurchasesError purchasesError)
{
ReportException(new PurchasesErrorException(purchasesError, false));
}
public void OnReceived(Offerings offerings)
{
ReportSuccess(offerings);
}
}
internal abstract class DelegatingListenerBase<TResult> : Java.Lang.Object
{
private readonly TaskCompletionSource<TResult> _taskCompletionSource;
public DelegatingListenerBase(CancellationToken cancellationToken)
{
_taskCompletionSource = new TaskCompletionSource<TResult>();
cancellationToken.Register(() => _taskCompletionSource.TrySetCanceled());
}
public Task<TResult> Task => _taskCompletionSource.Task;
protected void ReportSuccess(TResult result)
{
_taskCompletionSource.TrySetResult(result);
}
protected void ReportException(Exception exception)
{
_taskCompletionSource.TrySetException(exception);
}
}
Upvotes: 1
Reputation: 1126
[Edit 23 Feb 2023: For a complete sample of RevenueCat code for iOS and Android, see instead my post at https://stackoverflow.com/questions/75541953/sample-code-for-revenuecat-in-app-functions-in-xamarin-forms-or-net-maui]
[Edit] I removed my suggestion to bind the Swift library, as it does not seem to be necessary.
A few sample code lines:
using RevenueCat;
using Xamarin.RevenueCat.iOS.Extensions;
....
RCPurchases.DebugLogsEnabled = true;
RCPurchases.ConfigureWithAPIKey( "my api key" );
RCPurchases.SharedPurchases.AllowSharingAppStoreAccount = true;
RCCustomerInfo purchaserInfo = await RCPurchases.SharedPurchases.RestoreTransactionsAsync ();
RCOfferings offerings = await RCPurchases.SharedPurchases.GetOfferingsAsync ();
Upvotes: 3