Skip to content

Feature / Add host-owned offer view controllers - #9

Open
levochkaa wants to merge 2 commits into
EncoreKit:mainfrom
artworkout-team:feature/host-owned-offer-view-controller
Open

Feature / Add host-owned offer view controllers#9
levochkaa wants to merge 2 commits into
EncoreKit:mainfrom
artworkout-team:feature/host-owned-offer-view-controller

Conversation

@levochkaa

Copy link
Copy Markdown

Context

PlacementBuilder.show() owns presentation through Encore's overlay window. Publishers that already coordinate a UIKit navigation flow cannot currently push Encore as one screen in that flow or decide how the controller should be removed when the offer resolves.

This is especially limiting for chained onboarding, reward, and post-action flows where the next screen should be pushed before the previous controller is removed from the navigation stack.

API

let viewController = await Encore.shared
    .placement("streak_complete")
    .useCase(.rewardUsers)
    .makeViewController { result in
        // Update the host navigation flow from the terminal result.
    }

if let viewController {
    navigationController.pushViewController(viewController, animated: true)
}

Changes

  • Add makeViewController() and makeViewController(resume:) to PlacementBuilderProtocol.
  • Build the controller through the same placement gates, remote configuration, offer loading, IAP, analytics, and terminal outcome pipeline used by show().
  • Return nil for placements that cannot be built while still delivering the corresponding .notPresented result to resume.
  • Render offer content directly inside a host-owned UIHostingController instead of creating an Encore window.
  • Deliver resume before automatic controller dismissal so the host can push its next screen and remove or replace the Encore controller in the same navigation update.
  • Fall back to a normal navigation pop or modal dismissal when the host leaves the controller in place.
  • Preserve duplicate-presentation protection and lifecycle visibility tracking for both Encore-managed windows and host-owned controllers.

Compatibility

  • Existing show() and show(resume:) behavior remains unchanged.
  • The package deployment target and iOS 16 presentation floor remain unchanged.
  • Existing PlacementBuilderProtocol conformers receive a default implementation for the new requirement.
  • The server-driven configuration and offer API contracts are unchanged.

Risks

  • A host should push or present a successfully returned controller promptly; retaining it without attaching it leaves that placement active until it is resolved or reconciled by a later presentation attempt.
  • Hosts with custom container controllers may need to remove the Encore controller themselves from resume; automatic dismissal handles standard navigation and modal presentation hierarchies.

levochkaa and others added 2 commits August 28, 2026 00:12
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
@levochkaa

Copy link
Copy Markdown
Author

Note for reviewers: this PR is stacked on #8 in the fork. Because the upstream repository only exposes main as a base branch, GitHub currently shows the #8 compatibility commit in this PR as well. Once #8 is merged, this PR’s diff will automatically narrow to the makeViewController changes.

@mryan-encorekit

Copy link
Copy Markdown

Appreciate this, @levochkaa. The gap is real: a publisher already driving a UIKit navigation flow has no way to make Encore one screen in it, and chained onboarding is where that hurts most. We are taking the feature.

Three notes:

  1. Agreed, this stacks on Fix / Stabilize offer UI across iOS versions #8. git diff pr8 pr9 is 6 files, all of them the new controller work, so we review it that way and it will land after Fix / Stabilize offer UI across iOS versions #8.
  2. Two API adjustments. The protocol default returns .notPresented(.notConfigured), which misreports a configured placement, so that path gets its own case. And we align resume with show(resume:), which is @escaping @Sendable.
  3. On the retained-controller risk you flagged. You were right to call it out, so we are adding a debug-build warning rather than leaving it documented only.

Good API shape, and the reasoning in the body made it easy to review. Thanks again. 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants