[ios][admob] Implement NativeExpress
This commit is contained in:
parent
0e27d7345e
commit
d159d9bb6b
@ -282,7 +282,7 @@ adverts (e.g. Interstitial) they're available via the `on` method.
|
||||
##### onAdLoaded(config: `Object`)
|
||||
!> The config is not provided for Interstitial or Rewarded Video adverts.
|
||||
|
||||
On successful response from the AdMob servers.
|
||||
On successful response from the AdMob servers. This is also called when a new banner is automatically loaded from the AdMob servers if the current one expires.
|
||||
|
||||
Returns an object of config data related to the loaded advert:
|
||||
```js
|
||||
|
@ -21,7 +21,7 @@
|
||||
@end
|
||||
#else
|
||||
|
||||
@interface RNFirebaseAdMobBanner : NSObject <RCTBridgeModule> {
|
||||
@interface BannerComponent : NSObject <RCTBridgeModule> {
|
||||
}
|
||||
@end
|
||||
|
||||
|
31
ios/RNFirebase/admob/NativeExpressComponent.h
Normal file
31
ios/RNFirebase/admob/NativeExpressComponent.h
Normal file
@ -0,0 +1,31 @@
|
||||
#import <React/RCTComponent.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
#if __has_include(<GoogleMobileAds/GADMobileAds.h>)
|
||||
|
||||
#import "GoogleMobileAds/GADNativeExpressAdView.h"
|
||||
#import "GoogleMobileAds/GADVideoControllerDelegate.h"
|
||||
|
||||
@interface NativeExpressComponent : UIView <GADNativeExpressAdViewDelegate, GADVideoControllerDelegate>
|
||||
|
||||
@property GADNativeExpressAdView *banner;
|
||||
//@property(nonatomic, weak) IBOutlet GADNativeExpressAdView *banner;
|
||||
@property (nonatomic, assign) BOOL requested;
|
||||
|
||||
@property (nonatomic, copy) NSString *size;
|
||||
@property (nonatomic, copy) NSString *unitId;
|
||||
@property (nonatomic, copy) NSDictionary *request;
|
||||
@property (nonatomic, copy) NSDictionary *video;
|
||||
|
||||
@property (nonatomic, copy) RCTBubblingEventBlock onBannerEvent;
|
||||
|
||||
- (void)requestAd;
|
||||
|
||||
@end
|
||||
#else
|
||||
|
||||
@interface NativeExpressComponent : NSObject <RCTBridgeModule> {
|
||||
}
|
||||
@end
|
||||
|
||||
#endif
|
96
ios/RNFirebase/admob/NativeExpressComponent.m
Normal file
96
ios/RNFirebase/admob/NativeExpressComponent.m
Normal file
@ -0,0 +1,96 @@
|
||||
#import "NativeExpressComponent.h"
|
||||
#import "RNFirebaseAdMob.h"
|
||||
#import "React/UIView+React.h"
|
||||
|
||||
@implementation NativeExpressComponent
|
||||
|
||||
- (void)initBanner:(GADAdSize)adSize {
|
||||
if (_requested) {
|
||||
[_banner removeFromSuperview];
|
||||
}
|
||||
_banner = [[GADNativeExpressAdView alloc] initWithAdSize:adSize];
|
||||
_banner.rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
|
||||
_banner.delegate = self;
|
||||
_banner.videoController.delegate = self;
|
||||
}
|
||||
|
||||
- (void)setUnitId:(NSString *)unitId {
|
||||
_unitId = unitId;
|
||||
[self requestAd];
|
||||
}
|
||||
|
||||
- (void)setSize:(NSString *)size {
|
||||
_size = size;
|
||||
[self requestAd];
|
||||
}
|
||||
|
||||
- (void)setRequest:(NSDictionary *)request {
|
||||
_request = request;
|
||||
[self requestAd];
|
||||
}
|
||||
|
||||
- (void)setVideo:(NSDictionary *)video {
|
||||
_video = video;
|
||||
[self requestAd];
|
||||
}
|
||||
|
||||
- (void)requestAd {
|
||||
if (_unitId == nil || _size == nil || _request == nil || _video == nil) {
|
||||
[self setRequested:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
[self initBanner:[RNFirebaseAdMob stringToAdSize:_size]];
|
||||
[self addSubview:_banner];
|
||||
|
||||
[self sendEvent:@"onSizeChange" payload:@{
|
||||
@"width": @(_banner.bounds.size.width),
|
||||
@"height": @(_banner.bounds.size.height),
|
||||
}];
|
||||
|
||||
_banner.adUnitID = _unitId;
|
||||
[self setRequested:YES];
|
||||
[_banner setAdOptions:@[[RNFirebaseAdMob buildVideoOptions:_video]]];
|
||||
[_banner loadRequest:[RNFirebaseAdMob buildRequest:_request]];
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSString *)type payload:(NSDictionary *_Nullable)payload {
|
||||
self.onBannerEvent(@{
|
||||
@"type": type,
|
||||
@"payload": payload != nil ? payload : [NSNull null],
|
||||
});
|
||||
}
|
||||
|
||||
- (void)nativeExpressAdViewDidReceiveAd:(GADNativeExpressAdView *)adView {
|
||||
[self sendEvent:@"onAdLoaded" payload:@{
|
||||
@"width": @(adView.bounds.size.width),
|
||||
@"height": @(adView.bounds.size.height),
|
||||
@"hasVideoContent": @(adView.videoController.hasVideoContent),
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)nativeExpressAdView:(nonnull GADNativeExpressAdView *)nativeExpressAdView didFailToReceiveAdWithError:(nonnull GADRequestError *)error {
|
||||
[self sendEvent:@"onAdFailedToLoad" payload:[RNFirebaseAdMob errorCodeToDictionary:error]];
|
||||
}
|
||||
|
||||
- (void)nativeExpressAdViewWillPresentScreen:(GADNativeExpressAdView *)adView {
|
||||
[self sendEvent:@"onAdOpened" payload:nil];
|
||||
}
|
||||
|
||||
- (void)nativeExpressAdViewWillDismissScreen:(GADNativeExpressAdView *)adView {
|
||||
// not in use
|
||||
}
|
||||
|
||||
- (void)nativeExpressAdViewDidDismissScreen:(GADNativeExpressAdView *)adView {
|
||||
[self sendEvent:@"onAdClosed" payload:nil];
|
||||
}
|
||||
|
||||
- (void)nativeExpressAdViewWillLeaveApplication:(GADNativeExpressAdView *)adView {
|
||||
[self sendEvent:@"onAdLeftApplication" payload:nil];
|
||||
}
|
||||
|
||||
- (void)videoControllerDidEndVideoPlayback:(GADVideoController *)videoController {
|
||||
[self sendEvent:@"onVideoEnd" payload:nil];
|
||||
}
|
||||
|
||||
@end
|
@ -17,6 +17,7 @@
|
||||
@property NSMutableDictionary *rewardedVideos;
|
||||
|
||||
+ (GADRequest *)buildRequest:(NSDictionary *)request;
|
||||
+ (GADVideoOptions *)buildVideoOptions:(NSDictionary *)options;
|
||||
+ (NSDictionary *)errorCodeToDictionary:(NSError *)error;
|
||||
+ (GADAdSize)stringToAdSize:(NSString *)value;
|
||||
@end
|
||||
|
@ -88,8 +88,8 @@ RCT_EXPORT_METHOD(rewardedVideoShowAd:
|
||||
if (request[@"keywords"]) builder.keywords = request[@"keywords"];
|
||||
|
||||
if (request[@"testDevices"]) {
|
||||
NSArray * devices = request[@"testDevices"];
|
||||
NSMutableArray * testDevices = [[NSMutableArray alloc] init];
|
||||
NSArray *devices = request[@"testDevices"];
|
||||
NSMutableArray *testDevices = [[NSMutableArray alloc] init];
|
||||
|
||||
for (id device in devices) {
|
||||
if ([device isEqual:@"DEVICE_ID_EMULATOR"]) {
|
||||
@ -117,6 +117,12 @@ RCT_EXPORT_METHOD(rewardedVideoShowAd:
|
||||
return builder;
|
||||
}
|
||||
|
||||
+ (GADVideoOptions *)buildVideoOptions:(NSDictionary *)options {
|
||||
GADVideoOptions *builder = [[GADVideoOptions alloc] init];
|
||||
builder.startMuted = (BOOL) options[@"startMuted"];
|
||||
return builder;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)errorCodeToDictionary:(NSError *)error {
|
||||
NSString *code;
|
||||
NSString *message;
|
||||
@ -162,6 +168,22 @@ RCT_EXPORT_METHOD(rewardedVideoShowAd:
|
||||
}
|
||||
|
||||
+ (GADAdSize)stringToAdSize:(NSString *)value {
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"([0-9]+)x([0-9]+)" options:0 error:&error];
|
||||
NSArray *matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])];
|
||||
|
||||
for (NSTextCheckingResult *match in matches) {
|
||||
NSString *matchText = [value substringWithRange:[match range]];
|
||||
if (matchText) {
|
||||
NSArray *values = [matchText componentsSeparatedByString:@"x"];
|
||||
CGFloat width = (CGFloat)[values[0] intValue];
|
||||
CGFloat height = (CGFloat)[values[1] intValue];
|
||||
return GADAdSizeFromCGSize(CGSizeMake(width, height));
|
||||
}
|
||||
}
|
||||
|
||||
value = [value uppercaseString];
|
||||
|
||||
if ([value isEqualToString:@"BANNER"]) {
|
||||
return kGADAdSizeBanner;
|
||||
} else if ([value isEqualToString:@"LARGE_BANNER"]) {
|
||||
|
@ -0,0 +1,5 @@
|
||||
#import <React/RCTViewManager.h>
|
||||
|
||||
@interface RNFirebaseAdMobNativeExpressManager : RCTViewManager
|
||||
|
||||
@end
|
28
ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.m
Normal file
28
ios/RNFirebase/admob/RNFirebaseAdMobNativeExpressManager.m
Normal file
@ -0,0 +1,28 @@
|
||||
#import "RNFirebaseAdMobNativeExpressManager.h"
|
||||
#import "NativeExpressComponent.h"
|
||||
|
||||
@implementation RNFirebaseAdMobNativeExpressManager
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [[NativeExpressComponent alloc] init];
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
return dispatch_get_main_queue();
|
||||
}
|
||||
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(size, NSString);
|
||||
RCT_EXPORT_VIEW_PROPERTY(unitId, NSString);
|
||||
RCT_EXPORT_VIEW_PROPERTY(request, NSDictionary);
|
||||
RCT_EXPORT_VIEW_PROPERTY(video, NSDictionary);
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(onBannerEvent, RCTBubblingEventBlock);
|
||||
|
||||
@end
|
@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import { requireNativeComponent } from 'react-native';
|
||||
import AdMobComponent from './AdMobComponent';
|
||||
|
||||
function NativeExpress({ ...props }) {
|
||||
@ -14,7 +13,8 @@ function NativeExpress({ ...props }) {
|
||||
NativeExpress.propTypes = AdMobComponent.propTypes;
|
||||
|
||||
NativeExpress.defaultProps = {
|
||||
unitId: 'ca-app-pub-3940256099942544/2177258514',
|
||||
// unitId: 'ca-app-pub-3940256099942544/2177258514',
|
||||
unitId: 'ca-app-pub-3940256099942544/8897359316',
|
||||
size: 'SMART_BANNER',
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user