[admob][ios] Finish up Interstitial with events + AdRequest handling

This commit is contained in:
Elliot Hesp 2017-06-07 12:37:32 +01:00
parent 57e6463789
commit 921eac06a4
6 changed files with 159 additions and 24 deletions

View File

@ -60,6 +60,8 @@ An interstitial is a full screen advert which creates a new activity on top of R
allowing the developer to choose when to display them they're not available as a component. Instead they're controlled via allowing the developer to choose when to display them they're not available as a component. Instead they're controlled via
method calls. method calls.
A single interstitial instance can only be shown once. If you want to display another, create a new one.
To request an interstitial from AdMob, the `loadAd` method must be called with an instance of `AdRequest` (see below for full API): To request an interstitial from AdMob, the `loadAd` method must be called with an instance of `AdRequest` (see below for full API):
#### Methods #### Methods
@ -147,6 +149,8 @@ A rewarded video allows you to display a video to a user, whereby they're able t
and receive nothing. For example, when a user completes a level on your gaming app, show them a video which will give them in-game and receive nothing. For example, when a user completes a level on your gaming app, show them a video which will give them in-game
credit. credit.
A single rewarded video instance can only be shown once. If you want to display another, create a new one.
?> It's recommended you begin loading the video as soon as possible. ?> It's recommended you begin loading the video as soon as possible.
To request an Rewarded Video from AdMob, the `loadAd` method must be called with an instance of `AdRequest` (see below for full API): To request an Rewarded Video from AdMob, the `loadAd` method must be called with an instance of `AdRequest` (see below for full API):
@ -203,8 +207,8 @@ in production.
##### build() ##### build()
Builds the current request for AdMob to handle. Builds the current request for AdMob to handle.
##### addTestDevice() ##### addTestDevice(device?: string)
Sets the current device as a test device. Sets a device ID as a test device. If no device string is passed, a default emulator id is passed.
##### addKeyword(keyword: `string`) ##### addKeyword(keyword: `string`)
Add a new keyword to relate the advert to. Add a new keyword to relate the advert to.
@ -224,7 +228,7 @@ Sets the request agent string to identify the ad request's origin. Third party l
##### setContentUrl(url: `string`) ##### setContentUrl(url: `string`)
Sets the content URL for targeting purposes. Sets the content URL for targeting purposes.
##### setIsDesignedForFamilies(forFamilies: `boolean`) ##### [android] setIsDesignedForFamilies(forFamilies: `boolean`)
If you set this value to true, you indicate that your app requires that the ad request should return a Designed for Families-compliant ad. If you set this value to true, you indicate that your app requires that the ad request should return a Designed for Families-compliant ad.
If you set this value to false, you indicate that your app does not require that the ad request should return a Designed for Families-compliant ad. If you set this value to false, you indicate that your app does not require that the ad request should return a Designed for Families-compliant ad.
@ -301,7 +305,7 @@ Called if the opened advert causes the user to leave the application, for exampl
Called when the user returns back to the application after closing an advert. Called when the user returns back to the application after closing an advert.
##### onAdFailedToLoad(error: `Error`) ##### onAdFailedToLoad(error: `Error`)
Called when an advert fails to load. Returns a JavaScript Error with one of the following error codes: Called when an advert fails to load. Returns a JavaScript Error with one of the following error codes.
| code | message | | code | message |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------ | | --------------------------------- | ------------------------------------------------------------------------------------------------------------ |
@ -309,6 +313,7 @@ Called when an advert fails to load. Returns a JavaScript Error with one of the
| admob/error-code-invalid-request | The ad request was invalid; for instance, the ad unit ID was incorrect. | | admob/error-code-invalid-request | The ad request was invalid; for instance, the ad unit ID was incorrect. |
| admob/error-code-network-error | The ad request was unsuccessful due to network connectivity. | | admob/error-code-network-error | The ad request was unsuccessful due to network connectivity. |
| admob/error-code-no-fill | The ad request was successful, but no ad was returned due to lack of ad inventory. | | admob/error-code-no-fill | The ad request was successful, but no ad was returned due to lack of ad inventory. |
| admob/os-version-too-low | The current devices OS is below the minimum required version. |
##### [NativeExpress] onVideoEnd() ##### [NativeExpress] onVideoEnd()
Called when a the video has ended. Called when a the video has ended.
@ -340,3 +345,13 @@ Used to build a request object to pass into AdMob requests.
### VideoOptions ### VideoOptions
Used to build an options object for how videos should be handled with adverts containing a video. Used to build an options object for how videos should be handled with adverts containing a video.
### EventTypes
Returns all of the available advert event types.
### RewardedVideoEventTypes
Returns the extra event types for Rewarded Videos.
### NativeExpressEventTypes
Returns the extra event types for Native Express adverts.

View File

