Search code examples
iosfirebaseadmobxamarin.formsrenderer

Xamarin forms and Firebase AdMob for iOS


Until few days ago, my apps were working fine until I received a message in the Output where it advises me to add the following line:

request.TestDevices = new[] { "yourtestcodeid" };

For the Xamarin Components Store, the component called Xamarin.Google.iOS.MobileAds doesn't exists any more but you have to install Firebase AdMob for iOS.

The problem is that the example is only for a natve iOS project. I've a Xamarin forms project with a generic view in the main project

public class AdMobView : ContentView {
    /// <summary>
    /// Initializes a new instance of the <see cref="AdMobView"/> class.
    /// </summary>
    public AdMobView() {
    }
}

and in the project for each platform its implementation. For iOS was:

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]
namespace WordBankEasy.iOS.Renderers {
public class AdMobRenderer : ViewRenderer {
    const string AdmobID = "ca-app-pub-yourcode";

    BannerView adView;
    BannerView adViewTableView;
    BannerView adViewWindow;
    Interstitial adInterstitial;
    bool viewOnScreen;

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

        if(e.NewElement == null)
            return;

        if(e.OldElement == null)
        {
            adView = new BannerView(
                size: AdSizeCons.SmartBannerPortrait, 
                origin: new CGPoint(0, UIScreen.MainScreen.Bounds.Size.Height - AdSizeCons.Banner.Size.Height))
            {
                AdUnitID = AdmobID,
                RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
            };

            adView.AdReceived += (sender, args) =>
            {
                if(!viewOnScreen) this.AddSubview(adView);
                viewOnScreen = true;
            };

            adView.LoadRequest(GetRequest());
            base.SetNativeControl(adView);
        }
    }

    private void AdViewWindow_AdReceived(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }

    Request GetRequest()
    {
        var request = Request.GetDefaultRequest();
        // Requests test ads on devices you specify. Your test device ID is printed to the console when
        // an ad request is made. GADBannerView automatically returns test ads when running on a
        // simulator. After you get your device ID, add it here
        request.TestDevices = new[] { "96080e40efec5229aad21b540eae6fe0" };
        return request;
    }
}
}

Now I can't view an ads but I have a new kind of error

You must set the rootViewController property of <GADBannerView: 0x12de69c50; frame = (0 617; 375 50); clipsToBounds = YES; layer = <CALayer: 0x17103da00>> before loading a request.

How can I change my code? Thank you in advance for any advice.


Solution

  • With the new component there is a little change to do in the code like that:

    if(e.OldElement == null)
    {
        UIViewController viewCtrl = null;
    
        foreach(UIWindow v in UIApplication.SharedApplication.Windows)
        {
            if (v.RootViewController != null)
            {
                viewCtrl = v.RootViewController;
            }
        }
    
        adView = new BannerView(size: AdSizeCons.Banner, origin: new CGPoint(-10, 0))
        {
            AdUnitID = AdmobID,
            RootViewController = viewCtrl
        };
    
        adView.AdReceived += (sender, args) =>
        {
            if(!viewOnScreen) this.AddSubview(adView);
            viewOnScreen = true;
        };
    
        adView.LoadRequest(GetRequest());
        base.SetNativeControl(adView);
    }