Skip to content

Reward Verification APIs#6696

Merged
polmiro merged 44 commits into
mainfrom
admob-reward-verification-public-api
May 8, 2026
Merged

Reward Verification APIs#6696
polmiro merged 44 commits into
mainfrom
admob-reward-verification-public-api

Conversation

@polmiro

@polmiro polmiro commented Apr 24, 2026

Copy link
Copy Markdown
Member

Checklist

  • If applicable, unit tests
  • If applicable, create follow-up issues for purchases-android and hybrids

Motivation

Ship the first experimental AdMob reward-verification surface so apps can enable verification per loaded rewarded ad and receive a single, structured verification result after presentation, without coupling verification to loadAndTrack.

Description

  • Adds enableRewardVerification() on GoogleMobileAds.RewardedAd and RewardedInterstitialAd, delegating to RewardVerification.Setup.install(on:).
  • Adds reward-verification present overloads:
    • present(from:rewardVerificationStarted:rewardVerificationResult:)
    • present(from:placement:rewardVerificationStarted:rewardVerificationResult:)
  • Annotates both callbacks as @MainActor and documents callback timing explicitly.
  • Keeps internal outcome mapping in RewardedAds+RewardVerification.swift (Outcome -> RewardVerificationResult, internal VerifiedReward -> adapter VerifiedReward).
  • Simplifies show-time placement override behavior by applying override only in placement overloads.
  • Hardens misuse and invalid-data handling:
    • logs callback misuse warning before debug assert when verification wasn’t enabled
    • logs invalid virtual-currency amounts, asserts in debug, and falls back to .unsupportedReward
  • Public experimental types:
    • VerifiedReward (non-enum reward payload surface)
    • RewardVerificationResult (verified / failed, plus verifiedReward when present)
  • Tests updated/expanded across:
    • APISurfaceTests
    • PresentMappingTests
    • PresentRewardVerificationTests
    • RewardVerificationResultTests
    • RewardVerificationPlacementOverrideTests
    • Tests/UnitTests/Ads/RewardVerification/VerifiedRewardTests

Note

Medium Risk
Adds new experimental public APIs around rewarded-ad presentation and reward verification, plus new result types and state checks; mistakes could affect reward delivery callbacks and analytics placement attribution. Changes are scoped to the AdMob adapter and covered by new unit tests, but touch async dispatch and per-ad state/placement handling.

Overview
Introduces an experimental reward-verification API surface for AdMob rewarded formats: enableRewardVerification() on RewardedAd/RewardedInterstitialAd and new present(...) overloads that optionally emit rewardVerificationStarted and a single structured RewardVerificationResult after polling completes.

Adds public result payload types VerifiedReward and RewardVerificationResult, plus internal mapping from RevenueCat’s VerifiedReward/Outcome into the adapter types; includes new logging + debug assertions for misuse (result callback without enabling) and invalid virtual-currency amounts (assert + fallback to .unsupportedReward).

Updates tracking to allow show-time placement overrides via Tracking.setShowTimePlacement(...) (used by the new present(from:placement:...) overloads), and expands tests (including Nimble in SPM) to cover API availability, mapping, callback ordering, assertion behavior, and placement override semantics.

Reviewed by Cursor Bugbot for commit 1cb4d4f. Bugbot is set up for automated code reviews on this repo. Configure here.

@polmiro polmiro added pr:admob pr:feat A new feature labels Apr 24, 2026
@polmiro polmiro changed the title AdMob: enableRewardVerification (public API slice 1) Reward Verification APIs Apr 24, 2026
@polmiro polmiro force-pushed the admob-ssv-adapter-pipeline branch from 7736b9a to f6d079b Compare April 24, 2026 18:01
@polmiro polmiro force-pushed the admob-reward-verification-public-api branch 3 times, most recently from 6158e97 to 4cb910d Compare April 24, 2026 18:09
@polmiro polmiro requested a review from peterporfy April 24, 2026 19:16
@polmiro polmiro requested review from a team, JayShortway, ajpallares and rickvdl April 24, 2026 19:19
@polmiro polmiro force-pushed the admob-reward-verification-public-api branch from c0ed817 to 64067af Compare April 24, 2026 19:23
@polmiro

polmiro commented Apr 24, 2026

Copy link
Copy Markdown
Member Author

@RCGitBot please test

