{"id":23355656,"url":"https://github.com/jcsawyer/Jc.AdMob.Avalonia","last_synced_at":"2025-08-23T14:31:45.812Z","repository":{"id":250867709,"uuid":"835710621","full_name":"jcsawyer/Jc.AdMob.Avalonia","owner":"jcsawyer","description":"Library to bring AdMob advertisements to Avalonia mobile projects.","archived":false,"fork":false,"pushed_at":"2025-08-16T08:18:58.000Z","size":38689,"stargazers_count":23,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-16T10:15:00.127Z","etag":null,"topics":["admob","android","avaloniaui","dotnet","ios"],"latest_commit_sha":null,"homepage":"https://jcsawyer.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcsawyer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-30T11:34:26.000Z","updated_at":"2025-08-16T08:18:27.000Z","dependencies_parsed_at":"2024-07-30T14:47:20.432Z","dependency_job_id":"a8383565-63d1-4ed3-82b6-87d2a2205dc1","html_url":"https://github.com/jcsawyer/Jc.AdMob.Avalonia","commit_stats":null,"previous_names":["jcsawyer/jc.admob.avalonia"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/jcsawyer/Jc.AdMob.Avalonia","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcsawyer%2FJc.AdMob.Avalonia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcsawyer%2FJc.AdMob.Avalonia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcsawyer%2FJc.AdMob.Avalonia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcsawyer%2FJc.AdMob.Avalonia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcsawyer","download_url":"https://codeload.github.com/jcsawyer/Jc.AdMob.Avalonia/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcsawyer%2FJc.AdMob.Avalonia/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271752100,"owners_count":24814745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admob","android","avaloniaui","dotnet","ios"],"created_at":"2024-12-21T10:00:55.295Z","updated_at":"2025-08-23T14:31:45.801Z","avatar_url":"https://github.com/jcsawyer.png","language":"C#","funding_links":[],"categories":["Libraries \u0026 Extensions"],"sub_categories":["Generic"],"readme":"# Jc.AdMob.Avalonia\n\nLibrary to bring AdMob advertisements to Avalonia mobile projects.\n\nAvalonia solution derived from [marius-bughiu/Plugin.AdMob](https://github.com/marius-bughiu/Plugin.AdMob/tree/main)\n\n---\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Usage](#usage)\n- [Preparing for Apple Privacy Manifests](#preparing-for-apple-privacy-manifests)\n- [Troubleshooting](#troubleshooting)\n- [Avalonia 12.x Migration](#avalonia-12x-migration)\n\n## Introduction\n\nJc.AdMob.Avalonia is a library to bring [Google AdMob](https://developers.google.com/admob) services to Avalonia Android and iOS projects.\n\nThe library currently supports the following ad units:\n\n|         | Consent | Banner | Interstitial | Rewarded interstitial | Rewarded | Native advanced | App open |\n| ------- | ------- | ------ | ------------ | --------------------- | -------- | --------------- | -------- |\n| Android | ✓       | ✓      | ✓            | ✓                     | ✓        | ☓               | ✓        |\n| iOS     | ✓       | ✓      | ✓            | ✓                     | ✓        | ☓               | ✓        |\n\n## Usage\n\nTo use Jc.AdMob.Avalonia you must add the `Jc.AdMob.Avalonia` package to your cross-platform project.\n\n```\ndotnet add package Jc.AdMob.Avalonia\n```\n\nFollowed by adding the Android/iOS `Jc.AdMob.Avalonia.xxx` package to the platform specific project(s).\n\n```\ndotnet add package Jc.AdMob.Avalonia.Android\ndotnet add package Jc.AdMob.Avalonia.iOS\n```\n\nThen you must register AdMob in the `CustomizeAppBuilder` method in `MainActivity.cs` and `AppDelegate.cs` for Android and iOS respectively:\n\n```c#\nprotected override AppBuilder CustomizeAppBuilder(AppBuilder builder)\n{\n    return base.CustomizeAppBuilder(builder)\n        ...\n        .UseAdMob(new AdMobOptions\n        {\n            TestDeviceIds = [],\n            TagForUnderAgeOfConsent = false,\n            TagForChildDirectedTreatment = false,\n        });\n}\n```\n\nFinally, follow the AdMob platform specific instructions in regard to configuring the application/unit ids.\n\n### iOS\n\nFor iOS projects, from `v11.13.0`, you must add the following to your csproj file to support linking with Swift system libraries:\n\n```xml\n\u003cTarget Name=\"LinkWithSwift\" DependsOnTargets=\"_ParseBundlerArguments;_DetectSdkLocations\" BeforeTargets=\"_LinkNativeExecutable\"\u003e\n    \u003cPropertyGroup\u003e\n        \u003c_SwiftPlatform Condition=\"$(RuntimeIdentifier.StartsWith('iossimulator-'))\"\u003eiphonesimulator\u003c/_SwiftPlatform\u003e\n        \u003c_SwiftPlatform Condition=\"$(RuntimeIdentifier.StartsWith('ios-'))\"\u003eiphoneos\u003c/_SwiftPlatform\u003e\n    \u003c/PropertyGroup\u003e\n    \u003cItemGroup\u003e\n        \u003c_CustomLinkFlags Include=\"-L\" /\u003e\n        \u003c_CustomLinkFlags Include=\"/usr/lib/swift\" /\u003e\n        \u003c_CustomLinkFlags Include=\"-L\" /\u003e\n        \u003c_CustomLinkFlags Include=\"$(_SdkDevPath)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/$(_SwiftPlatform)\" /\u003e\n        \u003c_CustomLinkFlags Include=\"-Wl,-rpath\" /\u003e\n        \u003c_CustomLinkFlags Include=\"-Wl,/usr/lib/swift\" /\u003e\n    \u003c/ItemGroup\u003e\n\u003c/Target\u003e\n```\n\n### Test Devices\n\nTo configure test devices, the `.UseAdMob()` method accepts a collection of test device ids.\n\n### Consent\n\nGoogle requires all publishers serving ads to EEA and UK users to use a Google-Certified Consent Management Platform (CMP).\n\nJc.AdMob.Avalonia provides a consent service using the Google User Messaging Platform (UMP) SDK.\n\n#### iOS App Transparency Tracking\n\nWhen using `NSUserTrackingUsageDescription` in your `Info.plist`, your app must present the AppTrackingTransparency (ATT) dialog to the user to enable the AdMob personalised ads.\nBy default this will be displayed after the consent dialog, but you can disable this by setting `SkipTransparencyTracking` to `true` in the `AdMobOptions`:\n\n```c#\nreturn base.CustomizeAppBuilder(builder)\n        ...\n        .UseAdMob(new AdMobOptions\n        {\n          ...\n            SkipTransparencyTracking = true,\n        });\n```\n\n#### Usage\n\nWhen using the consent service, all services are accessed via the singleton `AdMob.Current`.\n\nTo enable ads in regions where consent is required, you must show the consent dialog once consent is initialized:\n\n```c#\nAdMob.Current.Consent.OnConsentInitialized += (_, _) =\u003e AdMob.Current.Consent.ShowConsent();\n```\n\n#### Events\n\n| Event                        | Notes                                         |\n| ---------------------------- | --------------------------------------------- |\n| OnConsentInitialized         |                                               |\n| OnConsentFailedToInitialize  |                                               |\n| OnConsentFormLoaded          | iOS only - issue being investigated           |\n| OnConsentFormFailedToLoad    | iOS only - issue being investigated           |\n| OnConsentFormFailedToPresent |                                               |\n| OnConsentProvided            | User consented and ads can be shown           |\n| OnConsentFormClosed          | User consent form was displayed and dismissed |\n\n### Banners\n\n| iOS                                                           | Android                                                            |\n| ------------------------------------------------------------- | ------------------------------------------------------------------ |\n| \u003cimg alt=\"iOS Banner\" src=\"img/iOS Banner.png\" width=\"250\" /\u003e | \u003cimg alt=\"iOS Banner\" src=\"img/Android Banner.jpeg\" width=\"250\" /\u003e |\n\nThe `BannerAd` control can be added to your XAML like so:\n\n```xaml\n...\nxmlns:admob=\"https://github.com/jc-admob-avalonia\"\n...\n\n\u003cadmob:BannerAd UnitId=\"{ADMOB_UNIT_ID}\" /\u003e\n```\n\n#### Sizes\n\nThe banner can be configured with the following sizes:\n\n| AdSize          | Size                                                                                                |\n| --------------- | --------------------------------------------------------------------------------------------------- |\n| Banner          | Mobile Marketing Association (MMA) banner ad size (320x50 density-independent pixels).              |\n| FullBanner      | Interactive Advertising Bureau (IAB) full banner ad size (468x60 density-independent pixels).       |\n| Invalid         | An invalid AdSize that will cause the ad request to fail immediately.                               |\n| LargeBanner     | Large banner ad size (320x100 density-independent pixels).                                          |\n| Leaderboard     | Interactive Advertising Bureau (IAB) leaderboard ad size (728x90 density-independent pixels).       |\n| MediumRectangle | Interactive Advertising Bureau (IAB) medium rectangle ad size (300x250 density-independent pixels). |\n| WideSkyscrapper | IAB wide skyscraper ad size (160x600 density-independent pixels).                                   |\n\n\u003e Note: If the size is left unspecified, the banner will resize to fit the parent container.\n\n#### Events\n\nThe banner exposes the following events:\n\n| Event            | Notes        |\n| ---------------- | ------------ |\n| OnAdLoaded       |              |\n| OnAdFailedToLoad |              |\n| OnAdImpression   |              |\n| OnAdClicked      |              |\n| OnAdOpened       |              |\n| OnAdClosed       |              |\n| OnAdSwiped       | Android only |\n\n### Interstitial\n\n| iOS                                                                 | Android                                                                  |\n| ------------------------------------------------------------------- | ------------------------------------------------------------------------ |\n| \u003cimg alt=\"iOS Banner\" src=\"img/iOS Interstitial.png\" width=\"250\" /\u003e | \u003cimg alt=\"iOS Banner\" src=\"img/Android Interstitial.jpeg\" width=\"250\" /\u003e |\n\nInterstitial ads can be used by calling `Interstitial.Create(unitId)` on the `AdMob` singleton.\n\nThis call will load and the return the interstitial ad with an `OnAdLoaded` event once it's finished loaded. `.Show()` can then be called to display the ad.\n\n```c#\npublic ICommand ShowInterstitialAdCommand { get; }\n\npublic MainViewModel()\n{\n    ShowInterstitialAdCommand = ReactiveCommand.Create(ShowInterstitialAd);\n}\n\nprivate void ShowInterstitialAd()\n{\n    var interstitial = AdMob.Current.Interstitial.Create();\n    interstitial.OnAdLoaded += (_, _) =\u003e interstitial.Show();\n}\n```\n\n#### Android\n\nWhen using interstitial ads on Android, the `Activity` must be passed into the `.AddAdMob()` call:\n\n```c#\nprotected override AppBuilder CustomizeAppBuilder(AppBuilder builder)\n{\n    return base.CustomizeAppBuilder(builder)\n        ...\n        .UseAdMob(this, adMobOptions);\n}\n```\n\n#### Events\n\n| Event               | Notes |\n| ------------------- | ----- |\n| OnAdLoaded          |       |\n| OnAdFailedToLoad    |       |\n| OnAdPresented       |       |\n| OnAdFailedToPresent |       |\n| OnAdImpression      |       |\n| OnAdClicked         |       |\n| OnAdClosed          |       |\n\n### Rewarded Interstitial\n\n| iOS                                                                           | Android                                                                          |\n| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\n| \u003cimg alt=\"iOS Banner\" src=\"img/iOS Rewarded Interstitial.jpeg\" width=\"250\" /\u003e | \u003cimg alt=\"iOS Banner\" src=\"img/Android Rewarded Interstitial.jpg\" width=\"250\" /\u003e |\n\nInterstitial ads can be used by calling `RewardedInterstitial.Create(unitId)` on the `AdMob` singleton.\n\nThis call will load and the return the interstitial ad with an `OnAdLoaded` event once it's finished loaded. `.Show()` can then be called to display the ad.\n\nThe reward event `OnUserEarnedReward` can then be used to know when a reward can be given to the user.\n\n```c#\npublic ICommand ShowRewardedInterstitialAdCommand { get; }\n\npublic MainViewModel()\n{\n    ShowRewardedInterstitialAdCommand = ReactiveCommand.Create(ShowRewardedInterstitialAd);\n}\n\nprivate void ShowRewardedInterstitialAd()\n{\n    var rewardedInterstitial = AdMob.Current.RewardedInterstitial.Create();\n    rewardedInterstitial.OnAdLoaded += (_, _) =\u003e rewardedInterstitial.Show();\n    rewardedInterstitial.OnUserEarnedReward += (_, reward) =\u003e Debug.WriteLine($\"User earned reward: {reward.Amount} {reward.Type}\");\n}\n```\n\n#### Android\n\nWhen using interstitial ads on Android, the `Activity` must be passed into the `.AddAdMob()` call:\n\n```c#\nprotected override AppBuilder CustomizeAppBuilder(AppBuilder builder)\n{\n    return base.CustomizeAppBuilder(builder)\n        ...\n        .UseAdMob(this, adMobOptions);\n}\n```\n\n#### Events\n\n| Event               | Notes                          |\n| ------------------- | ------------------------------ |\n| OnAdLoaded          |                                |\n| OnAdFailedToLoad    |                                |\n| OnAdPresented       |                                |\n| OnAdFailedToPresent |                                |\n| OnAdImpression      |                                |\n| OnAdClicked         |                                |\n| OnAdClosed          |                                |\n| OnUserEarnedReward  | Contains a `RewardItem` record |\n\n#### RewardItem\n\nThe reward item record is comprised of the following properties:\n\n| Property | Description                |\n| -------- | -------------------------- |\n| Amount   | The amount rewarded.       |\n| Type     | The type of reward earned. |\n\n### Rewarded\n\n| iOS                                                                           | Android                                                                          |\n| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\n| \u003cimg alt=\"iOS Banner\" src=\"img/iOS Rewarded Interstitial.jpeg\" width=\"250\" /\u003e | \u003cimg alt=\"iOS Banner\" src=\"img/Android Rewarded Interstitial.jpg\" width=\"250\" /\u003e |\n\nInterstitial ads can be used by calling `Rewarded.Create(unitId)` on the `AdMob` singleton.\n\nThis call will load and the return the interstitial ad with an `OnAdLoaded` event once it's finished loaded. `.Show()` can then be called to display the ad.\n\nThe reward event `OnUserEarnedReward` can then be used to know when a reward can be given to the user.\n\n```c#\npublic ICommand ShowRewardedAdCommand { get; }\n\npublic MainViewModel()\n{\n    ShowRewardedAdCommand = ReactiveCommand.Create(ShowRewardedAd);\n}\n\nprivate void ShowRewardedAd()\n{\n    var rewarded = AdMob.Current.Rewarded.Create();\n    rewarded.OnAdLoaded += (_, _) =\u003e rewarded.Show();\n    rewarded.OnUserEarnedReward += (_, reward) =\u003e Debug.WriteLine($\"User earned reward: {reward.Amount} {reward.Type}\");\n}\n```\n\n#### Android\n\nWhen using rewarded ads on Android, the `Activity` must be passed into the `.AddAdMob()` call:\n\n```c#\nprotected override AppBuilder CustomizeAppBuilder(AppBuilder builder)\n{\n    return base.CustomizeAppBuilder(builder)\n        ...\n        .UseAdMob(this, adMobOptions);\n}\n```\n\n#### Events\n\n| Event               | Notes                          |\n| ------------------- | ------------------------------ |\n| OnAdLoaded          |                                |\n| OnAdFailedToLoad    |                                |\n| OnAdPresented       |                                |\n| OnAdFailedToPresent |                                |\n| OnAdImpression      |                                |\n| OnAdClicked         |                                |\n| OnAdClosed          |                                |\n| OnUserEarnedReward  | Contains a `RewardItem` record |\n\n### App Open\n\n| iOS                                                             | Android                                                             |\n| --------------------------------------------------------------- | ------------------------------------------------------------------- |\n| \u003cimg alt=\"iOS Banner\" src=\"img/iOS App Open.png\" width=\"250\" /\u003e | \u003cimg alt=\"iOS Banner\" src=\"img/Android App Open.jpg\" width=\"250\" /\u003e |\n\nApp Open ads can be used by calling `AppOpen.Create(unitId)` on the `AdMob` singleton.\n\nThis call will load and the return the app load ad with an `OnAdLoaded` event once it's finished loaded. `.Show()` can then be called to display the ad.\n\n```c#\npublic ICommand ShowAppOpenAdCommand { get; }\n\npublic MainViewModel()\n{\n    ShowAppOpenAdCommand = ReactiveCommand.Create(ShowAppOpenAd);\n}\n\nprivate void ShowAppOpenAd()\n{\n    var appOpenAd = AdMob.Current.AppOpen.Create();\n    appOpenAd.OnAdLoaded += (_, _) =\u003e appOpenAd.Show();\n}\n```\n\n#### Android\n\nWhen using app open ads on Android, the `Activity` must be passed into the `.AddAdMob()` call:\n\n```c#\nprotected override AppBuilder CustomizeAppBuilder(AppBuilder builder)\n{\n    return base.CustomizeAppBuilder(builder)\n        ...\n        .UseAdMob(this, adMobOptions);\n}\n```\n\n#### Events\n\n| Event               | Notes |\n| ------------------- | ----- |\n| OnAdLoaded          |       |\n| OnAdFailedToLoad    |       |\n| OnAdPresented       |       |\n| OnAdFailedToPresent |       |\n| OnAdImpression      |       |\n| OnAdClicked         |       |\n| OnAdClosed          |       |\n\n## Preparing for Apple Privacy Manifests\n\n\u003e I have yet to get around to testing any of this, but now the library is using a different iOS native binding package, the number of frameworks it depends on is significantly lower, and it should just be a case of updating to the latest when I find the time.\n\nIn the mean time, this project leverages `NSUserDefaults` and so should just require the reason code `CA92.1`:\n\n```\n\u003cdict\u003e\n    \u003ckey\u003eNSPrivacyAccessedAPIType\u003c/key\u003e\n    \u003cstring\u003eNSPrivacyAccessedAPICategoryUserDefaults\u003c/string\u003e\n    \u003ckey\u003eNSPrivacyAccessedAPITypeReasons\u003c/key\u003e\n    \u003carray\u003e\n        \u003cstring\u003eCA92.1\u003c/string\u003e\n    \u003c/array\u003e\n\u003c/dict\u003e\n```\n\nYou can read more about the Apple Privacy Manifest [here](https://github.com/xamarin/xamarin-macios/blob/main/docs/apple-privacy-manifest.md).\n\n## Troubleshooting\n\n### The Google Mobile Ads SDK was initialized without AppMeasurement\n\nIf you receive an error similar to the following:\n\n```\nGADInvalidInitializationException Reason: The Google Mobile Ads SDK was initialized without AppMeasurement. Google AdMob publishers, follow instructions here: https://googlemobileadssdk.page.link/admob-ios-update-plist to include the AppMeasurement framework and set the -ObjC linker flag. Google Ad Manager publishers, follow instructions here: https://googlemobileadssdk.page.link/ad-manager-ios-update-plist\n```\n\nTry adding the following to your `Info.plist`:\n\n```xml\n\u003ckey\u003eGADIsAdManagerApp\u003c/key\u003e\n\u003ctrue/\u003e\n```\n\n\u003e The current iOS bindings are a little out of date and are still using an older version of the Google Mobile Ads SDK. While the version is now no longer a sunset version by Google, this is actively being worked on [here](https://github.com/jcsawyer/Jc.GoogleMobileAds.iOS).\n\n## Avalonia 12.x Migration\n\nComing soon...","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcsawyer%2FJc.AdMob.Avalonia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcsawyer%2FJc.AdMob.Avalonia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcsawyer%2FJc.AdMob.Avalonia/lists"}