Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sbugert committed Dec 8, 2015
0 parents commit c48e951
Show file tree
Hide file tree
Showing 11 changed files with 709 additions and 0 deletions.
55 changes: 55 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
build/
DerivedData

## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata

## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint

## Obj-C/Swift specific
*.hmap
*.ipa

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md

fastlane/report.xml
fastlane/screenshots

node_modules/**/*
23 changes: 23 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Copyright (c) 2015, Simon Bugert
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## react-native-admob

A react-native component for Google AdMob banners (currently only iOS.)

### Installation

1. `npm i react-native-admob -S`
2. Add [Google AdMob Framework](https://developers.google.com/admob/ios/quick-start#manually_using_the_sdk_download) to your Xcode project.
3. Add react-native-admob static library to your Xcode project like explained [here](http://facebook.github.io/react-native/docs/linking-libraries-ios.html).
4. To use it in your javascript code you can `import Banner from 'react-native-admob'` or `var Banner = require("react-native-admob")`

### Usage

```javascript
<Banner
bannerSize={"fullBanner"}
adUnitID={"your-admob-unit-id"}
didFailToReceiveAdWithError={this.bannerError} />
```

### Props
##### bannerSize
*Corresponding to [iOS framework banner size constants](https://developers.google.com/admob/ios/banner)*

* *banner* (320x50, Standard Banner for Phones and Tablets)
* *largeBanner* (320x100, Large Banner for Phones and Tablets)
* *mediumRectangle* (300x250, IAB Medium Rectangle for Phones and Tablets)
* *fullBanner* (468x60, IAB Full-Size Banner for Tablets)
* *leaderboard* (728x90, IAB Leaderboard for Tablets)
* *smartBannerPortrait* (Screen width x 32|50|90, Smart Banner for Phones and Tablets)
* *smartBannerLandscape* (Screen width x 32|50|90, Smart Banner for Phones and Tablets)

##### Events
*Corresponding to [Ad lifecycle event callbacks](https://developers.google.com/admob/ios/banner)*

* adViewDidReceiveAd()
* didFailToReceiveAdWithError(errorDescription)
* adViewWillPresentScreen()
* adViewWillDismissScreen()
* adViewDidDismissScreen()
* adViewWillLeaveApplication()


---

### TODO
- [ ] Add Interstitial Ads support
- [ ] Add Android support
- [ ] Add example project
15 changes: 15 additions & 0 deletions RNAdMobManager/BannerView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#import "RCTEventDispatcher.h"
@import GoogleMobileAds;

@class RCTEventDispatcher;

@interface BannerView : UIView <GADBannerViewDelegate>

@property (nonatomic, copy) NSString *bannerSize;
@property (nonatomic, copy) NSString *adUnitID;

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
- (GADAdSize)getAdSizeFromString:(NSString *)bannerSize;
- (void)loadBanner;

@end
152 changes: 152 additions & 0 deletions RNAdMobManager/BannerView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#import "BannerView.h"
#import "RCTBridgeModule.h"
#import "UIView+React.h"
#import "RCTLog.h"

@implementation BannerView {
GADBannerView *_bannerView;
RCTEventDispatcher *_eventDispatcher;
}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
if ((self = [super initWithFrame:CGRectZero])) {
_eventDispatcher = eventDispatcher;
}
return self;
}

RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)

- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
{
RCTLogError(@"AdMob Banner cannot have any subviews");
return;
}

- (void)removeReactSubview:(UIView *)subview
{
RCTLogError(@"AdMob Banner cannot have any subviews");
return;
}

- (GADAdSize)getAdSizeFromString:(NSString *)bannerSize
{
if ([bannerSize isEqualToString:@"banner"]) {
return kGADAdSizeBanner;
} else if ([bannerSize isEqualToString:@"largeBanner"]) {
return kGADAdSizeLargeBanner;
} else if ([bannerSize isEqualToString:@"mediumRectangle"]) {
return kGADAdSizeMediumRectangle;
} else if ([bannerSize isEqualToString:@"fullBanner"]) {
return kGADAdSizeFullBanner;
} else if ([bannerSize isEqualToString:@"leaderboard"]) {
return kGADAdSizeLeaderboard;
} else if ([bannerSize isEqualToString:@"smartBannerPortrait"]) {
return kGADAdSizeSmartBannerPortrait;
} else if ([bannerSize isEqualToString:@"smartBannerLandscape"]) {
return kGADAdSizeSmartBannerLandscape;
}
else {
return kGADAdSizeBanner;
}
}

-(void)loadBanner {
if (_adUnitID && _bannerSize) {
GADAdSize size = [self getAdSizeFromString:_bannerSize];
_bannerView = [[GADBannerView alloc] initWithAdSize:size];
if(!CGRectEqualToRect(self.bounds, _bannerView.bounds)) {
[_eventDispatcher
sendInputEventWithName:@"onSizeChange"
body:@{
@"target": self.reactTag,
@"width": [NSNumber numberWithFloat: _bannerView.bounds.size.width],
@"height": [NSNumber numberWithFloat: _bannerView.bounds.size.height]
}];
}
_bannerView.delegate = self;
_bannerView.adUnitID = _adUnitID;
_bannerView.rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
[_bannerView loadRequest:[GADRequest request]];
}
}

- (void)setBannerSize:(NSString *)bannerSize
{
if(![bannerSize isEqual:_bannerSize]) {
_bannerSize = bannerSize;
if (_bannerView) {
[_bannerView removeFromSuperview];
}
[self loadBanner];
}
}



- (void)setAdUnitID:(NSString *)adUnitID
{
if(![adUnitID isEqual:_adUnitID]) {
_adUnitID = adUnitID;
if (_bannerView) {
[_bannerView removeFromSuperview];
}

[self loadBanner];
}
}

-(void)layoutSubviews
{
[super layoutSubviews ];

_bannerView.frame = CGRectMake(
self.bounds.origin.x,
self.bounds.origin.x,
_bannerView.frame.size.width,
_bannerView.frame.size.height);
[self addSubview:_bannerView];
}

- (void)removeFromSuperview
{
_eventDispatcher = nil;
[super removeFromSuperview];
}

/// Tells the delegate an ad request loaded an ad.
- (void)adViewDidReceiveAd:(GADBannerView *)adView {
[_eventDispatcher sendInputEventWithName:@"onAdViewDidReceiveAd" body:@{ @"target": self.reactTag }];
}

/// Tells the delegate an ad request failed.
- (void)adView:(GADBannerView *)adView
didFailToReceiveAdWithError:(GADRequestError *)error {
[_eventDispatcher sendInputEventWithName:@"onDidFailToReceiveAdWithError" body:@{ @"target": self.reactTag, @"error": [error localizedDescription] }];
}

/// Tells the delegate that a full screen view will be presented in response
/// to the user clicking on an ad.
- (void)adViewWillPresentScreen:(GADBannerView *)adView {
[_eventDispatcher sendInputEventWithName:@"onAdViewWillPresentScreen" body:@{ @"target": self.reactTag }];
}

/// Tells the delegate that the full screen view will be dismissed.
- (void)adViewWillDismissScreen:(GADBannerView *)adView {
[_eventDispatcher sendInputEventWithName:@"onAdViewWillDismissScreen" body:@{ @"target": self.reactTag }];
}

/// Tells the delegate that the full screen view has been dismissed.
- (void)adViewDidDismissScreen:(GADBannerView *)adView {
[_eventDispatcher sendInputEventWithName:@"onAdViewDidDismissScreen" body:@{ @"target": self.reactTag }];
}

/// Tells the delegate that a user click will open another app (such as
/// the App Store), backgrounding the current app.
- (void)adViewWillLeaveApplication:(GADBannerView *)adView {
[_eventDispatcher sendInputEventWithName:@"onAdViewWillLeaveApplication" body:@{ @"target": self.reactTag }];
}

@end
5 changes: 5 additions & 0 deletions RNAdMobManager/RNAdMobManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import "RCTViewManager.h"

@interface RNAdMobManager : RCTViewManager

@end
40 changes: 40 additions & 0 deletions RNAdMobManager/RNAdMobManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#import "RNAdMobManager.h"
#import "BannerView.h"

#import "RCTBridge.h"

@implementation RNAdMobManager

RCT_EXPORT_MODULE();

@synthesize bridge = _bridge;

- (UIView *)view
{
return [[BannerView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
}

- (NSArray *) customDirectEventTypes
{
return @[
@"onSizeChange",
@"onAdViewDidReceiveAd",
@"onDidFailToReceiveAdWithError",
@"onAdViewWillPresentScreen",
@"onAdViewWillDismissScreen",
@"onAdViewDidDismissScreen",
@"onAdViewWillLeaveApplication"
];
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}


RCT_EXPORT_VIEW_PROPERTY(bannerSize, NSString);
RCT_EXPORT_VIEW_PROPERTY(adUnitID, NSString);

@end

Loading

0 comments on commit c48e951

Please sign in to comment.