#ios #flutter #dart #admob #googlemobileads
#iOS #трепетать #дротик #admob #googlemobileads
Вопрос:
У меня есть следующее хранилище объявлений
import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:my_app/data/api/constants.dart'; class AdMobRepository { late String liveBannerAdId; late String liveInterstitualAdId; late String liveRewardedAdId; AdMobRepository() { if (Platform.isAndroid) { liveBannerAdId = Constants.androidBannedAdId; liveInterstitualAdId = Constants.androidInterstitualAdId; liveRewardedAdId = Constants.androidRewardedAdId; } else if (Platform.isIOS) { liveBannerAdId = Constants.iosBannerAdId; liveInterstitualAdId = Constants.iosInterstitualAdId; liveRewardedAdId = Constants.iosRewardedAdId; } else { liveBannerAdId = ""; liveInterstitualAdId = ""; liveRewardedAdId = ""; } } BannerAd getBannerAd({ required AdSize size, void Function(Ad, LoadAdError)? onFailedLoad, void Function(Ad)? onLoad, void Function(Ad)? onAdOpened, void Function(Ad)? onAdImpression, }) { return BannerAd( adUnitId: kReleaseMode ? liveBannerAdId : BannerAd.testAdUnitId, request: AdRequest(), size: size, listener: BannerAdListener( onAdFailedToLoad: onFailedLoad ?? onFailedLoadFallback, onAdLoaded: onLoad, onAdImpression: onAdImpression, onAdOpened: onAdOpened, ), ); } void onFailedLoadFallback(Ad ad, LoadAdError error) { ad.dispose(); } void getInterstitualAd({required void Function(LoadAdError) onFailedLoad, void Function(InterstitialAd)? onLoad}) { InterstitialAd.load( adUnitId: kReleaseMode ? liveInterstitualAdId : InterstitialAd.testAdUnitId, request: AdRequest(), adLoadCallback: InterstitialAdLoadCallback( onAdLoaded: onLoad ?? onInterstitialAdLoadedFallback, onAdFailedToLoad: onFailedLoad, ), ); } void onInterstitialAdLoadedFallback(InterstitialAd ad) { ad.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) =gt; ad.dispose(), onAdFailedToShowFullScreenContent: (ad, error) =gt; ad.dispose()); } void getRewardAd({required String userId, required void Function(LoadAdError) onFailedLoad, void Function(RewardedAd)? onLoad}) { RewardedAd.load( adUnitId: kReleaseMode ? liveRewardedAdId : RewardedAd.testAdUnitId, request: AdRequest(), rewardedAdLoadCallback: RewardedAdLoadCallback( onAdLoaded: onLoad ?? onRewardedAdLoadedFallback, onAdFailedToLoad: onFailedLoad, ), serverSideVerificationOptions: ServerSideVerificationOptions(userId: userId), ); } void onRewardedAdLoadedFallback(RewardedAd ad) { ad.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) =gt; ad.dispose(), onAdFailedToShowFullScreenContent: (ad, error) =gt; ad.dispose()); } }
И у меня есть следующий виджет для баннерной рекламы
class MyBannerAd extends StatefulWidget { const MyBannerAd(); @override _MyBannerAdState createState() =gt; _MyBannerAdState(); } class _MyBannerAdState extends Statelt;MyBannerAdgt; { late AdSize adSize; late AdMobRepository adRepository; late AnalyticsRepository analyticsRepository; bool adLoaded = false; BannerAd? anchoredBanner; @override void initState() { super.initState(); adRepository = context.readlt;AdMobRepositorygt;(); analyticsRepository = context.readlt;AnalyticsRepositorygt;(); if (SizerUtil.deviceType != DeviceType.mobile amp;amp; SizerUtil.orientation == Orientation.portrait) { adSize = AdSize.leaderboard; } else { adSize = AdSize.largeBanner; } final bannerAd = adRepository.getBannerAd( size: adSize, onFailedLoad: (ad, error) { print('banner ad failed to load: $error'); ad.dispose(); }, onLoad: (ad) { setState(() { adLoaded = true; anchoredBanner = ad as BannerAd?; }); }, onAdImpression: (_) { analyticsRepository.sendBannerAdShownEvent(); }, onAdOpened: (_) { analyticsRepository.sendBannerAdClickEvent(); }, ); bannerAd.load(); } @override void dispose() { super.dispose(); anchoredBanner?.dispose(); } @override Widget build(BuildContext context) { return BlocBuilderlt;SubscriptionBloc, SubscriptionStategt;( builder: (context, state) { final isLoaded = !adLoaded; if (isLoaded || state.hasSubscribed || anchoredBanner == null) return SizedBox.shrink(); return Container( color: Colors.transparent, width: anchoredBanner!.size.width.toDouble(), height: anchoredBanner!.size.height.toDouble(), child: Center( child: Container( color: Colors.white, child: AdWidget( ad: anchoredBanner!, ), ), ), ); }, ); } }
Но на IOS он всегда показывает тестовую рекламу. Как это может быть, если приложение построено в режиме выпуска flutter с flutter build ios --release
помощью ? Приложение в настоящее время находится на рассмотрении, и я подумал, что эти объявления перестанут быть тестовыми, когда они будут в прямом эфире в app Store.
Но Apple прислала нам следующее сообщение
Мы заметили, что ваше приложение или его скриншоты содержат тестовую рекламу. Приложения или элементы метаданных, включающие функции, предназначенные для тестирования или демонстрации, не подходят для магазина приложений.
следующие шаги
Чтобы устранить эту проблему, пожалуйста, измените свое приложение, чтобы завершить, удалить или полностью настроить все частично реализованные функции. Пожалуйста, убедитесь, что ваши скриншоты не содержат изображений демонстрационного, тестового или другого неполного контента
Итак, как мне избавиться от тестовой рекламы? Я пропустил какую-то настройку XCode или?
Я использую
flutter: 2.5.3 google_mobile_ads: ^0.13.4
И я также добавил идентификатор GADApplicationIdentifier в свой список info.plist
lt;keygt;GADApplicationIdentifierlt;/keygt; lt;stringgt;{here I have the app Id}lt;/stringgt;
И я тестирую на реальном устройстве с помощью сборки testflight
Примечание сбоку:
В настройках admob я добавил следующий тестовый IDFA
00000000-0000-0000-0000-000000000000
что, похоже, работает для тестовой рекламы на всех устройствах IOS.
Комментарии:
1. Вы установили значение 00000000-0000-0000-0000-000000000000 в настройках тестовых устройств консоли AdMob?
2. Да, я добавил его в разделе AdMob gt; Настройки gt;gt; Тестовые устройства
Ответ №1:
Оказывается, мне нужно было удалить 00000000-0000-0000-0000-000000000000 из настроек теста на admob. После этого я больше не получаю тестовые объявления, но теперь я получаю объявления в сборке релиза.
Ответ №2:
Вам не нужно вносить какие-либо изменения в код.
следующие шаги
Чтобы устранить эту проблему, пожалуйста, измените свое приложение, чтобы завершить, удалить или полностью настроить все частично реализованные функции. Пожалуйста, убедитесь, что ваши скриншоты не содержат изображений демонстрационного, тестового или другого неполного контента
Чтобы устранить вышеуказанный отказ, все, что вам нужно сделать, это удалить баннерную рекламу со своих скриншотов и снова отправить на утверждение.