From d5d4df9ec0a5a8b3fc6616bd984e267823e5056d Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 15 Jun 2020 08:43:56 +0500 Subject: [PATCH 01/27] try fixing fb-audience --- .../rnadmob/nativeads/RNNativeAdWrapper.java | 23 +++++++++++-------- example/App.js | 1 - src/Wrapper.js | 15 ++++-------- src/index.js | 3 +++ 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java index 5a6cf14c..eb68e7a6 100644 --- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java @@ -137,7 +137,7 @@ public void addMediaView(int id) { nativeAdView.setMediaView(adMediaView); adMediaView.requestLayout(); if (unifiedNativeAd != null && unifiedNativeAd.getMediaContent().hasVideoContent()) { - unifiedNativeAd.getMediaContent().getVideoController().play(); + //unifiedNativeAd.getMediaContent().getVideoController().play(); } } } catch (Exception e) { @@ -160,16 +160,21 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { if (nativeAd.getStarRating() != null) { args.putInt("rating", nativeAd.getStarRating().intValue()); } - args.putString("aspectRatio", String.valueOf(nativeAd.getMediaContent().getAspectRatio())); - WritableArray images = Arguments.createArray(); - for (int i = 0; i < nativeAd.getImages().size(); i++) { - WritableMap map = Arguments.createMap(); - map.putString("url", nativeAd.getImages().get(i).getUri().toString()); - map.putInt("width", nativeAd.getImages().get(i).getWidth()); - map.putInt("height", nativeAd.getImages().get(i).getHeight()); - images.pushMap(map); + args.putString("aspectRatio", String.valueOf(1)); + + WritableArray images = Arguments.createArray(); + + if (nativeAd.getImages() != null && nativeAd.getImages().size() > 0 ) { + for (int i = 0; i < nativeAd.getImages().size(); i++) { + WritableMap map = Arguments.createMap(); + map.putString("url", nativeAd.getImages().get(i).getUri().toString()); + map.putInt("width", nativeAd.getImages().get(i).getWidth()); + map.putInt("height", nativeAd.getImages().get(i).getHeight()); + images.pushMap(map); + } } + args.putArray("images", images); args.putString("icon", nativeAd.getIcon().getUri().toString()); sendEvent(RNAdMobNativeViewManager.EVENT_UNIFIED_NATIVE_AD_LOADED, args); diff --git a/example/App.js b/example/App.js index 15aa9374..9efc09bc 100644 --- a/example/App.js +++ b/example/App.js @@ -54,7 +54,6 @@ const App = () => { style={{ height: 400, width: '100%', - backgroundColor: 'white', }}> { - return Platform.OS === "android" ? ( - - ) : ( - - ); + + return }; -const AdWrapperView = - Platform.OS === "android" - ? requireNativeComponent("RNAdComponentWrapper", Wrapper) - : null; export default Wrapper; diff --git a/src/index.js b/src/index.js index aa176fbe..ee6f86ca 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ import React, { useEffect, useState } from "react"; import { Platform, requireNativeComponent } from "react-native"; import { NativeAdContext } from "./context"; +import Wrapper from "./Wrapper"; const testNativeAd = { headline: "Test Ad: Lorem ipsum dolor ", @@ -123,7 +124,9 @@ const NativeAdView = (props) => { testDevices={props.testDevices? props.testDevices : []} adUnitID={props.adUnitID} > + {props.children} + ); From 468555d45b383e376e2c291fe09d3ec02da8c948 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Wed, 17 Jun 2020 10:41:05 +0500 Subject: [PATCH 02/27] add ability to change AdChoices placement --- src/utils.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/utils.js diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 00000000..5ba3c375 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,10 @@ + + +export const AdOptions = Object.freeze({ + adChoicesPlacement: { + TOP_LEFT:0, + TOP_RIGHT:1, + BOTTOM_RIGHT:2, + BOTTOM_LEFT: 3 + } +}) \ No newline at end of file From d993e7eb831dc81edbdf48a821780f7d729da0da Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Wed, 17 Jun 2020 10:41:14 +0500 Subject: [PATCH 03/27] update .ts definations --- index.d.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/index.d.ts b/index.d.ts index bcc36d2c..26a69edf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,5 +1,6 @@ import { ViewStyle, TextProps, ImageProps, TextStyle } from "react-native"; import { StarRatingProps } from "react-native-star-rating"; +import { AdOptions } from "./src/utils"; type Image = { @@ -18,6 +19,8 @@ type Image = { } + + type NativeAd = { /** * Title of the native ad. @@ -69,6 +72,15 @@ type NativeAd = { video: boolean; }; +type AdOptions = { + adChoicesPlacement: { + TOP_LEFT:number, + TOP_RIGHT:number, + BOTTOM_RIGHT:number, + BOTTOM_LEFT: number + } +} + type NativeAdViewProps = { /** * When you are designing your ad, placeholders @@ -105,6 +117,34 @@ type NativeAdViewProps = { delayAdLoading?: number; + /** + * Placement of AdChoicesView in any of the 4 corners of the ad + * + * import AdOptions then pass the value from there. AdOptions.adChoicesPlacement + */ + + adChoicesPlacement?: { + TOP_LEFT:number, + TOP_RIGHT:number, + BOTTOM_RIGHT:number, + BOTTOM_LEFT: number + } + + /** + * Under the Google EU User Consent Policy, you must make certain disclosures + * to your users in the European Economic Area (EEA) and obtain their consent + * to use cookies or other local storage, where legally required, and to use + * personal data (such as AdID) to serve ads. This policy reflects the requirements + * of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). + * + * You can use library such as: https://github.com/birgernass/react-native-ad-consent + * to obtain the consent or if you are using rn-firebase you can obtain the consent from + * there and then pass the consent to this library. If user has selected + * non-personalized-ads then pass `true` and non-personalized ads will be shown to the user. + * + */ + requestNonPersonalizedAdsOnly:boolean; + /** * Set testdevices for the ad. */ @@ -129,6 +169,8 @@ type NestedTextProps = { allCaps?: boolean; }; + + declare module "react-native-admob-native-ads" { /** * @@ -145,6 +187,8 @@ declare module "react-native-admob-native-ads" { * Ad Badge shows the {ad} badge on top of the ad telling the user that this is an AD. * */ + + export const AdOptions = AdOptions; export function AdBadge(props: NestedTextProps): React.FunctionComponent; From 99d0804a06e90071bdea304415043ce6f91b39f7 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Wed, 17 Jun 2020 10:42:20 +0500 Subject: [PATCH 04/27] add props for passing EU-Consent to Admob on JS --- index.js | 3 +++ src/index.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/index.js b/index.js index 75cc59b6..17a3bfc5 100755 --- a/index.js +++ b/index.js @@ -10,6 +10,8 @@ import StarRatingView from './src/StarRatingView' import PriceView from "./src/PriceView"; import AdBadge from "./src/AdBadge"; import NativeAdView from './src'; +import {AdOptions} from "./src/utils" + export default NativeAdView; export { @@ -24,6 +26,7 @@ export { StarRatingView, PriceView, AdBadge, + AdOptions } diff --git a/src/index.js b/src/index.js index ee6f86ca..c1f959e5 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,8 @@ const testNativeAd = { images: ["https://dummyimage.com/qvga"], }; + + const waitAsync = (ms) => new Promise((resolve, reject) => { setTimeout(() => { @@ -119,6 +121,8 @@ const NativeAdView = (props) => { onAdClosed={_onAdClosed} onAdImpression={_onAdImpression} style={props.style} + adChoicesPlacement={props.adChoicesPlacement? props.adChoicesPlacement : } + requestNonPersonalizedAdsOnly={props.requestNonPersonalizedAdsOnly? true : false} onUnifiedNativeAdLoaded={_onUnifiedNativeAdLoaded} refreshInterval={props.refreshInterval? props.refreshInterval : 60000} testDevices={props.testDevices? props.testDevices : []} From a3093628abcc4660153cf5c07439fa00d00b414c Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Wed, 17 Jun 2020 10:49:55 +0500 Subject: [PATCH 05/27] add new props to bridge --- .../nativeads/RNAdMobNativeViewManager.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java index 470d98bd..02edbb01 100755 --- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java @@ -46,6 +46,8 @@ public class RNAdMobNativeViewManager extends ViewGroupManager Date: Wed, 17 Jun 2020 10:50:25 +0500 Subject: [PATCH 06/27] handle eu-consent from JS & adChoicesPlacement --- .../rnadmob/nativeads/RNNativeAdWrapper.java | 87 ++++++++++++++----- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java index eb68e7a6..d503c1ae 100644 --- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java @@ -1,6 +1,7 @@ package com.ammarahmed.rnadmob.nativeads; import android.content.Context; +import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; @@ -13,6 +14,7 @@ import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.events.RCTEventEmitter; +import com.google.ads.mediation.admob.AdMobAdapter; import com.google.android.gms.ads.AdListener; import com.google.android.gms.ads.AdLoader; import com.google.android.gms.ads.AdRequest; @@ -36,6 +38,11 @@ public void run() { Context mContext; UnifiedNativeAdView nativeAdView; UnifiedNativeAd unifiedNativeAd; + + private int adChoicesPlacement = 1; + private boolean requestNonPersonalizedAdsOnly = false; + + AdListener adListener = new AdListener() { @Override public void onAdFailedToLoad(int i) { @@ -136,9 +143,7 @@ public void addMediaView(int id) { if (adMediaView != null) { nativeAdView.setMediaView(adMediaView); adMediaView.requestLayout(); - if (unifiedNativeAd != null && unifiedNativeAd.getMediaContent().hasVideoContent()) { - //unifiedNativeAd.getMediaContent().getVideoController().play(); - } + } } catch (Exception e) { @@ -161,11 +166,27 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { args.putInt("rating", nativeAd.getStarRating().intValue()); } - args.putString("aspectRatio", String.valueOf(1)); + + float aspectRatio = 1.0f; + + if (nativeAd.getMediaContent() != null) { + try { + aspectRatio = nativeAd.getMediaContent().getAspectRatio(); + + if (aspectRatio > 0) { + args.putString("aspectRatio", String.valueOf(aspectRatio)); + } else { + args.putString("aspectRatio", String.valueOf(1)); + } + } catch (Exception e) { + args.putString("aspectRatio", String.valueOf(1)); + } + } + WritableArray images = Arguments.createArray(); - - if (nativeAd.getImages() != null && nativeAd.getImages().size() > 0 ) { + + if (nativeAd.getImages() != null && nativeAd.getImages().size() > 0) { for (int i = 0; i < nativeAd.getImages().size(); i++) { WritableMap map = Arguments.createMap(); map.putString("url", nativeAd.getImages().get(i).getUri().toString()); @@ -175,6 +196,7 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { } } + args.putArray("images", images); args.putString("icon", nativeAd.getIcon().getUri().toString()); sendEvent(RNAdMobNativeViewManager.EVENT_UNIFIED_NATIVE_AD_LOADED, args); @@ -214,27 +236,39 @@ private void sendEvent(String name, @Nullable WritableMap event) { private void loadAd() { - try { - AdLoader.Builder builder = new AdLoader.Builder(mContext, admobAdUnitId); - builder.forUnifiedNativeAd(onUnifiedNativeAdLoadedListener); - VideoOptions videoOptions = new VideoOptions.Builder() - .setStartMuted(true) - .build(); + try { + AdLoader.Builder builder = new AdLoader.Builder(mContext, admobAdUnitId); + builder.forUnifiedNativeAd(onUnifiedNativeAdLoadedListener); - NativeAdOptions adOptions = new NativeAdOptions.Builder() - .setVideoOptions(videoOptions) - .setAdChoicesPlacement(NativeAdOptions.ADCHOICES_TOP_RIGHT) - .build(); - builder.withNativeAdOptions(adOptions); + VideoOptions videoOptions = new VideoOptions.Builder() + .setStartMuted(true) + .build(); - AdLoader adLoader = builder.withAdListener(adListener) - .build(); + NativeAdOptions adOptions = new NativeAdOptions.Builder() + .setVideoOptions(videoOptions) + .setAdChoicesPlacement(adChoicesPlacement) + .build(); + builder.withNativeAdOptions(adOptions); - adLoader.loadAd(new AdRequest.Builder().build()); - } catch (Exception e) { - } + AdLoader adLoader = builder.withAdListener(adListener) + .build(); + + AdRequest adRequest; + + if (requestNonPersonalizedAdsOnly) { + Bundle extras = new Bundle(); + extras.putString("npa", "1"); + adRequest = new AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter.class, extras).build(); + } else { + adRequest = new AdRequest.Builder().build(); + } + + adLoader.loadAd(adRequest); + + } catch (Exception e) { + } } @@ -270,6 +304,15 @@ public void setAdUnitId(String id) { loadAd(); } + public void setAdChoicesPlacement(int location) { + adChoicesPlacement = location; + } + + public void setRequestNonPersonalizedAdsOnly(boolean npa) { + requestNonPersonalizedAdsOnly = npa; + loadAd(); + } + @Override public void requestLayout() { super.requestLayout(); From b3d5d0311796437372962bbaf876cd794722e3dd Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Thu, 18 Jun 2020 10:57:38 +0500 Subject: [PATCH 07/27] minor fix --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index c1f959e5..ba30751a 100644 --- a/src/index.js +++ b/src/index.js @@ -121,7 +121,7 @@ const NativeAdView = (props) => { onAdClosed={_onAdClosed} onAdImpression={_onAdImpression} style={props.style} - adChoicesPlacement={props.adChoicesPlacement? props.adChoicesPlacement : } + adChoicesPlacement={props.adChoicesPlacement? props.adChoicesPlacement : 1} requestNonPersonalizedAdsOnly={props.requestNonPersonalizedAdsOnly? true : false} onUnifiedNativeAdLoaded={_onUnifiedNativeAdLoaded} refreshInterval={props.refreshInterval? props.refreshInterval : 60000} From da2b728fb4cdc1c6a1cabeb5e33d1930a76b757a Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Thu, 18 Jun 2020 12:01:12 +0500 Subject: [PATCH 08/27] prevent 0 return false of adPlacement prop --- src/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index ba30751a..5f61edaf 100644 --- a/src/index.js +++ b/src/index.js @@ -113,6 +113,7 @@ const NativeAdView = (props) => { setNativeAdView(nativeAdRef); return nativeAdRef; }} + adUnitID={props.adUnitID} onAdLoaded={_onAdLoaded} onAdFailedToLoad={_onAdFailedToLoad} onAdClicked={_onAdClicked} @@ -121,12 +122,12 @@ const NativeAdView = (props) => { onAdClosed={_onAdClosed} onAdImpression={_onAdImpression} style={props.style} - adChoicesPlacement={props.adChoicesPlacement? props.adChoicesPlacement : 1} - requestNonPersonalizedAdsOnly={props.requestNonPersonalizedAdsOnly? true : false} onUnifiedNativeAdLoaded={_onUnifiedNativeAdLoaded} refreshInterval={props.refreshInterval? props.refreshInterval : 60000} testDevices={props.testDevices? props.testDevices : []} - adUnitID={props.adUnitID} + adChoicesPlacement={props.adChoicesPlacement > -1? props.adChoicesPlacement : 1} + requestNonPersonalizedAdsOnly={props.requestNonPersonalizedAdsOnly? true : false} + > {props.children} From 9d13ffdb1b6f35398780d029acbb87debc722737 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Thu, 18 Jun 2020 12:04:37 +0500 Subject: [PATCH 09/27] add eu-consent & adPlacement props iOS --- ios/RNGADNativeView.h | 2 ++ ios/RNGADNativeView.m | 48 ++++++++++++++++++++++++++++-------- ios/RNGADNativeViewManager.m | 4 +-- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/ios/RNGADNativeView.h b/ios/RNGADNativeView.h index 32125463..12920217 100755 --- a/ios/RNGADNativeView.h +++ b/ios/RNGADNativeView.h @@ -23,6 +23,8 @@ @property (nonatomic, copy) NSNumber *mediaview; @property (nonatomic, copy) NSNumber *starrating; @property (nonatomic, copy) NSNumber *callToAction; +@property (nonatomic, copy) NSNumber *adChoicesPlacement; +@property (nonatomic) BOOL *requestNonPersonalizedAdsOnly; - (instancetype)initWithBridge:(RCTBridge *)bridge; diff --git a/ios/RNGADNativeView.m b/ios/RNGADNativeView.m index 12e4800b..174cd078 100755 --- a/ios/RNGADNativeView.m +++ b/ios/RNGADNativeView.m @@ -21,6 +21,9 @@ @implementation RNGADNativeView : GADUnifiedNativeAdView NSString *adUnitId; NSNumber *refreshingInterval; NSNumber *delay; +NSNumber *adChoicesPlace; +BOOL *nonPersonalizedAds; + - (instancetype)initWithBridge:(RCTBridge *)_bridge @@ -33,6 +36,16 @@ - (instancetype)initWithBridge:(RCTBridge *)_bridge return self; } +- (void)setAdChoicesPlacement:(NSNumber *)adChoicesPlacement { + + adChoicesPlace = adChoicesPlacement; +} + +- (void)setRequestNonPersonalizedAdsOnly:(BOOL *)requestNonPersonalizedAdsOnly { + + nonPersonalizedAds = requestNonPersonalizedAdsOnly; +} + - (void)setDelayAdLoad:(NSNumber *)delayAdLoad { delay = delayAdLoad; @@ -164,10 +177,6 @@ - (void)setPrice:(NSNumber *)price }]; }); - - - - } - (void)setStore:(NSNumber *)store @@ -184,10 +193,6 @@ - (void)setStore:(NSNumber *)store } }]; }); - - - - } - (void)setStarrating:(NSNumber *)starrating @@ -235,7 +240,22 @@ - (void)loadAd:(NSString *)adUnitId GADNativeAdViewAdOptions *adViewOptions = [GADNativeAdViewAdOptions new]; - adViewOptions.preferredAdChoicesPosition = GADAdChoicesPositionTopRightCorner; + + if ([adChoicesPlace isEqualToNumber:@0]) { + [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionTopLeftCorner]; + } else if ([adChoicesPlace isEqualToNumber:@1]) { + [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionTopRightCorner]; + } else if ([adChoicesPlace isEqualToNumber:@2]) { + [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionBottomRightCorner]; + } else if ([adChoicesPlace isEqualToNumber:@3]) { + [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionBottomLeftCorner]; + } else { + [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionTopRightCorner]; + + } + + + self.adLoader = [[GADAdLoader alloc] @@ -244,8 +264,16 @@ - (void)loadAd:(NSString *)adUnitId adTypes:@[ kGADAdLoaderAdTypeUnifiedNative ] options:@[adViewOptions]]; + self.adLoader.delegate = self; GADRequest *request = [GADRequest request]; + + if (nonPersonalizedAds) { + GADExtras *extras = [[GADExtras alloc] init]; + extras.additionalParameters = @{@"npa": @"1"}; + [request registerAdNetworkExtras:extras]; + } + GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers = _testDevices; [self.adLoader loadRequest:request]; } @@ -299,7 +327,7 @@ - (void)adLoader:(GADAdLoader *)adLoader didReceiveUnifiedNativeAd:(GADUnifiedNa NSInteger val2 = @(image.image.size.height).integerValue; [imageDic setValue: [NSNumber numberWithInteger:val2] forKey:@"height"]; [images addObject:imageDic]; - + } diff --git a/ios/RNGADNativeViewManager.m b/ios/RNGADNativeViewManager.m index cd65dc83..8db61bd1 100755 --- a/ios/RNGADNativeViewManager.m +++ b/ios/RNGADNativeViewManager.m @@ -44,8 +44,8 @@ -(UIView *)view RCT_EXPORT_VIEW_PROPERTY(price, NSNumber) RCT_EXPORT_VIEW_PROPERTY(starrating, NSNumber) RCT_EXPORT_VIEW_PROPERTY(callToAction, NSNumber) - - +RCT_EXPORT_VIEW_PROPERTY(requestNonPersonalizedAdsOnly, BOOL) +RCT_EXPORT_VIEW_PROPERTY(adChoicesPlacement, NSNumber) //RCT_EXPORT_VIEW_PROPERTY(ratingStarsColor, NSString) From 575f36ece10457bdd290fd75ac03d931b6acc7c5 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Thu, 18 Jun 2020 12:06:37 +0500 Subject: [PATCH 10/27] fix .ts definations --- index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 26a69edf..aabd1ead 100644 --- a/index.d.ts +++ b/index.d.ts @@ -72,7 +72,7 @@ type NativeAd = { video: boolean; }; -type AdOptions = { +type options = { adChoicesPlacement: { TOP_LEFT:number, TOP_RIGHT:number, @@ -188,7 +188,7 @@ declare module "react-native-admob-native-ads" { * */ - export const AdOptions = AdOptions; + export const AdOptions:options; export function AdBadge(props: NestedTextProps): React.FunctionComponent; From 289ac21bab1a89f8ef65d3be87d9d22ecfc42ebd Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Fri, 26 Jun 2020 18:03:31 +0500 Subject: [PATCH 11/27] try to fix fb-audience --- .../rnadmob/nativeads/RNNativeAdWrapper.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java index d503c1ae..cad96063 100644 --- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java @@ -176,10 +176,11 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { if (aspectRatio > 0) { args.putString("aspectRatio", String.valueOf(aspectRatio)); } else { - args.putString("aspectRatio", String.valueOf(1)); + args.putString("aspectRatio", String.valueOf(aspectRatio)); } } catch (Exception e) { - args.putString("aspectRatio", String.valueOf(1)); + aspectRatio = 1.0f; + args.putString("aspectRatio", String.valueOf(aspectRatio)); } } @@ -187,6 +188,7 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { WritableArray images = Arguments.createArray(); if (nativeAd.getImages() != null && nativeAd.getImages().size() > 0) { + for (int i = 0; i < nativeAd.getImages().size(); i++) { WritableMap map = Arguments.createMap(); map.putString("url", nativeAd.getImages().get(i).getUri().toString()); @@ -197,8 +199,18 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { } - args.putArray("images", images); - args.putString("icon", nativeAd.getIcon().getUri().toString()); + if (images != null) { + args.putArray("images", images); + } else { + args.putArray("images", null); + } + + if (nativeAd.getIcon() != null || nativeAd.getIcon().getUri() != null) { + args.putString("icon", nativeAd.getIcon().getUri().toString()); + } else { + args.putString("icon", "empty"); + } + sendEvent(RNAdMobNativeViewManager.EVENT_UNIFIED_NATIVE_AD_LOADED, args); } catch (Exception e) { From 4ef41a611352d87d6efcaa50b2801aa32add7c31 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Fri, 26 Jun 2020 18:04:28 +0500 Subject: [PATCH 12/27] make sure icon is loaded in fb-audience --- src/IconView.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/IconView.js b/src/IconView.js index 758b9221..2060c008 100644 --- a/src/IconView.js +++ b/src/IconView.js @@ -20,7 +20,7 @@ const IconView = (props) => { _onLayout(); }, [nativeAd, nativeAdView]); - return nativeAd && nativeAd.icon ? ( + return nativeAd && nativeAd.icon && nativeAd.icon !== "empty" ? ( { onLayout={_onLayout} source={{ uri: nativeAd.icon }} /> - ) : null; + ) : ( + + ); }; export default IconView; From 2265ea0f1e983fe20d4853f5371fc47aaf61a60a Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Fri, 26 Jun 2020 18:04:44 +0500 Subject: [PATCH 13/27] dont show imageView when empty --- src/ImageView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageView.js b/src/ImageView.js index 5a148797..958133ed 100644 --- a/src/ImageView.js +++ b/src/ImageView.js @@ -19,7 +19,7 @@ const ImageView = (props) => { _onLayout(); }, [nativeAd, nativeAdView]); - return nativeAd && nativeAd.images[0] ? ( + return nativeAd && nativeAd.images && nativeAd.images[0] ? ( Date: Mon, 6 Jul 2020 11:50:12 +0500 Subject: [PATCH 14/27] update README.md --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 661e2982..dfdb2978 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,66 @@ return (

📃 Reference

+## AdManager +AdManager allows you to configure your ads globally when the app starts + +### setRequestConfiguration(config) +Configure your Ad Requests during App Startup. You need to pass a single object as an argument with atleast one of the following properties + +| Name | Type | Required | +| --------- | -------- | -------- | +| testDeviceIds | `Array` | no | +| maxAdContentRating | AdManager.MAX_AD_CONTENT_RATING | no | +| tagForChildDirectedTreatment | AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT | no | +| tagForUnderAgeConsent | AdManager.TAG_FOR_UNDER_AGE_CONSENT | no | + +```js + +const config = { + testDeviceIds:["YOUR_TEST_DEVICE_ID"], + maxAdContetRating:AdManager.MAX_AD_CONTENT_RATING.MA, + tagForChildDirectedTreatment:AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT.FALSE, + tagForUnderAgeConsent:AdManager.TAG_FOR_UNDER_AGE_CONSENT.FALSE +} + +AdManager.setRequestConfiguration(config); + +``` + +### isTestDevice() +Check if the current device is registered as a test device to show test ads. + +```js + AdManager.isTestDevice().then(result => console.log(result)) +``` +return: `boolean` + +### AdManager.MAX_AD_CONTENT_RATING + +| Name | Description | +| --------- | -------- | +| G | "General audiences." Content suitable for all audiences, including families and children. | +| MA | "Mature audiences." Content suitable only for mature audiences; includes topics such as alcohol, gambling, sexual content, and weapons. | +| PG | "Parental guidance." Content suitable for most audiences with parental guidance, including topics like non-realistic, cartoonish violence. | +| T | "Teen." Content suitable for teen and older audiences, including topics such as general health, social networks, scary imagery, and fight sports. | +| UNSPECIFIED | Set default value to ""| + +### AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT + +| Name | Description | +| --------- | -------- | +| TRUE | Enabled | +| FALSE | Disabled | + +### AdManager.TAG_FOR_UNDER_AGE_CONSENT + +| Name | Description | +| --------- | -------- | +| TRUE | Enabled | +| FALSE | Disabled | + +# + ## NativeAdView NativeAdView will wrap all your views related to the ad and provides a context through which all the Views get their respective information and load it automatically. It has the following properties to it. @@ -238,7 +298,7 @@ Set Ad Unit ID for Native Advanced Ads that you created on your AdMob account. | -------- | -------- | -------- | | `string` | Yes | All | -# +# #### `testDevices` @@ -248,7 +308,7 @@ Set testDevices during testing ads or during development. | --------------- | -------- | -------- | | `Array` | no | All | -# +# #### `enableTestMode` @@ -258,7 +318,7 @@ Setting this to true will load a placeholder ad (Not from Admob server) incase y | --------- | -------- | -------- | | `boolean` | no | All | -# +# #### `delayAdloading` @@ -269,7 +329,7 @@ Delay ad loading and rendering by the specified time in milliseconds. This is a | `number` | no | 0 ms | All | -# +# #### `refreshInterval` @@ -279,7 +339,7 @@ Time in ms after which a new ad should be requested from the server. | -------- | -------- | ------------------- | -------- | | `number` | no | 60000 ms (1 minute) | All | -# +# ### Events From d884ae68ee6b5c439b749ca0495264fa547cc9c7 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:50:21 +0500 Subject: [PATCH 15/27] update build.gradle --- android/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index c6593848..4ed492ed 100755 --- a/android/build.gradle +++ b/android/build.gradle @@ -22,7 +22,8 @@ android { dependencies { implementation 'com.facebook.react:react-native:+' - implementation 'com.google.android.gms:play-services-ads:+' + implementation 'com.google.android.gms:play-services-ads:19.2.0' implementation 'com.android.support:support-annotations:28.0.0' + implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'com.android.support.constraint:constraint-layout:1.1.3' } From d6e45020d663fcd16315fbf859816cedc649b644 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:55:44 +0500 Subject: [PATCH 16/27] update type definations --- index.d.ts | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index aabd1ead..761c2835 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,6 +1,5 @@ import { ViewStyle, TextProps, ImageProps, TextStyle } from "react-native"; import { StarRatingProps } from "react-native-star-rating"; -import { AdOptions } from "./src/utils"; type Image = { @@ -81,6 +80,31 @@ type options = { } } +type MAX_AD_CONTENT_RATING = { + G: string, + MA:string, + PG: string, + T: string, + UNSPECIFIED:string, +} +type TAG_FOR_CHILD_DIRECTED_TREATMENT = { + TRUE:number, + FALSE:number +} + +type TAG_FOR_UNDER_AGE_CONSENT = { + TRUE:number, + FALSE:number +} + +type config = { + maxAdContentRating:MAX_AD_CONTENT_RATING, + tagForChildDirectedTreatment:TAG_FOR_CHILD_DIRECTED_TREATMENT, + tagForUnderAgeConsent:TAG_FOR_UNDER_AGE_CONSENT, + testDeviceIds:Array +} + + type NativeAdViewProps = { /** * When you are designing your ad, placeholders @@ -146,7 +170,7 @@ type NativeAdViewProps = { requestNonPersonalizedAdsOnly:boolean; /** - * Set testdevices for the ad. + * Set testdevices for the ad. (DEPRECATED) */ testDevices?: Array; onAdOpened?: Function; @@ -172,6 +196,8 @@ type NestedTextProps = { declare module "react-native-admob-native-ads" { + + /** * * Wrapper for the UnifiedNativeAdView from Google Ads SDK. All your views should be @@ -183,13 +209,101 @@ declare module "react-native-admob-native-ads" { props: NativeAdViewProps ): React.FunctionComponent; + + const MAX_AD_CONTENT_RATING:MAX_AD_CONTENT_RATING; + const TAG_FOR_CHILD_DIRECTED_TREATMENT:TAG_FOR_CHILD_DIRECTED_TREATMENT; + const TAG_FOR_UNDER_AGE_CONSENT:TAG_FOR_UNDER_AGE_CONSENT; + + /** - * Ad Badge shows the {ad} badge on top of the ad telling the user that this is an AD. - * + * AdManager can be used to configure your ads on App Startup such as setting test devices. + * */ + + export const AdManager = { + + /** + * Configure your Ad Requests during App Startup. You need to pass a single object as an argument with atleast one of the following properties + + | Name | Type | Required | + | --------- | -------- | -------- | + | testDeviceIds | `Array` | no | + | maxAdContentRating | AdManager.MAX_AD_CONTENT_RATING | no | + | tagForChildDirectedTreatment | AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT | no | + | tagForUnderAgeConsent | AdManager.TAG_FOR_UNDER_AGE_CONSENT | no | + + Example: + + ```js + + const config = { + testDeviceIds:["YOUR_TEST_DEVICE_ID"], + maxAdContetRating:AdManager.MAX_AD_CONTENT_RATING.MA, + tagForChildDirectedTreatment:AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT.FALSE, + tagForUnderAgeConsent:AdManager.TAG_FOR_UNDER_AGE_CONSENT.FALSE + } + + AdManager.setRequestConfiguration(config); + + ``` + * + */ + + setRequestConfiguration: (config:config) => {}, + + /** + * Check if the current device is registered as a test device to show test ads. + +```js + AdManager.isTestDevice().then(result => console.log(result)) +``` +return: `boolean` + */ + isTestDevice:async () => {}, + + + /** + * | Name | Description | +| --------- | -------- | +| G | "General audiences." Content suitable for all audiences, including families and children. | +| MA | "Mature audiences." Content suitable only for mature audiences; includes topics such as alcohol, gambling, sexual content, and weapons. | +| PG | "Parental guidance." Content suitable for most audiences with parental guidance, including topics like non-realistic, cartoonish violence. | +| T | "Teen." Content suitable for teen and older audiences, including topics such as general health, social networks, scary imagery, and fight sports. | +| UNSPECIFIED | Set default value to ""| + */ + + MAX_AD_CONTENT_RATING:MAX_AD_CONTENT_RATING, + + + /** + * | Name | Description | +| --------- | -------- | +| TRUE | Enabled | +| FALSE | Disabled | + */ + + TAG_FOR_CHILD_DIRECTED_TREATMENT:TAG_FOR_CHILD_DIRECTED_TREATMENT, + + /** + * | Name | Description | +| --------- | -------- | +| TRUE | Enabled | +| FALSE | Disabled | + */ + + + TAG_FOR_UNDER_AGE_CONSENT:TAG_FOR_UNDER_AGE_CONSENT +} + export const AdOptions:options; + + /** + * Ad Badge shows the {ad} badge on top of the ad telling the user that this is an AD. + * + */ + export function AdBadge(props: NestedTextProps): React.FunctionComponent; /** From c28fcd50857fb7f964e88b5df0d4810f7f9dfd4e Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:56:07 +0500 Subject: [PATCH 17/27] add AdManager to index.js --- index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 17a3bfc5..f0eef755 100755 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ import PriceView from "./src/PriceView"; import AdBadge from "./src/AdBadge"; import NativeAdView from './src'; import {AdOptions} from "./src/utils" - +import AdManager from "./src/AdManager" export default NativeAdView; export { @@ -26,7 +26,8 @@ export { StarRatingView, PriceView, AdBadge, - AdOptions + AdOptions, + AdManager } From 1c2f2a33e5b4f2a3d764aa789539c7a59082754d Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:58:02 +0500 Subject: [PATCH 18/27] no aspectRatio if ad is from mediation network --- .../rnadmob/nativeads/RNNativeAdWrapper.java | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java index cad96063..dacc9f12 100644 --- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java @@ -166,22 +166,22 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { args.putInt("rating", nativeAd.getStarRating().intValue()); } - float aspectRatio = 1.0f; - if (nativeAd.getMediaContent() != null) { - try { + + if (nativeAd.getResponseInfo().getMediationAdapterClassName().equals("com.google.ads.mediation.admob.AdMobAdapter")) { + if (nativeAd.getMediaContent() != null) { aspectRatio = nativeAd.getMediaContent().getAspectRatio(); if (aspectRatio > 0) { args.putString("aspectRatio", String.valueOf(aspectRatio)); } else { - args.putString("aspectRatio", String.valueOf(aspectRatio)); + args.putString("aspectRatio", String.valueOf(1.0f)); } - } catch (Exception e) { - aspectRatio = 1.0f; - args.putString("aspectRatio", String.valueOf(aspectRatio)); + } + } else { + args.putString("aspectRatio", String.valueOf(1.0f)); } @@ -198,7 +198,6 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) { } } - if (images != null) { args.putArray("images", images); } else { @@ -281,8 +280,6 @@ private void loadAd() { } catch (Exception e) { } - - } public void setLoadWithDelay(int delay) { @@ -322,7 +319,6 @@ public void setAdChoicesPlacement(int location) { public void setRequestNonPersonalizedAdsOnly(boolean npa) { requestNonPersonalizedAdsOnly = npa; - loadAd(); } @Override @@ -337,8 +333,5 @@ public void removeHandler() { handler.removeCallbacks(null); handler = null; } - } - - } From 8fcaa84ffc4ba41b07d7d148a6984644f88c88f4 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:58:27 +0500 Subject: [PATCH 19/27] add a module for configuring ads on app startup --- .../nativeads/RNAdMobNativePackage.java | 4 +- .../nativeads/RNAdmobNativeAdsManager.java | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdmobNativeAdsManager.java diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java index 0c66e14d..0ec8c739 100755 --- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java @@ -14,7 +14,9 @@ public class RNAdMobNativePackage implements ReactPackage { @Override public List createNativeModules(ReactApplicationContext reactContext) { - return Arrays.asList(); + return Arrays.asList( + new RNAdmobNativeAdsManager(reactContext) + ); } public List> createJSModules() { diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdmobNativeAdsManager.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdmobNativeAdsManager.java new file mode 100644 index 00000000..4be5dbb8 --- /dev/null +++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdmobNativeAdsManager.java @@ -0,0 +1,76 @@ +package com.ammarahmed.rnadmob.nativeads; + +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableNativeArray; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.MobileAds; +import com.google.android.gms.ads.RequestConfiguration; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class RNAdmobNativeAdsManager extends ReactContextBaseJavaModule { + + private ReactContext reactContext; + + public RNAdmobNativeAdsManager(ReactApplicationContext rc) { + super(rc); + reactContext = rc; + + } + + @Override + public String getName() { + return "RNAdmobNativeAdsManager"; + } + + + + + @ReactMethod + public void setRequestConfiguration(ReadableMap config) { + + + RequestConfiguration.Builder configuration = new RequestConfiguration.Builder(); + + if (config.hasKey("maxAdContentRating")) { + if (config.getString("maxAdContentRating") != null) { + configuration.setMaxAdContentRating(config.getString("maxAdContentRating")); + } + } + + if (config.hasKey("tagForChildDirectedTreatment")) { + configuration.setTagForChildDirectedTreatment(config.getInt("tagForChildDirectedTreatment")); + } + if (config.hasKey("tagForUnderAgeOfConsent")) { + configuration.setTagForUnderAgeOfConsent(config.getInt("TagForUnderAgeOfConsent")); + } + if (config.hasKey("testDeviceIds")) { + ReadableNativeArray nativeArray = (ReadableNativeArray) config.getArray("testDeviceIds"); + ArrayList list = nativeArray.toArrayList(); + List testDeviceIds = Arrays.asList(list.toArray(new String[list.size()])); + configuration.setTestDeviceIds(testDeviceIds); + } + + MobileAds.setRequestConfiguration(configuration.build()); + MobileAds.initialize(reactContext); + + } + + + + @ReactMethod + public void isTestDevice(Promise promise) { + + AdRequest builder = new AdRequest.Builder().build(); + if (builder != null) { + promise.resolve(builder.isTestDevice(reactContext)); + } + } +} From 8ebc84a0538b76e690ccb0e4d8bc9c97351bfd61 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:58:47 +0500 Subject: [PATCH 20/27] add AdManager on js side --- src/AdManager.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/AdManager.js diff --git a/src/AdManager.js b/src/AdManager.js new file mode 100644 index 00000000..048a5196 --- /dev/null +++ b/src/AdManager.js @@ -0,0 +1,37 @@ +import {NativeModules} from 'react-native'; + +const RNAdmobNativeAdsManager = NativeModules.RNAdmobNativeAdsManager; + +const MAX_AD_CONTENT_RATING = { + G: "G", + MA:"MA", + PG: "PG", + T: "T", + UNSPECIFIED: "", +} +const TAG_FOR_CHILD_DIRECTED_TREATMENT = { + TRUE:1, + FALSE:0 +} + +const TAG_FOR_UNDER_AGE_CONSENT = { + TRUE:1, + FALSE:0 +} + +function setRequestConfiguration(config) { + + RNAdmobNativeAdsManager.setRequestConfiguration(config); +} + +function isTestDevice() { + +} + +export default { + setRequestConfiguration, + isTestDevice, + MAX_AD_CONTENT_RATING, + TAG_FOR_CHILD_DIRECTED_TREATMENT, + TAG_FOR_UNDER_AGE_CONSENT +} \ No newline at end of file From c673afd51ab494253a994f2deb54399e73b2f882 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 11:59:43 +0500 Subject: [PATCH 21/27] minor change --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 5f61edaf..ef43b670 100644 --- a/src/index.js +++ b/src/index.js @@ -108,6 +108,7 @@ const NativeAdView = (props) => { value={{ nativeAd, nativeAdView, setNativeAdView, setNativeAd }} > { nativeAdRef = ref; setNativeAdView(nativeAdRef); @@ -125,9 +126,8 @@ const NativeAdView = (props) => { onUnifiedNativeAdLoaded={_onUnifiedNativeAdLoaded} refreshInterval={props.refreshInterval? props.refreshInterval : 60000} testDevices={props.testDevices? props.testDevices : []} - adChoicesPlacement={props.adChoicesPlacement > -1? props.adChoicesPlacement : 1} requestNonPersonalizedAdsOnly={props.requestNonPersonalizedAdsOnly? true : false} - + adChoicesPlacement={props.adChoicesPlacement > -1? props.adChoicesPlacement : 1} > {props.children} From 4b22d8eb58fd9f8c55acd773f09cc8bea5e9324f Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 12:00:46 +0500 Subject: [PATCH 22/27] add isTestDevice function --- src/AdManager.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AdManager.js b/src/AdManager.js index 048a5196..c02e5b19 100644 --- a/src/AdManager.js +++ b/src/AdManager.js @@ -24,8 +24,9 @@ function setRequestConfiguration(config) { RNAdmobNativeAdsManager.setRequestConfiguration(config); } -function isTestDevice() { +async function isTestDevice() { + return await RNAdmobNativeAdsManager.isTestDevice(); } export default { From bd8cd9137858dc63f9c75d620eb0338dea19bb95 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 13:57:57 +0500 Subject: [PATCH 23/27] add AdManager for ios --- ios/RNAdmobNativeAdsManager.h | 8 ++++ ios/RNAdmobNativeAdsManager.m | 77 +++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 ios/RNAdmobNativeAdsManager.h create mode 100644 ios/RNAdmobNativeAdsManager.m diff --git a/ios/RNAdmobNativeAdsManager.h b/ios/RNAdmobNativeAdsManager.h new file mode 100644 index 00000000..f1238ba7 --- /dev/null +++ b/ios/RNAdmobNativeAdsManager.h @@ -0,0 +1,8 @@ +// CalendarManager.h +#import + + +@interface RNAdmobNativeAdsManager : NSObject + +@end + diff --git a/ios/RNAdmobNativeAdsManager.m b/ios/RNAdmobNativeAdsManager.m new file mode 100644 index 00000000..8908ae83 --- /dev/null +++ b/ios/RNAdmobNativeAdsManager.m @@ -0,0 +1,77 @@ +#import "RNAdmobNativeAdsManager.h" + +@import GoogleMobileAds; + +@implementation RNAdmobNativeAdsManager + +RCT_EXPORT_MODULE(); + + + +RCT_EXPORT_METHOD(setRequestConfiguration:(NSDictionary *)config) +{ + + if ([[config allKeys] containsObject:@"maxAdContentRating"]) { + + NSString *rating = [config valueForKey:@"maxAdContentRating"]; + + if ([rating isEqualToString:@"G"]) { + [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingGeneral]; + + } else if ([rating isEqualToString:@"PG"]) { + + [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingParentalGuidance]; + } else if ([rating isEqualToString:@"MA"]) { + + [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingMatureAudience]; + } else if ([rating isEqualToString:@"T"]) { + [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingTeen]; + } else if ([rating isEqualToString:@""]) { + [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:NULL]; + + } + + }; + + if ([[config allKeys] containsObject:@"tagForChildDirectedTreatment"]) { + NSNumber *tag = [config valueForKey:@"tagForChildDirectedTreatment"]; + + if (tag.intValue == 0) { + [[[GADMobileAds sharedInstance] requestConfiguration] tagForChildDirectedTreatment:false]; + + } else { + [[[GADMobileAds sharedInstance] requestConfiguration] tagForChildDirectedTreatment:true]; + + } + }; + + if ([[config allKeys] containsObject:@"tagForUnderAgeConsent"]) { + NSNumber *tagC = [config valueForKey:@"tagForUnderAgeConsent"]; + + if (tagC.intValue == 0) { + [[[GADMobileAds sharedInstance] requestConfiguration] tagForUnderAgeOfConsent:false]; + } else { + [[[GADMobileAds sharedInstance] requestConfiguration] tagForUnderAgeOfConsent:true]; + } + }; + + if ([[config allKeys] containsObject:@"testDeviceIds"]) { + NSArray *testDevices = [config valueForKey:@"testDeviceIds"]; + + [[[GADMobileAds sharedInstance] requestConfiguration] setTestDeviceIdentifiers:testDevices]; + }; + + +} + +RCT_EXPORT_METHOD(isTestDevice:(RCTPromiseResolveBlock)resolve +rejecter:(RCTPromiseRejectBlock)reject) { + + resolve(@TRUE); +} + + + + + +@end From 52fbce32b935f4cbd1846f3894b5ea55f902b5f0 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 13:59:06 +0500 Subject: [PATCH 24/27] some minor updates --- example/App.js | 4 +++- example/index.js | 8 +++++++- example/ios/Podfile.lock | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/example/App.js b/example/App.js index 9efc09bc..65488543 100644 --- a/example/App.js +++ b/example/App.js @@ -8,6 +8,7 @@ import NativeAdView, { AdvertiserView, MediaView, } from 'react-native-admob-native-ads'; +import { AdManager } from 'react-native-admob-native-ads'; const NATIVE_AD_ID = Platform.OS === 'ios' @@ -26,6 +27,7 @@ const App = () => { }; const _onAdLoaded = () => { + console.log('Ad has loaded'); }; @@ -48,7 +50,7 @@ const App = () => { alignSelf: 'center', height: 900, }} - adUnitID={NATIVE_AD_VIDEO_ID} // REPLACE WITH NATIVE_AD_VIDEO_ID for video ads. + adUnitID={NATIVE_AD_ID} // REPLACE WITH NATIVE_AD_VIDEO_ID for video ads. > App); diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 66fd7c0b..45526f20 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -211,7 +211,7 @@ PODS: - React-cxxreact (= 0.61.5) - React-jsi (= 0.61.5) - React-jsinspector (0.61.5) - - react-native-admob-native-ads (0.1.1): + - react-native-admob-native-ads (0.2.9): - React - React-RCTActionSheet (0.61.5): - React-Core/RCTActionSheetHeaders (= 0.61.5) @@ -369,7 +369,7 @@ SPEC CHECKSUMS: React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7 React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386 React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 - react-native-admob-native-ads: d81f8f3232ef42aab90e7de4031fa7241d768b11 + react-native-admob-native-ads: 37849d7d88dd3348a713d441d012ab23e7ddcd3e React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 From 05fe17911f0dbb9db460ee751e278c50893ba2e6 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 14:04:12 +0500 Subject: [PATCH 25/27] update version to 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f1e1199..dac017cd 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-admob-native-ads", - "version": "0.2.9", + "version": "0.3.0", "description": "A simple and robust library for creating & displaying Admob Native Ads in your React Native App using Native Views", "author": "Ammar Ahmed ", "main": "index.js", From f04a6b3de51f515583c41382f0c2081ff1526f47 Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 14:17:41 +0500 Subject: [PATCH 26/27] prevent multiple state updates --- src/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/index.js b/src/index.js index ef43b670..36465bc3 100644 --- a/src/index.js +++ b/src/index.js @@ -69,8 +69,6 @@ const NativeAdView = (props) => { updateAd(event.nativeEvent); setTimeout(() => { setForceRefresh(!forceRefresh); - setForceRefresh(!forceRefresh); - setForceRefresh(!forceRefresh); }, 0); if (props.onUnifiedNativeAdLoaded) { From b140dc587083dbd0b1d8e38609a140cf276df55a Mon Sep 17 00:00:00 2001 From: ammarahm-ed Date: Mon, 6 Jul 2020 14:18:15 +0500 Subject: [PATCH 27/27] update Podfile.lock in example --- example/ios/Podfile.lock | 42 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 45526f20..4612613c 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -19,35 +19,37 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - Google-Mobile-Ads-SDK (7.56.0): + - Google-Mobile-Ads-SDK (7.61.0): - GoogleAppMeasurement (~> 6.0) - - GoogleAppMeasurement (6.3.1): + - GoogleAppMeasurement (6.6.1): - GoogleUtilities/AppDelegateSwizzler (~> 6.0) - GoogleUtilities/MethodSwizzler (~> 6.0) - GoogleUtilities/Network (~> 6.0) - "GoogleUtilities/NSData+zlib (~> 6.0)" - - nanopb (= 0.3.9011) - - GoogleUtilities/AppDelegateSwizzler (6.5.2): + - nanopb (~> 1.30905.0) + - GoogleUtilities/AppDelegateSwizzler (6.6.0): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (6.5.2) - - GoogleUtilities/Logger (6.5.2): + - GoogleUtilities/Environment (6.6.0): + - PromisesObjC (~> 1.2) + - GoogleUtilities/Logger (6.6.0): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (6.5.2): + - GoogleUtilities/MethodSwizzler (6.6.0): - GoogleUtilities/Logger - - GoogleUtilities/Network (6.5.2): + - GoogleUtilities/Network (6.6.0): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.5.2)" - - GoogleUtilities/Reachability (6.5.2): + - "GoogleUtilities/NSData+zlib (6.6.0)" + - GoogleUtilities/Reachability (6.6.0): - GoogleUtilities/Logger - - nanopb (0.3.9011): - - nanopb/decode (= 0.3.9011) - - nanopb/encode (= 0.3.9011) - - nanopb/decode (0.3.9011) - - nanopb/encode (0.3.9011) + - nanopb (1.30905.0): + - nanopb/decode (= 1.30905.0) + - nanopb/encode (= 1.30905.0) + - nanopb/decode (1.30905.0) + - nanopb/encode (1.30905.0) + - PromisesObjC (1.2.9) - RCTRequired (0.61.5) - RCTTypeSafety (0.61.5): - FBLazyVector (= 0.61.5) @@ -292,6 +294,7 @@ SPEC REPOS: - GoogleAppMeasurement - GoogleUtilities - nanopb + - PromisesObjC EXTERNAL SOURCES: DoubleConversion: @@ -356,10 +359,11 @@ SPEC CHECKSUMS: FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - Google-Mobile-Ads-SDK: 65e335fadc97c5a91a9d4546214bfd3a2fb11047 - GoogleAppMeasurement: c29d405ff76e18551b5d158eaba6753fda8c7542 - GoogleUtilities: ad0f3b691c67909d03a3327cc205222ab8f42e0e - nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd + Google-Mobile-Ads-SDK: 4c3b24b04293b4bb370b2cb392cdd3ee97c87752 + GoogleAppMeasurement: 2fd5c5a56c069db635c8e7b92d4809a9591d0a69 + GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1 + nanopb: c43f40fadfe79e8b8db116583945847910cbabc9 + PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75 RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78