@polmiro polmiro marked this pull request as ready for review April 24, 2026 19:59
@polmiro polmiro requested a review from a team as a code owner April 24, 2026 19:59
@polmiro

polmiro commented Apr 24, 2026

Copy link
Copy Markdown
Member Author

@RCGitBot please test

@polmiro

polmiro commented Apr 24, 2026

Copy link
Copy Markdown
Member Author

@RCGitBot please test

@peterporfy peterporfy force-pushed the admob-ssv-adapter-pipeline branch from 38bdafa to c9e8e0a Compare April 28, 2026 12:36
@peterporfy

peterporfy commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

This change is part of the following stack:

Change managed by git-spice.

@peterporfy peterporfy force-pushed the admob-reward-verification-public-api branch from 6e871e7 to 988a8f2 Compare April 28, 2026 16:52
@peterporfy peterporfy force-pushed the admob-ssv-adapter-pipeline branch from c9e8e0a to b096c5e Compare April 30, 2026 09:57
@peterporfy peterporfy force-pushed the admob-ssv-adapter-pipeline branch from b096c5e to 6e4e9da Compare April 30, 2026 10:04
@peterporfy peterporfy force-pushed the admob-reward-verification-public-api branch from 988a8f2 to e1207e3 Compare April 30, 2026 10:07

@ajpallares ajpallares left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some final comments, mostly to simplify the code even further

polmiro added 3 commits May 7, 2026 14:34
Move invalid virtual-currency handling into VerifiedReward with assertion + fallback, and centralize the assertion string while simplifying mapping logic.
Make unsupportedReward the canonical public representation and remove the transient unknown naming from the adapter API surface.
Simplify handler control flow by gating state checks on a non-nil result callback and invoke `.failed` when state is unexpectedly missing so production callers receive a terminal outcome.
polmiro added 6 commits May 7, 2026 14:53
Unify the reward-earned handler into a single closure path that invokes the start callback once and handles missing verification state with a failed result while preserving debug assertions and logging.
Move RewardVerification mapping helpers next to their only call site and remove the now-redundant Present.swift file.
Remove the dedicated placement-override helper and assign the tracked placement directly at the show-time call sites to keep the flow simpler with unchanged behavior.
Drop the test that only re-validates delegate store round-tripping so the suite stays focused on show-time placement override behavior.
…tion-public-api

# Conflicts:
#	AdapterSDKs/RevenueCatAdMob/Sources/RevenueCatAdMob/RewardVerification/Strings.swift
Relocate rewarded ad reward-verification extensions from Tracking into RewardVerification and keep placement wiring in Tracking through a small show-time placement bridge.
Emit a production error log before asserting when reward verification receives a non-positive virtual currency amount, while still falling back to unsupportedReward.
@polmiro polmiro requested a review from ajpallares May 7, 2026 13:53
Emit the warning before the debug assert so callback misuse diagnostics are visible in all build configurations.

@ajpallares ajpallares left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is almost ready! I still have some comments before approval.

Also, I think the PR description is stale? E.g. Present.swift is still referenced

polmiro added 5 commits May 7, 2026 18:07
Drop the test that only validates delegate-store round-tripping and keep coverage focused on explicit nil placement override behavior.
Remove not-nil assertions that do not add value while keeping the API symbol references in place for signature coverage.
Mark rewardVerificationStarted callbacks as MainActor in public present overloads and helper signatures to make callback threading guarantees explicit and consistent.
Clarify when rewardVerificationStarted and rewardVerificationResult callbacks execute in all reward verification present overloads.
Clarify that verification starts when AdMob invokes the reward callback while keeping result timing wording implementation-agnostic.
@polmiro polmiro requested a review from ajpallares May 7, 2026 16:26

@ajpallares ajpallares left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the iterations on this! I think this is ready.

I still think we should separate the API tests from the unit tests, but we can definitely tackle that separately 👍

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 785db5c. Configure here.

Update API surface method reference annotations so tests fail if MainActor is removed from rewardVerificationStarted callback parameters.
@polmiro polmiro requested a review from ajpallares May 8, 2026 09:39
@polmiro polmiro merged commit 8e35224 into main May 8, 2026
42 checks passed
@polmiro polmiro deleted the admob-reward-verification-public-api branch May 8, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:admob pr:feat A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants