Thursday 9 February 2023

 

  Google AdMob - Display Ads In Xamarin Forms 

(Using NUGET and Without NUGET)


In this instructional exercise I'll tell you the best way to adapt your Xamarin applications with AdMob utilizing my MTAdmob module.

To assist you with accelerating your Xamarin improvement, I've made a bunch of modules, one of them is MTAdmob. Because of this module you can add Admob pennants and Insterstitials in only couple of lines of code. It couldn't be simpler than that and I'll show you




Introduce the module

Above all else, right snap on your Xamarin arrangement and select "Oversee Nuget bundles for Arrangement"




Visual Studio will open another screen where you can look and introduce at least one nuget bundles. For this situation we can look for the MTAdmob module. Looking for MarcTron will show you every one of my bundles (I'm certain you can find other valuable modules that I've composed), and we can choose the MTAdmob module as displayed in the following picture.



t's vital that you introduce the module in your PCL/.Net standard undertaking and in your foundation projects (Android, iOS, UWP).

After the Admob module is introduced we can add flags and insterstitials to our ventures.

Add Promotions to our undertaking

MTAdmob module upholds standard, interstitials and compensated recordings for Android and iOS. In the event that you might want to see the module supporting likewise the UWP stage, let me now and I'll add the help in another rendition.

As I've said we can add Flags, Interstitials and Compensated Recordings promotions to our undertaking. We should begin with the Flags

The most effective method to add an Admob Flag

An Admob flag is only a view inside our page. It implies that we can add it utilizing XAML or C#. Most importantly we should perceive how to add an Admob flag utilizing XAML.

Add an Admob Pennant with XAML

In MTAdmob to utilize an Admob flag I've made a custom control called AdView, so to utilize it we can utilize this code:


<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:MarcTron.Plugin.Controls;assembly=Plugin.MtAdmob" x:Class="Test.MTAdmob.MainPage"> <StackLayout> <Label Text="Let's test an Admob Banner!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" /> <!-- Place the Admob controls here --> <controls:MTAdView/> </StackLayout>


In this model we have made a StackLayout with 2 controls: a mark and an AdView (our Admob flag). Simple! Isn't it???

The AdView control is fundamentally a View so you can utilize every one of the properties you can imagine like: HorizontalOptions, VerticalOptions, IsVisible…

In addition to these properties, I’ve added in AdView two other properties: AdsId and PersonalizedAds.

AdsId: Allows you to add the Banner Id (you can find it in your Admob account)

PersonalizedAds: This allow you to use non personalized ads. For example in case of GPDR. Of course it’s better to use personalized Ads.

To use these properties you can update the previous code to:

<controls:AdView PersonalizedAds="true" AdsId="xxxxxxxxxxxxxxxxxx"/>

Add an Admob Banner with C#

In case you don’t write your pages with XAML or you write your UI in C# or you want to add your view only in some cases, you can add your Admob Banner using this code:

using MarcTron.Plugin;
...
MTAdView ads = new MTAdView();

Of course you need to attach this View to your layout, but you know how to do it (If not, feel free to ask).

To use the custom properties you can change the previous code to:

...
MTAdView ads = new MTAdView();
ads.AdsId = "xxx";
ads.PersonalizedAds = true;

Also in this case, to add an Admob banner is INCREDIBILY EASY!!!

Global Custom Properties

As you have seen, the properties AdsId and PersonalizedAds belong to a single AdView. It means that you have to set them for every Admob Banner.

To make things even easier I’ve added the option to set these properties only once. To do so, you can use this C# code:

CrossMTAdmob.Current.UserPersonalizedAds = true;
CrossMTAdmob.Current.AdsId = "xxxxxxxxxxxxxxxx";

In this case all your Admob banner will show personalized ads and will have the same Id. 

If you set local and global properties, the local ones will have higher priority.

Use of Banner Events

I’ve added 4 events to the Admob banner that you could find nice to have. These events are:

  • AdsClicked When a user clicks on the ads
  • AdsClosed When the user closes the ads
  • AdsImpression Called when an impression is recorded for an ad.
  • AdsOpened When the ads is opened

To use these events you can write this code:

AdView myAds = new AdView();
myAds.AdsClicked += MyAdsAdsClicked;
myAds.AdsClosed += MyAds_AdVClosed;
myAds.AdsImpression += MyAds_AdVImpression;
myAds.AdsOpened += MyAds_AdVOpened;

Of course you can use these events also if you have declared your AdView in your XAML code.

Admob Interstitials

Now that we know how to add Admob banners using my plugin MTAdmob, let’s see how we can add Admob Interstitials. If possible, to add an Admob interstitial is even easier. You just need a single line of code. Don’t you believe me? Look here how to show an Admob interstitial:

CrossMTAdmob.Current.ShowInterstitial("ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");

I told you!!! That’s it!!! With that line of code you have just showed an Interstitial in you app. Of course you need to replace that string with the Insterstitial ID you can find in your Admob account.

Events for Interstitials

There 3 events that you can use with Interstitials:

OnInterstitialLoaded        When it's loaded
OnInterstitialOpened        When it's opened      
OnInterstitialClosed        When it's closed

Rewarded Video

From version 1.1 the plugin supports the amazing Rewarded Video too.

To show a rewarded video you just need a single line of code:

CrossMTAdmob.Current.ShowRewardedVideo("xx-xxx-xxx-xxxxxxxxxxxxxxxxx/xxxxxxxxxx");

Events for Rewarded videos

There are 7 events that you can use with the Rewarded video Ads:

OnRewarded                          When the user gets a reward
OnRewardedVideoAdClosed             When the ads is closed
OnRewardedVideoAdFailedToLoad       When the ads fails to load
OnRewardedVideoAdLeftApplication    When the users leaves the application
OnRewardedVideoAdLoaded             When the ads is loaded
OnRewardedVideoAdOpened             When the ads is opened
OnRewardedVideoStarted              When the ads starts

Initialization

Before you can use the Admob banners and Interstitials, you need to initialize it. 

You need to do it only once so it makes sense to initialize it in the OnCreate method in Android and FinishedLaunching in iOS.

In your Android project add this line in your OnCreate method:

 MobileAds.Initialize(this);

Remeber to add this to your AppManifest:

<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID"
           android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>

In your iOS project add this line in your FinishedLaunching method:

MobileAds.SharedInstance.Start(CompletionHandler);

private void CompletionHandler(InitializationStatus status){}

On iOS you need to add to your Info.plist file this:

	<key>GADApplicationIdentifier</key>
	<string>YOUR APP ID</string>
	<key>GADIsAdManagerApp</key>
	<true/>

IMPORTANT:  If you receive errors compiling the code for iOS, install the package Xamarin.Google.iOS.MobileAds in your iOS project.


This Admob MTAdmob plugin is incredibly easy to use but in case you need help, or you want to suggest a new feature or for any other reason, write me.

This plugin is free of charge and you may use it as you like, but regardless of your situation and usage, I won’t be held responsible of any loss.

It’s your responsibility to comply with every regulation around the word needed to show personalized and not personalized ads to the user.



----------------------------------------------------------------------------------------------------------------------------
Now If we want to be using Custom Renderers  -- NO NUGET 

A banner Ad is like a ribbon. This is selected if our requirement is to provide an ad at the footer or at header part, this does not cover the entire region of the Page. It only uses a portion of the app page.

Interstitial Ads cover the entire page with the ad, so mostly this is displayed as a popup. This process is the same for displaying rewarded type ads.

Requirements

We need “App Id” and “Unit Id”, which are created in “AdMob by Google” available on this website,

  • https://code.msdn.microsoft.com/Google-AdMob-in-Xamarinform-cd500224/https://www.google.com/admob/.

To create these follow the tutorial available here:

  • @https://code.msdn.microsoft.com/Google-AdMob-in-Xamarinform-cd500224/https://code.msdn.microsoft.com/Google-AdMob-in-Xamarinform-cd500224/
  • Or @http://allsoftwaredevelopments.blogspot.com/2018/09/google-admob-mobile-development_4.html
  • Or @https://www.c-sharpcorner.com/article/getting-started-with-google-admob/