@ -11,9 +11,11 @@
#import "GoogleMobileAds/GADAdDelegate.h" #import "GoogleMobileAds/GADAdDelegate.h"
@interface RNFirebaseAdMob : RCTEventEmitter <RCTBridgeModule, GADInterstitialDelegate, GADAdDelegate> { @interface RNFirebaseAdMob : RCTEventEmitter <RCTBridgeModule, GADInterstitialDelegate, GADAdDelegate>
}
@property NSMutableDictionary *interstitials; @property NSMutableDictionary *interstitials;
- (GADRequest *)buildRequest:(NSDictionary *)request;
- (NSDictionary *)errorCodeToDictionary:(NSError *)error;
@end @end
#else #else

View File

@ -3,6 +3,10 @@
#import "RNFirebaseAdMobInterstitial.h" #import "RNFirebaseAdMobInterstitial.h"
NSString *MALE = @"male";
NSString *FEMALE = @"female";
NSString *UNKNOWN = @"unknown";
@implementation RNFirebaseAdMob @implementation RNFirebaseAdMob
RCT_EXPORT_MODULE(); RCT_EXPORT_MODULE();
@ -18,27 +22,32 @@ RCT_EXPORT_MODULE();
return dispatch_get_main_queue(); return dispatch_get_main_queue();
} }
RCT_EXPORT_METHOD(initialize:(NSString *)appId) { RCT_EXPORT_METHOD(initialize:
(NSString *) appId) {
[GADMobileAds configureWithApplicationID:appId]; [GADMobileAds configureWithApplicationID:appId];
} }
RCT_EXPORT_METHOD(interstitialShowAd:(NSString *)adUnit) { RCT_EXPORT_METHOD(interstitialShowAd:
RNFirebaseAdMobInterstitial * interstitial = [self getOrCreateInterstitial:adUnit]; (NSString *) adUnit) {
RNFirebaseAdMobInterstitial *interstitial = [self getOrCreateInterstitial:adUnit];
[interstitial showAd]; [interstitial showAd];
} }
RCT_EXPORT_METHOD(interstitialLoadAd:(NSString *)adUnit request:(NSDictionary *) request) { RCT_EXPORT_METHOD(interstitialLoadAd:
RNFirebaseAdMobInterstitial * interstitial = [self getOrCreateInterstitial:adUnit]; (NSString *) adUnit
[interstitial loadAd]; request:
(NSDictionary *) request) {
RNFirebaseAdMobInterstitial *interstitial = [self getOrCreateInterstitial:adUnit];
[interstitial loadAd:request];
} }
- (RNFirebaseAdMobInterstitial *) getOrCreateInterstitial:(NSString *)adUnit { - (RNFirebaseAdMobInterstitial *)getOrCreateInterstitial:(NSString *)adUnit {
if (_interstitials[adUnit]) { if (_interstitials[adUnit]) {
return _interstitials[adUnit]; return _interstitials[adUnit];
} }
_interstitials[adUnit] = [[RNFirebaseAdMobInterstitial alloc] initWithProps:adUnit delegate:self]; _interstitials[adUnit] = [[RNFirebaseAdMobInterstitial alloc] initWithProps:adUnit delegate:self];
return _interstitials[adUnit]; return _interstitials[adUnit];
} }
@ -46,4 +55,72 @@ RCT_EXPORT_METHOD(interstitialLoadAd:(NSString *)adUnit request:(NSDictionary *)
return @[ADMOB_INTERSTITIAL_EVENT, ADMOB_REWARDED_VIDEO_EVENT]; return @[ADMOB_INTERSTITIAL_EVENT, ADMOB_REWARDED_VIDEO_EVENT];
} }
- (GADRequest *)buildRequest:(NSDictionary *)request {
GADRequest *builder = [GADRequest request];
if (request[@"tagForChildDirectedTreatment"]) [builder tagForChildDirectedTreatment:(BOOL) request[@"tagForChildDirectedTreatment"]];
if (request[@"contentUrl"]) builder.contentURL = request[@"contentUrl"];
if (request[@"requestAgent"]) builder.requestAgent = request[@"requestAgent"];
if (request[@"keywords"]) builder.keywords = request[@"keywords"];
if (request[@"testDevices"]) builder.testDevices = request[@"testDevices"];
if (request[@"gender"]) {
NSString *gender = [request[@"gender"] stringValue];
if (gender == MALE) {
builder.gender = kGADGenderMale;
} else if (gender == FEMALE) {
builder.gender = kGADGenderFemale;
} else if (gender == UNKNOWN) {
builder.gender = kGADGenderUnknown;
}
}
return builder;
}
- (NSDictionary *)errorCodeToDictionary:(NSError *)error {
NSString *code;
NSString *message;
switch (error.code) {
default:
case kGADErrorServerError:
case kGADErrorInternalError:
case kGADErrorInvalidArgument:
case kGADErrorMediationDataError:
case kGADErrorMediationAdapterError:
code = @"admob/error-code-internal-error ";
message = @"Something happened internally; for instance, an invalid response was received from the ad server.";
break;
case kGADErrorMediationInvalidAdSize:
code = @"admob/error-code-invalid-request";
message = @"The ad requested has an invalid size.";
break;
case kGADErrorInvalidRequest:
case kGADErrorReceivedInvalidResponse:
code = @"admob/error-code-invalid-request";
message = @"The ad request was invalid; for instance, the ad unit ID was incorrect.";
break;
case kGADErrorNoFill:
case kGADErrorMediationNoFill:
code = @"admob/error-code-no-fill";
message = @"The ad request was successful, but no ad was returned due to lack of ad inventory.";
break;
case kGADErrorNetworkError:
code = @"admob/error-code-network-error";
message = @"The ad request was unsuccessful due to network connectivity.";
break;
case kGADErrorOSVersionTooLow:
code = @"admob/os-version-too-low";
message = @"The current devices OS is below the minimum required version.";
break;
}
return @{
@"code": code,
@"message": message,
};
}
@end @end

