如何在 Xamarin Forms IOS 中实施 AdMob 原生广告?

时间:2021-01-11 10:34:39

标签: xamarin xamarin.forms xamarin.ios admob renderer

我有一个 Xamarin Forms 应用程序,我可以在其中使用 Google AdMob NuGet 通过自定义渲染器成功地为 android 添加横幅广告和原生广告。我在这里试图实现的是让它们在 IOS 上工作,我设法用横幅做到了(我想是因为我正在接收测试广告),但是当涉及到原生广告时,我得到了统一的原生广告,它从不呈现...

我在自定义列表视图数据模板中使用它,我认为它可能会导致问题,所以我尝试在页面本身中使用它,但没有运气,同样的问题。

到目前为止,这是我的 IOS 渲染器:

[assembly: ExportRenderer(typeof(NativeAdMobUnit), typeof(NativeAdMobUnitRenderer))]
namespace Example.iOS.Components
{
    public class NativeAdMobUnitRenderer : ViewRenderer<NativeAdMobUnit, NativeExpressAdView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<NativeAdMobUnit> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement == null)
                return;

            if (e.OldElement == null)
            {
               
                CreateAdView(this, e.NewElement.AdUnitId);
            }
        }
        private void CreateAdView(NativeAdMobUnitRenderer renderer,String AdUnitId)
        {

            if (Element == null) return;

            var loader = new AdLoader(
               AdUnitId,
                GetVisibleViewController(),
                new AdLoaderAdType[] { AdLoaderAdType.UnifiedNative },
                new AdLoaderOptions[] {
                    new NativeAdViewAdOptions {PreferredAdChoicesPosition = AdChoicesPosition.TopRightCorner}
                });

            var request = Request.GetDefaultRequest();
            request.TestDevices = new string[] { Request.SimulatorId };

         
            try
            {
                loader.Delegate = new MyAdLoaderDelegate(renderer);
                Device.BeginInvokeOnMainThread(() => {
                    loader.LoadRequest(Request.GetDefaultRequest());
                });
            }
            catch(Exception ex) 
            { 
            }
        }

        private UIViewController GetVisibleViewController()
        {
            var windows = UIApplication.SharedApplication.Windows;
            foreach (var window in windows)
            {
                if (window.RootViewController != null)
                {
                    return window.RootViewController;
                }
            }
            return null;
        }

        private class MyAdLoaderDelegate : NSObject, IUnifiedNativeAdLoaderDelegate
        {
            private readonly NativeAdMobUnitRenderer _renderer;

            public MyAdLoaderDelegate(NativeAdMobUnitRenderer renderer)
            {
                _renderer = renderer;
            }

            public void DidReceiveUnifiedNativeAd(AdLoader adLoader, UnifiedNativeAd nativeAd)
            {
                Debug.WriteLine("DidReceiveUnifiedNativeAd");
            }
            public void DidFailToReceiveAd(AdLoader adLoader, RequestError error)
            {
                Debug.WriteLine("DidFailToReceiveAd");
            }

            public void DidFinishLoading(AdLoader adLoader)
            {
                Debug.WriteLine("DidFinishLoading");
            }
        }
    }
}

这是相同的,但对于按预期工作的 Android:

[assembly: ExportRenderer(typeof(NativeAdMobUnit), typeof(NativeAdMobUnitRenderer))]
namespace Example.Droid.Renderers
{
    public class NativeAdMobUnitRenderer : ViewRenderer
    {
        public NativeAdMobUnitRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                NativeAdMobUnit NativeAdUnit = (NativeAdMobUnit)Element;
                var adLoader = new AdLoader.Builder(Context, NativeAdUnit.AdUnitId);

                var listener = new UnifiedNativeAdLoadedListener();
                listener.OnNativeAdLoaded += (s, ad) =>
                {
                    try
                    {
                        var root = new UnifiedNativeAdView(Context);
                        var inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
                        var adView = (UnifiedNativeAdView)inflater.Inflate(Resource.Layout.ad_unified, root);

                        populateUnifiedNativeAdView(ad, adView);

                        SetNativeControl(adView);
                    }
                    catch
                    {

                    }
                };

