Kebechet.Maui.RevenueCat.iOS 5.102.1

Prefix Reserved
dotnet add package Kebechet.Maui.RevenueCat.iOS --version 5.102.1
                    
NuGet\Install-Package Kebechet.Maui.RevenueCat.iOS -Version 5.102.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kebechet.Maui.RevenueCat.iOS" Version="5.102.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kebechet.Maui.RevenueCat.iOS" Version="5.102.1" />
                    
Directory.Packages.props
<PackageReference Include="Kebechet.Maui.RevenueCat.iOS" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kebechet.Maui.RevenueCat.iOS --version 5.102.1
                    
#r "nuget: Kebechet.Maui.RevenueCat.iOS, 5.102.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kebechet.Maui.RevenueCat.iOS@5.102.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kebechet.Maui.RevenueCat.iOS&version=5.102.1
                    
Install as a Cake Addin
#tool nuget:?package=Kebechet.Maui.RevenueCat.iOS&version=5.102.1
                    
Install as a Cake Tool

"Buy Me A Coffee"

Maui.RevenueCat.iOS

NuGet Version NuGet Downloads Last updated (main) Twitter

Versioning Scheme

The versioning scheme of Maui.RevenueCat.iOS is derived from the versioning of revenuecat/purchases-ios.

Example:

revenuecat/purchases-ios Maui.RevenueCat.iOS Note
3.4.1 3.4.1.0 First version of bindings for 3.4.1
3.4.1 3.4.1.17 Bindings for 3.4.1 containing fixes

Binding creation

The canonical way to regenerate this binding is the .github/workflows/try-bump-ios.yml workflow (daily, or dispatched with a version), not the manual steps below. The workflow builds RevenueCat.xcframework from source with the BYPASS_SIMULATED_STORE_RELEASE_CHECK flag so Test Store (test_…) keys work on iOS — see Test Store API key support and #116. The manual steps in this section download the pre-built RevenueCat.xcframework.zip instead, which is always Release-configured and does NOT include that bypass — following them would reintroduce the force-close on Test Store keys. They are kept for historical context and to explain the cleanups the workflow's post-processor automates.

Porting old xamarin library ios to .NET MAUI

First version of our Maui binding was just changed Xamarin.RevenueCat.iOS binding working for .NET MAUI. It was binding around RevenueCat ios 4.9.0, but this native library contained bitcode which is no longer accepted by AppStore. Porting of binding from Xamarin to Maui required several changes:

  • Removed some attributes in ApiDefinitions - commit
  • Changed IntPtr → NativeReference in ApiDefinitions - commit
  • Added NoBindingEmbedding = false - commit

Creating completely new binding consisted of these steps:

Because of a problem with bitcode I have decided to create completely new binding from scratch. Here are steps I have done:

Generating binding files

  • On my MAC I have downloaded and installed Objective Sharpie
  • I have downloaded RevenueCat.xcframework.zip of purchases-ios v4.19.0
  • Extract inner RevenueCat.xcframework/ios-arm64 folder on MAC desktop.
  • started terminal, then cd ~/Desktop
  • firstly check what versions of xcode SDKs you have installed by sharpie xcode -sdks and use the iphoneosXX.Y version you have
  • I used command sharpie bind -framework ios-arm64/RevenueCat.framework -sdk iphoneos18.4 -scope ios-arm64/RevenueCat.framework/Headers
    • this command generated ApiDefinitions.cs and StructsAndEnums.cs files
    • in case it did not and gives you error: RevenueCat: framework requires SDK 'iphoneosXX.Y' which is not installed. You may need a newer Xcode. In my case it was iphoneos16.4
      • if you have older Xcode then update it
      • if you have newest Xcode then you need to install older iOS SDKs
        • go to Apple developer web and download Xcode that contains that SDK. In my case Xcode 14.3.1 contains iphoneos16.4
        • after the download extract .xip file and after extraction right click on extracted Xcode file and Show Package Contents
        • then navigate there into Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs and copy iPhoneOsXX.Y.sdk (if it is just link/alias then copy the iPhoneOs.sdk and rename it to iPhoneOsXX.Y.sdk in my case iPhoneOS16.4.sdk)
        • then go to location of your original Xcode → Show Package Contents → navigate again to: Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs and paste the copied iPhoneOSXX.Y.sdk there
        • restart Xcode
        • to verify you did everything correctly run in terminal: sharpie xcode -sdks and the new SDK you copied should be now there as well
        • then run the sharpie command to generate ApiDefinitions.cs and StructsAndEnums.cs files again