Steps in Brief,

  • Adding required packages.
  • Changes to be done in Manifest.xml file(only for Android)
  • Creating Custom Renders to access Ads for Banner type Ads.
  • Accessing Custom Renders in the code to display Banner type Ads.
  • Creating Dependency Services to access Ads for Interstitial type Ads.
  • Accessing Dependency Services in the code to display Interstitial type Ads.

Steps in Detail,

Adding required packages

Here, we are using Custom Renders so the packages are to be added in Xamarin.Android and Xamarin.iOS folders only. There is no need to add any package in PCL folder.

  1. For Android
    Add “Xamarin.GooglePlayServices.Ads” package.

  2. For iOS
    Add “Xamarin.Firebase.iOS.AdMob” Package

Changes to be done in Manifest.xml file (only for Android)

Add Permissions for "INTERNET" and "ACCESS_NETWORK_STATE" and then add the following lines in the Manifest.xml file in Project->Android->Properties folder.

<?xml version="1.0" encoding="utf-8"?>  

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.AdMob">  

    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="27" />  

    <uses-permission android:name="android.permission.INTERNET" />  

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  

    <application android:label="AdMob.Android">  

        <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />  

    </application>  

</manifest>  



Creating Custom Renders to access Banner type Ads

In PCL,

While showing the Banner ad we have to set the size also. For this purpose we have to use custom renders as we can add nuget packages for AdMob by Google in native folders only.

Different sizes of banners available are,

Size in dp (WxH)DescriptionAvailabilityAdSize constant
320x50Standard BannerPhones and TabletsBANNER
320x100Large BannerPhones and TabletsLARGE_BANNER
300x250IAB Medium RectanglePhones and TabletsMEDIUM_RECTANGLE
468x60IAB Full-Size BannerTabletsFULL_BANNER
728x90IAB LeaderboardTabletsLEADERBOARD
Screen width x 32|50|90Smart BannerPhones and TabletsSMART_BANNER

Now in PCL add the following class with name AdBanner.cs

using System;  

using Xamarin.Forms;  

  

namespace AdMob.CustomRenders  

{  

    public class AdBanner : View  

    {  

        public enum Sizes { Standardbanner, LargeBanner, MediumRectangle, FullBanner, Leaderboard, SmartBannerPortrait }  

        public Sizes Size { get; set; }  

        public AdBanner()  

        {  

            this.BackgroundColor = Color.Accent;  

        }  

    }  

}  


In Android.

In Android we have to add the following class to create a view and use it in PCL with CustomRenders concept, let us create it here with name AdBanner_Droid.cs

using System;  

using AdMob;  

using Android.Gms.Ads;  

using Xamarin.Forms;  

using Xamarin.Forms.Platform.Android;  

using AdMob.CustomRenders;  

using AdMob.Droid.CustomRenders;  

using Android.Content;  

  

[assembly: ExportRenderer(typeof(AdBanner), typeof(AdBanner_Droid))]  

namespace AdMob.Droid.CustomRenders  

{  

    public class AdBanner_Droid : ViewRenderer  

    {  

        Context context;  

        public AdBanner_Droid(Context _context) : base(_context)  

        {  

            context = _context;  

        }  

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)  

        {  

            base.OnElementChanged(e);  

            if (e.OldElement == null)  

            {  

                var adView = new AdView(Context);  

                switch ((Element as AdBanner).Size)  

                {  

                    case AdBanner.Sizes.Standardbanner:  

                        adView.AdSize = AdSize.Banner;  

                        break;  

                    case AdBanner.Sizes.LargeBanner:  

                        adView.AdSize = AdSize.LargeBanner;  

                        break;  

                    case AdBanner.Sizes.MediumRectangle:  

                        adView.AdSize = AdSize.MediumRectangle;  

                        break;  

                    case AdBanner.Sizes.FullBanner:  

                        adView.AdSize = AdSize.FullBanner;  

                        break;  

                    case AdBanner.Sizes.Leaderboard:  

                        adView.AdSize = AdSize.Leaderboard;  

                        break;  

                    case AdBanner.Sizes.SmartBannerPortrait:  

                        adView.AdSize = AdSize.SmartBanner;  

                        break;  

                    default:  

                        adView.AdSize = AdSize.Banner;  

                        break;  

                }  

                // TODO: change this id to your admob id  

                adView.AdUnitId = "Your AdMob id";  

                var requestbuilder = new AdRequest.Builder();  

                adView.LoadAd(requestbuilder.Build());  

                SetNativeControl(adView);  

            }  

        }  

    }  

}  


