Advertisement

Solving AdMob Crashes on iOS 17.4+: A Deep Dive into MarketplaceKit and Initialization Strategies

2026-03-08

With the release of iOS 17.4, Apple introduced significant changes to the app ecosystem, particularly in the European Union, to support alternative app marketplaces. While these changes open new opportunities, they also introduced a critical compatibility issue for developers using the Google Mobile Ads SDK (AdMob), manifesting as a persistent SIGABRT crash on launch.

This article details our investigation into this issue, the root cause analysis involving the MarketplaceKit framework, and the robust solution we implemented to stabilize our application.

The Problem: Immediate Crash on Launch

Symptoms: Upon launching the application on devices running iOS 17.4 or later, the app immediately terminates with a SIGABRT signal.

Crash Stack Trace: The stack trace points directly to the Google Mobile Ads SDK, specifically within the GADMarketplaceKitSignals class:

Thread 1: signal SIGABRT
...
[GADMarketplaceKitSignals appDistributor]
...
Swift runtime failure: fatal error

Affected Environments:

  • OS Version: iOS 17.4 and higher.
  • Distribution: Most frequent in TestFlight and Ad Hoc builds; occasionally reproducible in development builds.
  • SDK Version: Prevalent in AdMob SDK versions prior to 11.x or when configuration is incomplete.

Root Cause Analysis

Our investigation identified three converging factors causing this instability:

1. MarketplaceKit Compatibility

iOS 17.4 introduced the MarketplaceKit framework to manage app distribution channels. The AdMob SDK attempts to invoke this framework internally to gather distribution signals (likely for attribution or fraud detection). Older versions of the SDK fail to handle certain edge cases—such as specific return values or permission states in TestFlight environments—triggering a fatal error within the Swift runtime.

2. Initialization Timing Conflict

The default integration guide for AdMob suggests initializing the SDK in application:didFinishLaunchingWithOptions:. However, on iOS 17.4+, system environments (including MarketplaceKit) may not be fully initialized at this early stage. This creates a race condition where the SDK attempts to access system services that are not yet ready, or conflicts with the initialization threads of game engines (like Cocos2d-x or Unity), increasing the likelihood of a crash.

3. Missing Configuration

By default, the AdMob SDK enables "App Measurement," which automatically runs at launch. If the Info.plist lacks the necessary SKAdNetworkItems configuration, or if automatic initialization isn't explicitly disabled, the SDK begins performing sensitive operations before the developer's code has control, hitting the MarketplaceKit issue before any mitigation logic can run.

The Solution: A Three-Layered Approach

To resolve this, we implemented a "Disable + Upgrade + Delay" strategy that addresses the issue at the configuration, dependency, and code levels.

1. Configuration Layer: Disable Automatic Initialization

We explicitly prohibit the AdMob and UMP (User Messaging Platform) SDKs from running automatically at launch. This ensures the SDK remains dormant until we decide it is safe to initialize.

Add the following keys to your Info.plist:

<key>GADDelayAppMeasurementInit</key>
<true/>
<key>UMPDelayAppMeasurementInit</key>
<true/>

Additionally, ensure your SKAdNetworkItems are fully populated with Google's and other networks' IDs to prevent exceptions caused by missing configuration.

2. Dependency Layer: Upgrade SDK

We enforce the use of the latest SDK version which officially supports iOS 17.4+.

Podfile Update:

# Force latest major version
pod 'Google-Mobile-Ads-SDK', '~> 13.0'
# Explicitly include UMP dependency
pod 'GoogleUserMessagingPlatform', '~> 2.1'

Note: Always check the Google Mobile Ads SDK Release Notes for the latest stable version.

3. Code Layer: Manual Delayed Initialization

We moved the initialization logic out of the AppDelegate (app launch phase) and into the ViewController (view presentation phase), adding a safety buffer.

Old Approach (Remove from AppDelegate.mm):

// REMOVE THIS
// [[GADMobileAds sharedInstance] startWithCompletionHandler:nil];

New Approach (Add to ViewController.mm): In the viewDidAppear: lifecycle method, we use dispatch_after to delay initialization by 1 second. This allows the system frameworks and the main UI runloop to settle before the heavy lifting of the Ads SDK begins.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    // Delay AdMob initialization by 1 second
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[GADMobileAds sharedInstance] startWithCompletionHandler:^(GADInitializationStatus * _Nonnull status) {
            NSLog(@"AdMob SDK initialized successfully.");
            // Signal to your game engine or ad manager that ads are ready
        }];
    });
}

For game engines like Cocos2d-x, we also added a corresponding delay to the showHomeBanner call to ensure the native SDK is fully ready before the game logic requests an ad.

Verification

After applying these fixes, we conducted extensive testing:

  • Simulator: Verified on iPhone 15 Pro (iOS 17.4+ simulator runtime).
  • Real Device: Verified on iPhone devices running iOS 17.4 and 17.5 via TestFlight.

Result: The application launches successfully without any SIGABRT crashes. The AdMob SDK initializes correctly after the 1-second delay, and banner/interstitial ads load and display as expected.

By controlling the initialization timing and ensuring dependency compatibility, we successfully mitigated the instability introduced by the new iOS system framework.

Advertisement