Test Store API key support (BYPASS_SIMULATED_STORE_RELEASE_CHECK)

  • The pre-built RevenueCat.xcframework.zip release asset published by RevenueCat/purchases-ios is always Release-configured. Its Sources/Purchasing/Configuration.swift contains the guard #if !DEBUG && !BYPASS_SIMULATED_STORE_RELEASE_CHECK which calls checkForSimulatedStoreAPIKeyInRelease(...) and force-closes any consumer app initialised with a Test Store API key (test_…) — even in DEBUG, because the framework itself was built Release.
  • To make Test Store keys usable for development without an App Store setup, the bundled nativelib/RevenueCat.xcframework is built from source by .github/workflows/try-bump-ios.yml with the BYPASS_SIMULATED_STORE_RELEASE_CHECK Swift compilation flag set via Local.xcconfig:
    SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) BYPASS_SIMULATED_STORE_RELEASE_CHECK
    
  • This mirrors the approach used by RevenueCat/purchases-kmp in its kn-core/build.gradle.kts (swiftSettings { define("BYPASS_SIMULATED_STORE_RELEASE_CHECK") }).
  • Global.xcconfig at the purchases-ios repo root does #include? "Local.xcconfig" and is read by RevenueCat.xcodeproj, so writing Local.xcconfig is enough for the flag to reach the build.
  • The workflow verifies the bypass is active by asserting BYPASS_SIMULATED_STORE_RELEASE_CHECK is present in the RevenueCat target's resolved SWIFT_ACTIVE_COMPILATION_CONDITIONS (xcodebuild -showBuildSettings) before building — a direct, positive check rather than relying on the absence of an internal symbol that may never be externally visible regardless of the flag.
  • See issue #116 for context.

Adjusting generated files

  • then I placed new framework file into repo
  • firstly commented but later completely removed Verify attributes - commit
  • then removed all device-specific attributes - commit
    • TIP: You can find all attributes by searching for iOS (. Because all of them contain this string
    • at the same time commented out (AutoGeneratedName = true)
  • added namespaces - commit
  • comment out text that was not commented out - commit
  • then I merged interfaces with the same names e.g. RCAttribution and RCAttribution_RevenueCat_Swift_3714 I put together - commit
    • I have also removed obsolete & deprecated interfaces/methods
  • removed default using there were useless - commit
  • removed constants interface - commit
    • because I didnt know how to bind byte[] 😅
    • (optional) If you would like to bind the RevenueCatVersionNumber use this for interface name: [BaseType(typeof(NSObject))] [DisableDefaultCtor] interface RCConstants and above the variable put [Static] attribute
  • removed interfaces without methods/properties - commit
  • remove Protocols that were used for inheritance - commit
  • removed delegate that was not used anywhere - commit
  • added INativeObject inheritance for interfaces that were used in dictionaries and was of type NSObject - commit
    • error example: cannot be used as type parameter 'TValue' in the generic type or method 'NSDictionary<TKey, TValue>'
  • replaced NSUrlRequest for NSMutableUrlRequest - commit
  • created delegates for Purchases - commit
    • when delegates are not replaced then error Trampolines.g.cs(433,25,433,26): error CS1026: ) expected
  • removed inherited NSObject methods - commit
    • isEqual and Description
    • also removed DebugDescription - commit
  • removed inherited NSOperation methods - commit
  • I have created aliases for methods named the same - commit
    • ⚠️ I dont know if this is correct or even necessary, maybe I could delete them as well
    • The post-processor does this for methods: the second LogIn (string, Action<…>) becomes LogInCompletionHandler, named after the last part of its selector.
    • 🛑 Never rename a Constructor this way. bgen treats only a member named Constructor as an initializer, so a renamed one (ConstructorCustomEntitlementComputation) is a plain method that sends init… to an object that already exists.
      • Two initializers can share a C# signature: 5.102.1 added initWithAutoSyncPurchases:forceAllowTestStoreInReleaseBuilds: next to initWithAutoSyncPurchases:customEntitlementComputation:, both (bool, bool).
      • Keep Constructor on the selector the published binding already binds, otherwise new RCDangerousSettings(bool, bool) still compiles for every consumer and quietly sets the other option.
      • Bind the other one [Internal], the way dotnet/macios binds VNVector's initWithR:theta: (VNVector.cs):
        [Export ("initWithAutoSyncPurchases:forceAllowTestStoreInReleaseBuilds:")]
        [Internal]
        NativeHandle _InitWithAutoSyncPurchasesForceAllowTestStoreInReleaseBuilds (bool autoSyncPurchases, bool forceAllowTestStoreInReleaseBuilds);
        
      • The post-processor does all of this itself: the bump workflow passes the committed ApiDefinitions.cs as --published, and the manual-review report lists every initializer it bound [Internal].
      • To make such an initializer public, add a factory in a partial class in a regular .cs file of the binding project (not ApiDefinitions.cs):
        public partial class RCDangerousSettings
        {
            public static RCDangerousSettings CreateWithForceAllowTestStoreInReleaseBuilds(bool autoSyncPurchases, bool forceAllowTestStoreInReleaseBuilds)
            {
                var dangerousSettings = new RCDangerousSettings(NSObjectFlag.Empty);
                dangerousSettings.InitializeHandle(dangerousSettings._InitWithAutoSyncPurchasesForceAllowTestStoreInReleaseBuilds(autoSyncPurchases, forceAllowTestStoreInReleaseBuilds));
                return dangerousSettings;
            }
        }
        
      • The bump PR's API report lists a member under 🛑 when its C# signature stayed but its selector changed, and the PR opens as an api-rebound draft.
  • removed attributes containing Name - commit
    • this was because on my windows machine I was getting errors that platform doesnt have symbols specified for this methods containing the name
    • later I completely removed those methods because the error was still there - commit
  • From [Obsoleted] remove all new line characters \n
  • from .xcframework remove all *.swiftmodule directories
  • ✅ - Done
    • I have tested this new binding in the simulator as well as on real device through TestFlight and it works as expected