At this line adView.AdUnitId = "Your Ad Unit id";

We have to place our AdMob Banner unit id.


In iOS,


In iOS we have to add the following class to create a view and use it in PCL with CustomRenders concept, let us create it here with name AdBanner_iOS.cs


using System;  

using AdMob.CustomRenders;  

using AdMob.iOS.CustomRenders;  

using CoreGraphics;  

using Google.MobileAds;  

using UIKit;  

using Xamarin.Forms;  

using Xamarin.Forms.Platform.iOS;  

//using GoogleAdMobAds;  

  

  

  

[assembly: ExportRenderer(typeof(AdBanner), typeof(AdBanner_iOS))]  

namespace AdMob.iOS.CustomRenders  

{  

    public class AdBanner_iOS : ViewRenderer  

    {  

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)  

        {  

            base.OnElementChanged(e);  

  

            if (e.OldElement == null)  

            {  

                BannerView bannerView = null;  

  

                switch ((Element as AdBanner).Size)  

                {  

                    case AdBanner.Sizes.Standardbanner:  

                        bannerView = new BannerView(AdSizeCons.Banner, new CGPoint(0, 0));  

                        break;  

                    case AdBanner.Sizes.LargeBanner:  

                        bannerView = new BannerView(AdSizeCons.LargeBanner, new CGPoint(0, 0));  

                        break;  

                    case AdBanner.Sizes.MediumRectangle:  

                        bannerView = new BannerView(AdSizeCons.MediumRectangle, new CGPoint(0, 0));  

                        break;  

                    case AdBanner.Sizes.FullBanner:  

                        bannerView = new BannerView(AdSizeCons.FullBanner, new CGPoint(0, 0));  

                        break;  

                    case AdBanner.Sizes.Leaderboard:  

                        bannerView = new BannerView(AdSizeCons.Leaderboard, new CGPoint(0, 0));  

                        break;  

                    case AdBanner.Sizes.SmartBannerPortrait:  

                        bannerView = new BannerView(AdSizeCons.SmartBannerPortrait, new CGPoint(0, 0));  

                        break;  

                    default:  

                        bannerView = new BannerView(AdSizeCons.Banner, new CGPoint(0, 0));  

                        break;  

                }  

  

                // TODO: change this id to your admob id  

                bannerView.AdUnitID = "Your AdMob Banner Ad Unit id";  

                foreach (UIWindow uiWindow in UIApplication.SharedApplication.Windows)  

                {  

                    if (uiWindow.RootViewController != null)  

                    {  

                        bannerView.RootViewController = uiWindow.RootViewController;  

                    }  

                }  

                var request = Request.GetDefaultRequest();  

                bannerView.LoadRequest(request);  

                SetNativeControl(bannerView);  

            }  

  

        }  

  

    }  

}  



At this line adView.AdUnitId = "Your Ad Unit id";


We have to place our AdMob Banner unit id.

Accessing Custom Renders to Display Banner Type Ads

Now, the only task remaining in our current tutorial is using the created custom renders in our code.

UI design code in XAML, for examlple in BannerAdPage.xaml

Here, we have to create a local object as in the following code and call the custom render as <local:AdBanner />


<?xml version="1.0" encoding="UTF-8"?>  

