Overview
Encore presents a premium brand offer (a real perk a brand funds to acquire customers, such as a free trial, discount, or credit) at a moment you choose. Start with Reward Users: a reward sheet at a moment the user just earned, such as a completed purchase, a streak, or a milestone, at no cost to you. The other use case, Reduce Churn, presents offers in a cancel flow or after a paywall decline.Present an offer
The native SDK renders all offer UI natively (SwiftUI on iOS, Jetpack Compose on Android); the Flutter layer triggers presentation and receives the result.show() never throws. Every failure, including “nothing was presented”, is a value on the returned EncorePresentationResult:
- Reward Users
- Reduce Churn
EncoreUseCase.rewardUsers on every reward placement. A reward placement never runs a purchase and never falls back to the paywall sheet, so it needs no subscription product and no purchase controller. The walkthrough, including per-call copy, is the Reward Placements guide.placement() · EncorePresentationResult.
Read the result
EncorePresentationResult is a sealed pair, so Dart 3 gives you an exhaustive switch:
One presentation can claim an offer and run a purchase, so both are recorded rather than competing for one winning case.
notAttempted is a real value, meaning “the funnel was open and nothing entered it”, never null.
claim carries the offer itself:
transactionId is the one to hold on to. The brand-side completion lands later,
sometimes days later, and reaches your server through the
offer-completed webhook, which
carries the same value; credit the user once per transactionId. It is the only way to match the
result your app just received against the completion it eventually produces.
There is deliberately no SDK-computed “unlocked” verdict. What a claim means is a property of the variant flow that served it, so any projection over app-global config can contradict the flow that actually ran. Branch on the raw axes.
When nothing was presented
EncoreNotPresented is not a synonym for failure:
Run your fallback for all of them, and log only the
error case.
Purchases
This section applies to Reduce Churn placements only. A reward placement never runs a purchase, so an app that presents only reward placements can skip it. A user who accepts an offer that carries an in-app purchase triggers your registeredEncorePurchaseController. It is registered at configure; see Configure the SDK.
Observe outcomes globally
For analytics forwarding, app-owned state, or a debug overlay, listen to the outcomes stream. It is multicast, so several listeners can subscribe at once.Full example: cancel flow
Bring users back to finish their gift
Put a Claim Reminder on your home tab. It stays hidden until the user claims a gift, then reminds them to finish. Once they do, it thanks them or steps aside. Encore manages that. You can also put a Gifts Button on your reward screen, so users can open their gifts there whenever offers are waiting. Both need version 2.4.0 or later of the SDK. See the trigger components quickstart.Next Steps
- Reward Placements: reward a user at a moment they just earned, with copy you set per call
- Add Subscription Product: Reduce Churn only. Create a subscription product and connect it to Encore
- Integration Patterns: where the controller, the call site, and the stream each belong