                adLoader.ForUnifiedNativeAd(listener);
                var requestBuilder = new AdRequest.Builder();
                adLoader.Build().LoadAd(requestBuilder.Build());
            }
        }

        private void populateUnifiedNativeAdView(UnifiedNativeAd nativeAd, UnifiedNativeAdView adView)
        {
            adView.MediaView = adView.FindViewById<MediaView>(Resource.Id.ad_media);

            // Set other ad assets.
            adView.HeadlineView = adView.FindViewById<TextView>(Resource.Id.ad_headline);
            adView.BodyView = adView.FindViewById<TextView>(Resource.Id.ad_body);
            adView.CallToActionView = adView.FindViewById<TextView>(Resource.Id.ad_call_to_action);
            adView.IconView = adView.FindViewById<ImageView>(Resource.Id.ad_app_icon);
            adView.PriceView = adView.FindViewById<TextView>(Resource.Id.ad_price);
            adView.StarRatingView = adView.FindViewById<RatingBar>(Resource.Id.ad_stars);
            adView.StoreView = adView.FindViewById<TextView>(Resource.Id.ad_store);
            adView.AdvertiserView = adView.FindViewById<TextView>(Resource.Id.ad_advertiser);

            // The headline and mediaContent are guaranteed to be in every UnifiedNativeAd.
            ((TextView)adView.HeadlineView).Text = nativeAd.Headline;

            // These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
            // check before trying to display them.
            if (nativeAd.Body == null)
            {
                adView.BodyView.Visibility = ViewStates.Invisible;
            }
            else
            {
                adView.BodyView.Visibility = ViewStates.Visible;
                ((TextView)adView.BodyView).Text = nativeAd.Body;
            }

            if (nativeAd.CallToAction == null)
            {
                adView.CallToActionView.Visibility = ViewStates.Invisible;
            }
            else
            {
                adView.CallToActionView.Visibility = ViewStates.Visible;
                ((Android.Widget.Button)adView.CallToActionView).Text = nativeAd.CallToAction;
            }

            if (nativeAd.Icon == null)
            {
                adView.IconView.Visibility = ViewStates.Gone;
            }
            else
            {
                ((ImageView)adView.IconView).SetImageDrawable(nativeAd.Icon.Drawable);
                adView.IconView.Visibility = ViewStates.Visible;
            }

            if (string.IsNullOrEmpty(nativeAd.Price))
            {
                adView.PriceView.Visibility = ViewStates.Gone;
            }
            else
            {
                adView.PriceView.Visibility = ViewStates.Visible;
                ((TextView)adView.PriceView).Text = nativeAd.Price;
            }

            if (nativeAd.Store == null)
            {
                adView.StoreView.Visibility = ViewStates.Invisible;
            }
            else
            {
                adView.StoreView.Visibility = ViewStates.Visible;
                ((TextView)adView.StoreView).Text = nativeAd.Store;
            }

            if (nativeAd.StarRating == null)
            {
                adView.StarRatingView.Visibility = ViewStates.Invisible;
            }
            else
            {
                ((RatingBar)adView.StarRatingView).Rating = nativeAd.StarRating.FloatValue();
                adView.StarRatingView.Visibility = ViewStates.Visible;
            }

            if (nativeAd.Advertiser == null)
            {
                adView.AdvertiserView.Visibility = ViewStates.Invisible;
            }
            else
            {
                ((TextView)adView.AdvertiserView).Text = nativeAd.Advertiser;
                adView.AdvertiserView.Visibility = ViewStates.Visible;
            }

            adView.SetNativeAd(nativeAd);
        }
    }

    public class UnifiedNativeAdLoadedListener : AdListener, UnifiedNativeAd.IOnUnifiedNativeAdLoadedListener
    {
        public void OnUnifiedNativeAdLoaded(UnifiedNativeAd ad)
        {
            OnNativeAdLoaded?.Invoke(this, ad);
        }

        public EventHandler<UnifiedNativeAd> OnNativeAdLoaded { get; set; }
    }
}

0 个答案:

没有答案