<ContentPage   

    xmlns="http://xamarin.com/schemas/2014/forms"   

    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"   

    xmlns:local="clr-namespace:AdMob.CustomRenders;assembly=AdMob"  

    x:Class="AdMob.Views.BannerAdPage">  

  

    <ContentPage.Padding>  

        <OnPlatform x:TypeArguments="Thickness">  

            <On Platform="iOS" Value="0,20,0,0"/>  

            <On Platform="Android" Value="0,0,0,0"/>  

            <On Platform="WinPhone" Value="0,0,0,0"/>  

        </OnPlatform>  

    </ContentPage.Padding>  

      

    <ContentPage.Content>  

        <StackLayout x:Name="stackLayout" BackgroundColor="Yellow" VerticalOptions="FillAndExpand" Padding="0,0,0,0">  

            <Label Text="Banner Advertisement" HorizontalOptions="CenterAndExpand" TextColor="Green" FontSize="25" />  

            <local:AdBanner Size="Standardbanner" VerticalOptions="EndAndExpand"/>  

        </StackLayout>  

    </ContentPage.Content>  

      

</ContentPage> 


The Banner type ad is displayed at the bottom of the page, and this can be placed anywhere in the page. For this tutorial I have placed it at the lower/footer part of the page.

Creating Dependency Services to access Interstitial type Ads

In PCL

Unlike Banner Ads, Interstitial Ads have only one kind of size; i.e., the full page of the application. We can show a popup to display our ad, but the popup is not created by us. It is done by the installed SDK itself. We only have to call the popup to appear when required, suppose on a button click here.

Now in PCL add the following Interface, for example, assume name IAdInterstitial.cs

using System;  

namespace AdMob.DependencyServices  

{  

    public interface IAdInterstitial  

    {  

        void ShowAd();  

    }  

}


In Android
In Android add the following class , Assume AdInterstitial_Droid.cs


using System;  

using AdMob.DependencyServices;  

using AdMob.Droid.DependencyServices;  

using Android.Gms.Ads;  

using Xamarin.Forms;  

  

[assembly: Dependency(typeof(AdInterstitial_Droid))]  

namespace AdMob.Droid.DependencyServices  

{  

    public class AdInterstitial_Droid : IAdInterstitial  

    {  

        InterstitialAd interstitialAd;  

  

        public AdInterstitial_Droid()  

        {  

            interstitialAd = new InterstitialAd(Android.App.Application.Context);  

  

            // TODO: change this id to your admob id  

            interstitialAd.AdUnitId = "Your AdMob id";  

            LoadAd();  

        }  

  

        void LoadAd()  

        {  

            var requestbuilder = new AdRequest.Builder();  

            interstitialAd.LoadAd(requestbuilder.Build());  

        }  

  

        public void ShowAd()  

        {  

            if (interstitialAd.IsLoaded)  

                interstitialAd.Show();  

  

            LoadAd();  

        }  

    }  


At this line adView.AdUnitId = "Your Interstitial AdMob Unit id";

We have to place our Your Interstitial AdMob Unit id.


In iOS
In iOS add the following class, Assume AdInterstitial_iOS.cs


using System;    

using AdMob.DependencyServices;    

using AdMob.iOS.DependencyServices;    

using Google.MobileAds;    

using UIKit;    

using Xamarin.Forms;    

    

[assembly: Dependency(typeof(AdInterstitial_iOS))]    

namespace AdMob.iOS.DependencyServices    

{    

    public class AdInterstitial_iOS : IAdInterstitial    

   {    

       Interstitial interstitial;    

    

        public AdInterstitial_iOS()    

        {    

            LoadAd();    

            interstitial.ScreenDismissed += (s, e) => LoadAd();    

        }    

    

        void LoadAd()    

        {    

            // TODO: change this id to your admob id    

            interstitial = new Interstitial("Your AdMob Interstitial Ad Unit id");    

    

            var request = Request.GetDefaultRequest();    

            request.TestDevices = new string[] {"Your Test Device ID", "GADSimulator" };    

            interstitial.LoadRequest(request);    

        }    

    

        public void ShowAd()    

        {    

            if (interstitial.IsReady)    

            {    

                var viewController = GetVisibleViewController();    

                interstitial.PresentFromRootViewController(viewController);    

            }    

        }    