Additional fix:

  • if you experience build error: lang++ exited with code 1: error : Undefined symbols for architecture arm64
    • I experienced this problem while debugging on Remote device (iphone connected directly to MAC and that MAC connected to Windows)
"_OBJC_CLASS_$_FakeASIdManager", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_FakeAfficheClient", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_FakeTrackingManager", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_NetworkOperation", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_PaymentQueueWrapper", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_ProductsFetcherSK1", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_PurchasesReceiptParser", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_StoreKit1Wrapper", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_StoreKitRequestFetcher", referenced from:
  objc-class-ref in registrar.o
"_OBJC_CLASS_$_TrackingManagerProxy", referenced from:
  objc-class-ref in registrar.o

  • then remove those types e.g. FakeASIdManager from ApiDefinitions.cs file - commit

Xcode

  • When latest Xcode version is out it doesn't mean MAUI/Xamarin can immediately it.
    • You can find here what Xcode is currently supported. Even though Xcode version is on the list make sure to check open github issues in the xamarin-macios repo
    • In case you want to upgrade/downgrade to specific Xcode version then:
      • uninstall your current version
      • download version you want: https://developer.apple.com/download/all/
      • extract .xip file and move it's content to /Applications folder
      • after extraction open Xcode and it will ask you to install additional components (e.g. iOS) so install it
  • In case you get error The connection cannot continue because the remote iOS SDK was not found or is corrupted.
    • go to your MAC and in terminal do: rm -rf ~/Library/Caches/Xamarin/XMA/SDKs/dotnet/

⚠️Warning

  • in .NET 7 and with VS2022 v17.7 IT IS NOT POSSIBLE TO BUILD THE PACKAGE WITH EMBEDDED NATIVE LIBRARY (even with connected MAC).
  • in VS2022 v17.8.4 with latest MAUI it works correctly

License

This repository is licensed with the MIT license.

Product Compatible and additional computed target framework versions.
.NET net9.0-ios18.0 is compatible.  net9.0-maccatalyst18.0 is compatible.  net10.0-ios was computed.  net10.0-maccatalyst was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0-ios18.0

    • No dependencies.
  • net9.0-maccatalyst18.0

    • No dependencies.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Kebechet.Maui.RevenueCat.iOS:

Package Downloads
Kebechet.Maui.RevenueCat.InAppBilling

A unified C# API over the RevenueCat Android, iOS and Mac Catalyst SDKs, so you write no platform-specific purchase code. Covers subscriptions, one-time purchases, entitlements, restore, login/logout and subscriber attributes, with a Windows stub for development. RevenueCat Test Store keys (test_...) also work in iOS Release builds - the shipped xcframework is built from source with BYPASS_SIMULATED_STORE_RELEASE_CHECK instead of using the prebuilt framework, which would force-close the app. https://docs.revenuecat.com/docs

MZikmund.Uno.RevenueCat

Serves as an abstraction around RevenueCat Android and iOS SDKs for Uno Platform https://docs.revenuecat.com/docs

Kapusch.RevenueCatUI.iOS

Thin .NET iOS interop for RevenueCat Paywalls (RevenueCatUI), on top of the Kebechet.Maui.RevenueCat.iOS core binding.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.102.1 228 11/5/2026
5.83.1 3,967 8/6/2026
5.72.0.3 212 8/5/2026
5.72.0.2 152 8/5/2026
5.72.0.1 2,026 5/12/2026
5.72.0 166 5/12/2026
5.34.0.1 3,955 8/18/2025
5.34.0 295 8/11/2025
4.31.9.6 1,543 1/11/2025
4.31.9.6-preview4 200 1/11/2025
4.31.9.6-preview3 187 1/11/2025
4.31.9.6-preview2 177 1/11/2025
4.31.9.6-preview1 194 1/11/2025
4.31.9.5 237 1/11/2025
4.31.9.4 247 1/11/2025
4.31.9.3 2,251 9/30/2024
4.31.9.2 323 8/7/2024
4.31.9.1 2,732 1/18/2024
4.31.9.1-preview1 204 1/18/2024
4.31.9 289 1/17/2024
Loading failed

