init static method

Future<AdsService> init({
  1. required AdsAdUnitIds adUnitIds,
  2. AdsRemoteConfigOptions? remoteConfig,
  3. int interstitialAfter = 3,
  4. bool isProUser()?,
  5. AdsConsentOptions? consent,
  6. AdsPolicyOptions? policy,
  7. bool? bannerEnabled,
  8. bool? interstitialEnabled,
  9. bool? nativeEnabled,
  10. bool? appOpenEnabled,
  11. bool? rewardedEnabled,
  12. bool? directInterstitialEnabled,
  13. bool adsEnabled = true,
  14. int maxRetryAttempts = 2,
  15. Duration retryBaseDelay = const Duration(seconds: 10),
  16. bool preloadEnabled = true,
  17. Duration connectivityRecheckInterval = const Duration(minutes: 3),
})

Initialize the package once.

Calling this method more than once is safe; subsequent calls are ignored by AdsService. Initialization errors are logged and do not crash the host app, because advertising should never prevent the app from opening.

Implementation

static Future<AdsService> init({
  required AdsAdUnitIds adUnitIds,
  AdsRemoteConfigOptions? remoteConfig,
  int interstitialAfter = 3,
  bool Function()? isProUser,
  AdsConsentOptions? consent,
  AdsPolicyOptions? policy,
  bool? bannerEnabled,
  bool? interstitialEnabled,
  bool? nativeEnabled,
  bool? appOpenEnabled,
  bool? rewardedEnabled,
  bool? directInterstitialEnabled,
  bool adsEnabled = true,
  int maxRetryAttempts = 2,
  Duration retryBaseDelay = const Duration(seconds: 10),
  bool preloadEnabled = true,
  Duration connectivityRecheckInterval = const Duration(minutes: 3),
}) async {
  if (AdsService.isInitialized) {
    dPrint('🔁 AdsBootstrap: already initialized, skipping');
    return AdsService.instance;
  }

  final options = remoteConfig ?? const AdsRemoteConfigOptions.disabled();

  _consentManager = null;
  AdsConsentManager? consentManager;
  final consentOptions = resolveConsentOptions(consent: consent);
  final useConsent = consent != null || !kDebugMode;
  if (useConsent) {
    consentManager = AdsConsentManager();
    _consentManager = consentManager;
    final canRequestAds = await consentManager.requestConsent(consentOptions);
    dPrint('🛡️ AdsBootstrap: consent gate allows ads = $canRequestAds');
  }

  if (policy != null) {
    try {
      await MobileAds.instance.updateRequestConfiguration(
        policy.toRequestConfiguration(),
      );
    } catch (error) {
      // Restriction configuration must not make the host app fail to open.
      // The host can observe this in its own logs and should verify native
      // setup if it occurs.
      dPrint('⚠️ AdsBootstrap: request policy could not be applied: $error');
    }
  }

  final config = adUnitIds.toConfig(
    bannerEnabled: bannerEnabled,
    interstitialEnabled: interstitialEnabled,
    nativeEnabled: nativeEnabled,
    appOpenEnabled: appOpenEnabled,
    rewardedEnabled: rewardedEnabled,
    directInterstitialEnabled: directInterstitialEnabled,
    adsEnabled: adsEnabled,
    interstitialAfter: interstitialAfter,
    maxRetryAttempts: maxRetryAttempts,
    retryBaseDelay: retryBaseDelay,
    preloadEnabled: preloadEnabled,
    connectivityRecheckInterval: connectivityRecheckInterval,
  );

  dPrint('🚀 AdsBootstrap: starting with ${config.availableAdTypes}');

  final AdsKeyProvider provider;
  if (options.enabled) {
    provider = RemoteConfigAdsKeyProvider(
      fallback: config,
      customKeys: options.keys,
      onConfigFetched: options.onFetched,
      fetchTimeout: options.fetchTimeout,
      minimumFetchInterval: options.minimumFetchInterval,
    );
    dPrint('🔥 AdsBootstrap: Remote Config enabled');
  } else {
    provider = DirectAdsKeyProvider(config);
    dPrint('📦 AdsBootstrap: using supplied IDs without Remote Config');
  }

  try {
    final service = await AdsService.initialize(
      keyProvider: provider,
      isProUser: isProUser,
      consentChecker: consentManager?.canRequestAds,
    );
    dPrint('✅ AdsBootstrap: initialization complete');
    service.dPrintDebug();
    return service;
  } catch (error, stackTrace) {
    dPrint('❌ AdsBootstrap: initialization failed: $error');
    dPrint('$stackTrace');
    // The service's safe pre-init getters keep the host app usable.
    return AdsService.instance;
  }
}