View File

@ -2,6 +2,7 @@
#define RNFirebaseAdMobInterstitial_h #define RNFirebaseAdMobInterstitial_h
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
#import "RNFirebaseEvents.h"
#if __has_include(<GoogleMobileAds/GADMobileAds.h>) #if __has_include(<GoogleMobileAds/GADMobileAds.h>)
@ -18,7 +19,8 @@
- (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate; - (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate;
- (void)showAd; - (void)showAd;
- (void)loadAd; - (void)loadAd:(NSDictionary *)request;
- (void)sendJSEvent:(NSString *)type payload:(nullable NSDictionary *)payload;
@end @end

View File

@ -1,6 +1,5 @@
#import "RNFirebaseAdMobInterstitial.h" #import "RNFirebaseAdMobInterstitial.h"
@implementation RNFirebaseAdMobInterstitial @implementation RNFirebaseAdMobInterstitial
- (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate { - (id)initWithProps:(NSString *)adUnit delegate:(RNFirebaseAdMob *)delegate {
@ -15,17 +14,50 @@
- (GADInterstitial *)createInterstitial { - (GADInterstitial *)createInterstitial {
GADInterstitial *interstitial = [[GADInterstitial alloc] initWithAdUnitID:_adUnitID]; GADInterstitial *interstitial = [[GADInterstitial alloc] initWithAdUnitID:_adUnitID];
interstitial.delegate = _delegate; interstitial.delegate = self;
return interstitial; return interstitial;
} }
- (void) loadAd { - (void)loadAd:(NSDictionary *)request {
// todo build request [_interstitial loadRequest:[_delegate buildRequest:request]];
[_interstitial loadRequest:[GADRequest request]];
} }
- (void)showAd { - (void)showAd {
[_interstitial presentFromRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController]; if (_interstitial.isReady) {
[_interstitial presentFromRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController];
}
}
- (void)sendJSEvent:(NSString *)type payload:(NSDictionary *)payload {
if (payload == nil) {
payload = @{};
}
[_delegate sendEventWithName:ADMOB_INTERSTITIAL_EVENT body:@{
@"type": type,
@"adUnit": _adUnitID,
@"payload": payload
}];
}
- (void)interstitialDidReceiveAd:(nonnull GADInterstitial *)ad {
[self sendJSEvent:@"onAdLoaded" payload:@{}];
}
- (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error {
[self sendJSEvent:@"onAdFailedToLoad" payload:[_delegate errorCodeToDictionary:error]];
}
- (void)interstitialWillPresentScreen:(GADInterstitial *)ad {
[self sendJSEvent:@"onAdOpened" payload:@{}];
}
- (void)interstitialDidDismissScreen:(GADInterstitial *)ad {
[self sendJSEvent:@"onAdClosed" payload:@{}];
}
- (void)interstitialWillLeaveApplication:(GADInterstitial *)ad {
[self sendJSEvent:@"onAdLeftApplication" payload:@{}];
} }
@end @end

View File

@ -1,8 +1,9 @@
import { NativeModules } from 'react-native'; import { NativeModules } from 'react-native';
import { statics } from './'; import { statics } from './';
import AdRequest from './AdRequest';
import { nativeToJSError } from '../../utils'; import { nativeToJSError } from '../../utils';
const FirebaseAdMob = NativeModules.RNFirebaseAdmob; const FirebaseAdMob = NativeModules.RNFirebaseAdMob;
export default class Interstitial { export default class Interstitial {
@ -43,8 +44,14 @@ export default class Interstitial {
* @param request * @param request
* @returns {*} * @returns {*}
*/ */
loadAd(request: Object) { loadAd(request?: AdRequest) {
return FirebaseAdMob.interstitialLoadAd(this.adUnit, request); let adRequest = request;
if (!adRequest || !Object.keys(adRequest)) {
adRequest = new AdRequest().addTestDevice().build();
}
return FirebaseAdMob.interstitialLoadAd(this.adUnit, adRequest);
} }
/** /**