Skip to content

Keep asking for a banner after one does not fill - #188

Merged
andiwand merged 1 commit into
mainfrom
keep-asking-after-a-banner-does-not-fill
Sep 1, 2026
Merged

Keep asking for a banner after one does not fill#188
andiwand merged 1 commit into
mainfrom
keep-asking-after-a-banner-does-not-fill

Conversation

@andiwand

@andiwand andiwand commented Sep 1, 2026

Copy link
Copy Markdown
Member

didFailToReceiveAdWithError hid the banner and called onNoAd, and nothing asked again for the life of the controller. The ad unit's automatic refresh only runs for a banner that is on screen — a hidden one is not — so a single refusal left the slot silent until the next document.

It is the same hole droid#643 closes on Android; this is the iOS half.

What changes

  • A failure schedules its own ask, rescheduling before each request so one that never comes back cannot end the chain and leave the slot as silent as before. The delay doubles up to the rate the unit refreshes at, so a slot that is never going to fill settles on what the sdk would have done anyway. The first ask is not shorter on purpose: the sdk throttles a burst of failed requests itself, and an ask it answers never reaches the auction.
  • A refresh that does not fill keeps the ad already on screen. Any failure used to hide the banner, including one arriving after a good ad had been served — which forfeited the rest of a live impression and, since a hidden banner is not refreshed, stopped the sdk trying again.
  • A failed load leaves a CrashManager breadcrumb, as the consent flow already does.

Notes

  • Backgrounding needs no guard: a DispatchWorkItem cannot fire while the app is suspended, so unlike the Android side this needs no pause/resume plumbing.
  • load()'s width != requestedWidth guard is deliberately bypassed by the retry, which calls bannerView.load directly — a retry wants the same width it just failed at.
  • The retry is cancelled on a fill, on the next load(), and in deinit.
  • Left alone, and the same on both platforms: a first launch with no network leaves consent undecided and reportNoAd() runs with no retry at all. That deserves its own change.

🤖 Generated with Claude Code

didFailToReceiveAdWithError hid the banner and nothing asked again for the life
of the controller. The ad unit only refreshes a banner that is on screen, and a
hidden one is not, so a single refusal left the slot silent until the next
document. It is the same hole droid#643 closes on Android; this is the iOS half.

A failure now schedules its own ask, rescheduling before each request so one
that never answers cannot end the chain, and a refresh that does not fill keeps
the ad already on screen instead of hiding a live one. A suspended app cannot
fire the work item, so backgrounding needs no guard.
@andiwand
andiwand force-pushed the keep-asking-after-a-banner-does-not-fill branch from a63577e to 2cc4050 Compare September 1, 2026 19:27
@andiwand
andiwand merged commit 81395d5 into main Sep 1, 2026
4 checks passed
@andiwand
andiwand deleted the keep-asking-after-a-banner-does-not-fill branch September 1, 2026 19:31
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.

1 participant