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
<PackageReference Include="Kebechet.Maui.RevenueCat.iOS" Version="5.102.1" />
<PackageVersion Include="Kebechet.Maui.RevenueCat.iOS" Version="5.102.1" />
<PackageReference Include="Kebechet.Maui.RevenueCat.iOS" />
paket add Kebechet.Maui.RevenueCat.iOS --version 5.102.1
#r "nuget: Kebechet.Maui.RevenueCat.iOS, 5.102.1"
#:package Kebechet.Maui.RevenueCat.iOS@5.102.1
#addin nuget:?package=Kebechet.Maui.RevenueCat.iOS&version=5.102.1
#tool nuget:?package=Kebechet.Maui.RevenueCat.iOS&version=5.102.1
Maui.RevenueCat.iOS
- this binding is based on: https://github.com/thisisthekap/Xamarin.RevenueCat.iOS
- it is created for .NET MAUI
- it contains bindings for RevenueCat iOS plugin
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→NativeReferenceinApiDefinitions- 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-arm64folder on MAC desktop. - started terminal, then
cd ~/Desktop - firstly check what versions of xcode SDKs you have installed by
sharpie xcode -sdksand use theiphoneosXX.Yversion 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.csandStructsAndEnums.csfiles - 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 wasiphoneos16.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.1containsiphoneos16.4 - after the download extract
.xipfile and after extraction right click on extracted Xcode file andShow Package Contents - then navigate there into
Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKsand copyiPhoneOsXX.Y.sdk(if it is just link/alias then copy theiPhoneOs.sdkand rename it toiPhoneOsXX.Y.sdkin my caseiPhoneOS16.4.sdk) - then go to location of your original Xcode →
Show Package Contents→ navigate again to:Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKsand paste the copiediPhoneOSXX.Y.sdkthere - restart Xcode
- to verify you did everything correctly run in terminal:
sharpie xcode -sdksand the new SDK you copied should be now there as well - then run the
sharpiecommand to generateApiDefinitions.csandStructsAndEnums.csfiles again
- go to Apple developer web and download Xcode that contains that SDK. In my case
- this command generated
Test Store API key support (BYPASS_SIMULATED_STORE_RELEASE_CHECK)
- The pre-built
RevenueCat.xcframework.ziprelease asset published byRevenueCat/purchases-iosis always Release-configured. ItsSources/Purchasing/Configuration.swiftcontains the guard#if !DEBUG && !BYPASS_SIMULATED_STORE_RELEASE_CHECKwhich callscheckForSimulatedStoreAPIKeyInRelease(...)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.xcframeworkis built from source by.github/workflows/try-bump-ios.ymlwith theBYPASS_SIMULATED_STORE_RELEASE_CHECKSwift compilation flag set viaLocal.xcconfig:SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) BYPASS_SIMULATED_STORE_RELEASE_CHECK - This mirrors the approach used by
RevenueCat/purchases-kmpin itskn-core/build.gradle.kts(swiftSettings { define("BYPASS_SIMULATED_STORE_RELEASE_CHECK") }). Global.xcconfigat thepurchases-iosrepo root does#include? "Local.xcconfig"and is read byRevenueCat.xcodeproj, so writingLocal.xcconfigis enough for the flag to reach the build.- The workflow verifies the bypass is active by asserting
BYPASS_SIMULATED_STORE_RELEASE_CHECKis present in the RevenueCat target's resolvedSWIFT_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
Verifyattributes - 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)
- TIP: You can find all attributes by searching for
- added namespaces - commit
- comment out text that was not commented out - commit
- then I merged interfaces with the same names e.g.
RCAttributionandRCAttribution_RevenueCat_Swift_3714I 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
RevenueCatVersionNumberuse this for interface name:[BaseType(typeof(NSObject))] [DisableDefaultCtor] interface RCConstantsand above the variable put[Static]attribute
- because I didnt know how to bind
- removed interfaces without methods/properties - commit
- remove Protocols that were used for inheritance - commit
- removed delegate that was not used anywhere - commit
- added
INativeObjectinheritance for interfaces that were used in dictionaries and was of typeNSObject- commit- error example:
cannot be used as type parameter 'TValue' in the generic type or method 'NSDictionary<TKey, TValue>'
- error example:
- replaced
NSUrlRequestforNSMutableUrlRequest- commit - created delegates for Purchases - commit
- when delegates are not replaced then error
Trampolines.g.cs(433,25,433,26): error CS1026: ) expected
- when delegates are not replaced then error
- removed inherited
NSObjectmethods - commitisEqualandDescription- also removed
DebugDescription- commit
- removed inherited
NSOperationmethods - 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<…>)becomesLogInCompletionHandler, named after the last part of its selector. - 🛑 Never rename a
Constructorthis way. bgen treats only a member namedConstructoras an initializer, so a renamed one (ConstructorCustomEntitlementComputation) is a plain method that sendsinit…to an object that already exists.- Two initializers can share a C# signature: 5.102.1 added
initWithAutoSyncPurchases:forceAllowTestStoreInReleaseBuilds:next toinitWithAutoSyncPurchases:customEntitlementComputation:, both(bool, bool). - Keep
Constructoron the selector the published binding already binds, otherwisenew RCDangerousSettings(bool, bool)still compiles for every consumer and quietly sets the other option. - Bind the other one
[Internal], the way dotnet/macios bindsVNVector'sinitWithR: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.csas--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
.csfile of the binding project (notApiDefinitions.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-rebounddraft.
- Two initializers can share a C# signature: 5.102.1 added
- 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
.xcframeworkremove all*.swiftmoduledirectories - ✅ - 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.
FakeASIdManagerfromApiDefinitions.csfile - 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
.xipfile and move it's content to/Applicationsfolder - 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/
- go to your MAC and in terminal do:
⚠️Warning
- in
.NET 7and withVS2022v17.7IT IS NOT POSSIBLE TO BUILD THE PACKAGE WITH EMBEDDED NATIVE LIBRARY (even with connected MAC).- You need to build this package on MAC with VS for MAC. Only that way it will link native library to the package.
- https://github.com/dotnet/maui/issues/14982
- in
VS2022v17.8.4with latestMAUIit works correctly
License
This repository is licensed with the MIT license.
| Product | Versions 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. |
-
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 |
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