revnix_flutter 1.11.0
revnix_flutter: ^1.11.0 copied to clipboard
Revnix subscriptions and entitlements for Flutter: offline-resilient entitlement checks, placements, and StoreKit 2 / Play Billing purchase registration.
Unreleased #
1.11.0 #
Added #
logPaywallShown(productsShown:)andRevnixPaywallProductShown: the display beacon can carry the products a paywall showed (productId,priceLabel,amountMinor,currency);RevnixPaywallfills it from packages that have aproductId. Omitted when empty.
Changed #
- Native SDKs: RevnixSDK-iOS 28dcb7c → 095c4f1, RevnixSDK-Android 42914f9 → 035ffb6.
1.10.1 #
Changed #
- Native SDKs: RevnixSDK-iOS 3acce2c → 2c65edf, RevnixSDK-Android 986f79d → f1b54dd.
1.10.0 #
Added #
Future<String> identify(String userId): adopts the given customer id on the device with no network call, using the native 1.9.0identify. Trims the id; an empty id or one over 200 characters is ignored and the current id is returned. Your backend must still callPOST /v1/identifywith a secret key to merge the anonymous history.
Changed #
- The offline entitlement cache is not signed yet: the bundled native SDKs (1.9.0) do not verify the server's new entitlement signature. Verification arrives when the plugin next bumps its native iOS and Android SDKs.
- Native SDKs: RevnixSDK-iOS 46e92d7 → 3acce2c, RevnixSDK-Android 26255ae → 986f79d.
1.9.0 #
Added #
collectAdvertisingIdoption onconfigure(default false, Android only): reports the Google Advertising ID asgps_adid. Needscom.google.android.gms:play-services-ads-identifierand theAD_IDpermission in the app. With limit ad tracking on, no id is sent and a previously sent id is cleared; without the dependency no id is sent and thediagnosticsstream reports it.
Changed #
- Native SDKs: RevnixSDK-iOS 4e83602 → 46e92d7, RevnixSDK-Android 8e29fcd → 26255ae.
1.8.1 #
Changed #
- Native SDKs: RevnixSDK-iOS 56a5ac8 → 4e83602, RevnixSDK-Android 8e29fcd → 8e29fcd.
1.8.0 #
Added #
- Paywall blocks: onboarding screens. A designed paywall can open on intro
screenswith progress dots, moved through by the newnextandbackactions, before the paywall itself; one display, one view report, and older SDKs open straight on the paywall.
Changed #
- Native SDKs: RevnixSDK-iOS d2bac3a → 56a5ac8, RevnixSDK-Android 8077d6e → 8e29fcd.
1.7.0 #
deviceIntegrityoption onconfigure. Opt in to Apple App Attest / Google Play Integrity evidence on install reports.- Paywall blocks:
timer,video,toggleand the cardcarousellayout. Countdown to a date or from when the paywall opens, a video drawn as its poster (Flutter has no built-in player), a free-trial switch that flips the selected package, and swipeable pages with dots and optional auto-advance.
Changed #
- Native SDKs: RevnixSDK-iOS ef5d1a9 → d2bac3a, RevnixSDK-Android 1b6799a → 8077d6e.
1.6.0 #
flushEvents()andpreload(placementKeys). Events are now batched and persisted, and placements resolve cache-first, via the 1.6.0 natives.- Release automation:
release.ymllands the version bump and tags it;publish.ymlpublishes the tag to pub.dev through automated publishing.
Changed #
- Native SDKs: RevnixSDK-iOS d1979df → ef5d1a9, RevnixSDK-Android 0c952db → 1b6799a.
1.5.0 #
First release on pub.dev. Version numbers now follow the Revnix app and the other Revnix SDKs.
-
Built-in
purchase(productId)andrestore(). The plugin now runs the store purchase itself through StoreKit 2 / Play Billing, validates the receipt and grants the entitlement;in_app_purchaseis no longer required.registerPurchasestays for apps that keep their own store plugin. -
Native SDKs bumped to revnix-swift 1.5.0 and revnix-kotlin 1.5.0 (3779134). What reaches Flutter: on iOS the IDFA goes out with the install report when tracking is authorized; on Android install reports now carry a device key so restored reinstalls are counted. Device integrity evidence is in the pins but not exposed by this plugin yet.
-
PlacementResolution.previewis now forwarded by both native bridges instead of always readingfalse. -
diagnosticsfires on iOS. The sink was captured atconfigure()time, before Dart could subscribe, so the stream stayed silent. -
Re-
configure()cleans up. The previous StoreKit observer is cancelled and the previous Play Billing connector closed instead of leaking. -
Unexpected native failures surface as
RevnixExceptioncodeunknownwithisRetryable: false, not as a retryablenetworkerror. -
setAttributesrejects booleans on both platforms with anArgumentError(iOS silently coerced them to1/0, Android threw). -
diagnosticsandimplicitPaywallsare shared broadcast streams, so a second listener's cancel no longer tears down the first. -
Dart SDK floor is now
^3.8.0with Flutter 3.32 or later; the unusedplugin_platform_interfacedependency is gone. -
README rewritten as a landing page. The long-form guides moved to revnix.io/docs/flutter.
-
setPushToken. Register the device push token for uninstall measurement (APNs token on iOS, FCM on Android); fire-and-forget, deduped per customer+token. (MS1) -
RevnixClient.setLocale(tag)and localized footer links. Forces everyRevnixPaywallbuilt afterwards into that language; the links element's Restore/Terms/Privacy labels now render in 43 languages. -
iOS privacy manifest. The plugin now bundles revnix-swift's
PrivacyInfo.xcprivacy(CocoaPodsrevnix_flutter_privacybundle; SwiftPM through the Revnix package) in place of the empty template, which was never bundled. (TP8) -
requestTrackingAuthorizationandconfigure(attWaitTimeout:). Show Apple's App Tracking Transparency prompt and get its status back (0–3, -1 off iOS); the answer and, when authorized, the IDFA are stored on the customer.attWaitTimeoutholds the first install report until the prompt is answered. (TP3) -
track. Report a custom in-app event (name + optional properties), recorded on the ledger ascustom.<event>. Fire-and-forget like the other beacons; not for purchases. (MS8) -
updateSkanConversionValue(value, coarse:, lockWindow:)andconfigure(skan:)(iOS only, AT10). -
logAdRevenue. Report impression-level ad revenue from your mediation SDK's paid-event callback (AdMobonPaidEvent, AppLovin MAXonAdRevenuePaid). Fire-and-forget like the other beacons. (PT8) -
setAttribution. Hand the SDK an attribution verdict your MMP (Adjust, AppsFlyer, …) already reached, from that MMP's own callback, so Revnix can credit revenue to the right network and campaign. (PT11) -
getAttribution/onAttribution. The install-attribution verdict — which channel gets credit for this install, and the campaign fields that came with it — straight from the native SDK's own record.getAttribution()is a point-in-time read;onAttributiondelivers the same verdict once the native SDK settles on it after cold-start install registration, and again whenever it later changes (de-duplicated natively). (AT11) -
getLastDeepLink. Reads the link the customer clicked most recently, straight from the native SDK's own deep-link handling, without waiting on a stream. Never throws; returns null when nothing has been recorded yet. -
resolveDeepLink. Unwraps a link an email service provider (Mailchimp, SendGrid, ...) wrapped in its own click-tracking domain, e.g.https://click.mailchimp.com/track/abcbecomescom.voigu.app://promo?utm_source=email&utm_campaign=summer50. Route on the result and pass it tohandleDeepLink; never throws, and a failure hands the inputurlback unchanged. (REV-299) -
onDeferredDeepLink/handleInstallReferrer. The link a customer clicked before installing, echoed once per install through theonDeferredDeepLinkstream — exact on Android (from the install referrer), probabilistic on iOS (same-network click within the last hour).handleInstallReferrer(referrer)hands the raw Play Install Referrer string to the native Android SDK; a no-op on iOS. (REV-299) -
On-device QR paywall preview.
PlacementResolution.previewandrevnixPreviewPlacementKeydecode a dashboard QR/link preview trigger, andRevnixPaywallrefuses to purchase for that placement key. Needs the revnix-swift / revnix-kotlin submodule pins that recognize the preview deep link and forward it onimplicitPaywalls— inert here until those land (the plugin bridges must then also forwardpreview; until then detect a preview byplacementKey). -
Device attribute contract. The native SDKs now send the device facts — platform, OS version, app version, locale, currency, storefront, model, install date, SDK version, sandbox, first open — with every placement resolve (
X-Revnix-Device), so targeting rules and audiences can use them from the first launch and the dashboard shows them on the customer asdevice.*attributes.configure(device: {…})overrides individual keys. Requires revnix-swift 0.3.0 / revnix-kotlin 0.3.0 (the submodules). (REV-268) -
Five style fields the designs use now reach the renderer.
translate,clipPath,fillSize,textWrapandfilterwere named by no property onBlockStyle, sofromJsondropped them before the renderer ever saw them.translateis now drawn: 5 of the 25 template categories centre a pinned badge withleft: 50%plustranslate: "-50% 0", and without the second half the chip sat half its own width off centre — on Flutter only, never in the dashboard preview the design was approved in.clipPath,fillSizeandfilterare decoded and reported throughonDiagnostic(clipPath not drawn,fillSize not tiled,filter not drawn) rather than silently ignored, so a design that renders approximately says so in your logs.textWrapis decoded but not reported: it moves a line break, not the design, and half the gallery sets it. -
logPaywallEvent— the six paywall interactions (selected,purchaseStarted,purchaseAbandoned,purchaseFailed,restore,error), i.e. what the customer did BETWEEN the display and the close.RevnixPaywallsends all but the purchase outcome, which only your app can see. All six are pure history: over-reporting skews a report, it never grants or revokes access.logPaywallShownnow resolves with theviewIdit minted — hold it and pass it tologPaywallClosedandlogPaywallEventso the whole life of one impression threads together. -
The selected plan is drawn from the design. Every block carries
selectedStyleandvisibility, so a plan card can change its fill, border and text when its package is the selected one, and a block can be drawn only while selected (a filled radio dot) or only while not. -
The native SDKs are git submodules (
ios/revnix_flutter/Revnix→ RevnixSDK-iOS,android/revnix-kotlin→ RevnixSDK-Android) instead of vendored copies, which had already drifted from upstream. Clone with--recurse-submodules. Both bridges now forward the placement'spaywallas the raw wire value (upstreampaywallJSON/paywallJson), so a designed paywall from a newer dashboard reaches Dart untouched. Until the package is on pub.dev, install it as a path dependency from a recursive clone: a pubspecgit:dependency does not fetch submodules. -
The Swift package's iOS floor is 16.0, matching the podspec and revnix-swift (it said 13.0).
0.2.0 #
A/B experiments (REV-219) — parity with revnix-swift 0.2.0 and
revnix-kotlin 0.2.0, whose vendored copies are updated in step.
PlacementResolution.experiment— the running experiment's sticky assignment (PlacementExperiment:key,variantId). Null when no running experiment covers the placement (or the server predates experiments); the served offering/paywall are already the variant's, so this is attribution metadata, not something to branch on.resolvePlacementnow sends the customer id (?customer=) so the server can pin a sticky variant; older servers ignore the parameter.setAttributes(Map<String, Object?>)(REV-033) — the write half of audience targeting. String/num values upsert,nulldeletes. Awaits the write and throws on failure, unlike the fire-and-forget beacons, since the nextresolvePlacementmay depend on it.email/usernameare reserved (secret key only) and a server-set attribute cannot be changed from a device; both reject the whole batch.
0.1.0 #
Initial release — feature parity with revnix-swift 0.1.0 and
revnix-kotlin 0.1.0, which this plugin bridges (vendored until they ship to
CocoaPods / Maven Central).
RevnixClient.configure/instance— publishable-key client, one per app- Entitlements: network-first
entitlements()with offline cache (stalesurvives the channel),cachedEntitlements(), fail-closedisEntitled(), read-your-writeswaitForEntitlements(seq) - Purchases:
registerPurchase(StoreKit 2 JWS proof path on iOS, purchase-token claims on Android), durable retry queue (retryPendingPurchases,pendingPurchaseCount); Play Billing acknowledgement ordering lives in the native connector - Placements:
resolvePlacementwith remote paywall config - Telemetry:
registerInstall,logPaywallShown,diagnosticsstream - Typed error taxonomy (
RevnixExceptionsubclasses) — retryable vs deliberate is preserved across the platform channel