5.102.1.0: RevenueCat iOS SDK updated from 5.83.1 to 5.102.1. The xcframework is built from source with BYPASS_SIMULATED_STORE_RELEASE_CHECK, so Test Store keys work in Release. RevenueCat SDK changes per version (RevenueCatUI is not bound):
5.83.2: fix(remote-config): Fix misleading ui_config warnings for projects without paywalls.
5.84.0: feat(ads): add optional tracking metadata to pollRewardVerification. fix(paywalls): Resolve bundled fonts by name before downloading. fix(paywalls): tolerate duplicate font names when registering.
5.85.0: feat(ads): admob adapter support for reward tracking. fix: order queue receipt post after in-flight purchase post.
5.86.0: feat: add confirmInScene and confirmInWindow purchase params. feat: Expose displayName and originalPurchaseDate on NonSubscriptionTransaction. Track checkpoint hits through the analytics events pipeline.
5.87.0: feat(singular) add $singularDeviceId subscriber attribute for Singular V2.
5.87.1: no RevenueCat SDK changes listed (RevenueCatUI or internal changes only).
5.88.0: Surface attribute sync errors when fetching offerings. Fall back to "en" when a workflow screen omits default_locale. Cache web purchase redemption CustomerInfo for the initiating App User ID.
5.89.0: feat(ads): ad tracking and rewarded ad grants beta. Fix Paywall V2 rendering when components are provided by an offering. fix: send X-Is-Sandbox header when using a Test Store API key. Fix URL-open publishing on a background thread.
5.90.0: fix: preserve errors when Result's Success is inferred as optional.
5.90.1: Do not apply a previous user's CustomerInfo after an identity change.
5.90.2: Fix fallback config signature verification for 304 responses.
5.91.0: Prevent subscriber attribute sync before CustomerInfo is available.
5.92.0: refactor(ads): rename rewarded ad prompt types to AdRewardPrompt*. feat(ads): track rewarded ad prompt shown and accepted events. Allow opting in to external purchase custom links (experimental). fix(customerinfo): notify observers when active entitlements change.
5.93.0: feat(paywalls): prewarm videos for current locale. feat(paywalls): implement support for localized videos on iOS. fix(paywalls): use video size for thumbnail overlay.
5.94.0: fix(paywalls): videos with fit width not rendering.
5.95.0: feat(ads): allow manual rewarded ad earned tracking. Render lifetime period variables on Paywalls V2. Checkpoints: fix(checkpoints): Prevent duplicate workflow error alerts when an error presenter is configured. Paywallsv2: Open the in-app web checkout from the purchase button.
5.96.0: feat(ads): add revenuecat mediator type. fix(test-store): Forward Test Store purchase attribution context. fix(billing plans): use product.id in log messages. Checkpoints: fix(checkpoints): suppress callbacks for terminal checkpoint errors. Checkpoints: fix(checkpoints): respect preferred locale override in local rules.
5.96.1: no RevenueCat SDK changes listed (RevenueCatUI or internal changes only).
5.97.0: Load configured ad rewards from remote config. Add configured ad rewards API. Storekit 2: feat: parse OwnershipType.assigned.
5.98.0: Share one product cache between offerings and intro eligibility. Fix product cache invalidation and shared request results. Handle re-login as the same user.
5.99.0: (Experimental) Allow configuring intro eligibility warm-up task priority. Share StoreKit 2 intro eligibility checks by subscription group.
5.99.1: Coordinate overlapping intro eligibility cache warm-ups.
5.99.2: fix(flows) share in-flight flow prewarming decodes.
5.100.0: feat(checkpoints): ad checkpoint presenter. Avoid repeated rejected SK2 observer-mode history submissions.
5.101.0: feat(ads): AdMob interstitial checkpoint presenter. Fix diagnostics timestamp overflow on 32-bit watchOS.
5.102.0: feat(ads): dispatch checkpoint ad presentation by format. feat(ads): extend admob presenter with rewarded support. fix: preserve workflow attribution in custom paywall impressions. Paywallsv2: fix: Reduce CPU usage when downloading large assets.
5.102.1: fix: prevent race in sandbox environment detection.
Full changelog: https://github.com/RevenueCat/purchases-ios/releases