        UIViewController GetVisibleViewController()    

        {    

            var rootController = UIApplication.SharedApplication.KeyWindow.RootViewController;    

    

            if (rootController.PresentedViewController == null)    

                return rootController;    

    

            if (rootController.PresentedViewController is UINavigationController)    

            {    

                return ((UINavigationController)rootController.PresentedViewController).VisibleViewController;    

            }    

    

            if (rootController.PresentedViewController is UITabBarController)    

            {    

                return ((UITabBarController)rootController.PresentedViewController).SelectedViewController;    

            }    

    

            return rootController.PresentedViewController;    

        }    

    }    

}  


  1. At this line adView.AdUnitId = "Your Interstitial AdMob Unit id";

    We have to place our Your Interstitial AdMob Unit id.

Note
To generate Interstitial Ad in iOS for testing purposes we have to add the following line with an array of test device ID's or else you won't get an ad to display.

request.TestDevices = new string[] {"Your Test Device ID""GADSimulator" };

For either simulator or for the physical device to test in debug mode we have to submit the device ID, and the above-presented line is to be removed while submitting the app in release mode.

To get the Device Id

  1. First, fill the entire code using the empty string for device Id.
  2. Allow it to run.
  3. Now click the button to open Interstitial Ad.
  4. Then Observe the Application Output console of IDE for the following line

    "<Google> To get test ads on this device, call: request.testDevices = @[ @"07*******************************89" ];"

  5. "07*******************************89" this will be your device Id. Copy this.
  6. Instead of empty string now paste the above Id and now run the program.
    For Simulators the device Id need not be a number/numeric value It can also be a text like "IGADSimulator" or "GAD_SIMULATOR_ID" or "Simulator" or ...

Accessing Dependency Services to Display Interstitial type Ads :

UI design code in XAML, for example, in "BannerAdPage.xaml and we have to open the Interstitial Ad on button Click. So the button click event is handled in the backed page of the UI created for example in "BannerAdPage.xaml.cs".

In BannerAdPage.xaml

<?xml version="1.0" encoding="UTF-8"?>  

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="AdMob.Views.InterstitialAdPage">  

  

    <ContentPage.Padding>  

        <OnPlatform x:TypeArguments="Thickness">  

            <On Platform="iOS" Value="0,20,0,0"/>  

            <On Platform="Android" Value="0,0,0,0"/>  

            <On Platform="WinPhone" Value="0,0,0,0"/>  

        </OnPlatform>  

    </ContentPage.Padding>  

      

    <ContentPage.Content>  

        <StackLayout x:Name="stackLayout" VerticalOptions="FillAndExpand" Padding="0,0,0,0">  

            <Label Text="Interstitial Advertisements" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="White" />  

            <StackLayout VerticalOptions="CenterAndExpand" Padding="40,0,40,0">  

                <Button Text="Interstitial" HorizontalOptions="FillAndExpand" TextColor="Blue"  BackgroundColor="White" Clicked="InterstitialAdShowClick"/>  

            </StackLayout>  

        </StackLayout>  

    </ContentPage.Content>  

</ContentPage> 


In BannerAdPage.xaml.cs


using System;  

using System.Collections.Generic;  

using AdMob.DependencyServices;  

using Xamarin.Forms;  

  

namespace AdMob.Views  

{  

    public partial class InterstitialAdPage : ContentPage  

    {  

        public InterstitialAdPage()  

        {  

            InitializeComponent();  

        }  

  

        void InterstitialAdShowClick(object sender, EventArgs e)  

        {  

            DependencyService.Get<IAdInterstitial>().ShowAd();  

        }  

    }  

To open the Interstitial Ad you have to click the button.

Result - Banner Type Ad



Interstitial Type Ad




Conclusion

This is how to create an ad in Xamarin.Forms using AdMob by Google.

References










No comments:

Post a Comment

All About .NET MAUI

  What’s .NET MAUI? .NET MAUI (.NET Multi-platform App UI) is a framework for building modern, multi-platform, natively compiled iOS, Androi...

Ads2