From 5bcc4e70bc04d644390a7b8a0c2354909541b5c6 Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Sat, 22 Sep 2012 18:04:31 -0700 Subject: [PATCH 1/7] Initial commit of Android and iOS AdMob plugins. --- Android/AdMobPlugin/AdMobPlugin.java | 313 +++++++++++++++++++++++++++ Android/AdMobPlugin/AdMobPlugin.js | 129 +++++++++++ Android/AdMobPlugin/README.md | 75 +++++++ iOS/AdMobPlugin/AdMobPlugin.h | 33 +++ iOS/AdMobPlugin/AdMobPlugin.js | 132 +++++++++++ iOS/AdMobPlugin/AdMobPlugin.m | 298 +++++++++++++++++++++++++ iOS/AdMobPlugin/README.md | 78 +++++++ 7 files changed, 1058 insertions(+) create mode 100644 Android/AdMobPlugin/AdMobPlugin.java create mode 100644 Android/AdMobPlugin/AdMobPlugin.js create mode 100644 Android/AdMobPlugin/README.md create mode 100644 iOS/AdMobPlugin/AdMobPlugin.h create mode 100644 iOS/AdMobPlugin/AdMobPlugin.js create mode 100644 iOS/AdMobPlugin/AdMobPlugin.m create mode 100644 iOS/AdMobPlugin/README.md diff --git a/Android/AdMobPlugin/AdMobPlugin.java b/Android/AdMobPlugin/AdMobPlugin.java new file mode 100644 index 00000000..90f80449 --- /dev/null +++ b/Android/AdMobPlugin/AdMobPlugin.java @@ -0,0 +1,313 @@ +package com.google.cordova.plugin; + +import com.google.ads.Ad; +import com.google.ads.AdListener; +import com.google.ads.AdRequest; +import com.google.ads.AdRequest.ErrorCode; +import com.google.ads.AdSize; +import com.google.ads.AdView; +import com.google.ads.mediation.admob.AdMobAdapterExtras; + +import android.util.Log; + +import org.apache.cordova.LinearLayoutSoftKeyboardDetect; +import org.apache.cordova.api.Plugin; +import org.apache.cordova.api.PluginResult; +import org.apache.cordova.api.PluginResult.Status; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Iterator; + +/** + * This class represents the native implementation for the AdMob Cordova plugin. + * This plugin can be used to request AdMob ads natively via the Google AdMob SDK. + * The Google AdMob SDK is a dependency for this plugin. + */ +public class AdMobPlugin extends Plugin { + /** The adView to display to the user. */ + private AdView adView; + + /** Whether or not the ad should be positioned at top or bottom of screen. */ + private boolean positionAtTop; + + /** Common tag used for logging statements. */ + private static final String LOGTAG = "AdMobPlugin"; + + /** Cordova Actions. */ + private static final String ACTION_CREATE_BANNER_VIEW = "createBannerView"; + private static final String ACTION_REQUEST_AD = "requestAd"; + + /** + * This is the main method for the AdMob plugin. All API calls go through here. + * This method determines the action, and executes the appropriate call. + * + * @param action The action that the plugin should execute. + * @param inputs The input parameters for the action. + * @param callbackId The callback ID. This is currently unused. + * @return A PluginResult representing the result of the provided action. A + * status of INVALID_ACTION is returned if the action is not recognized. + */ + @Override + public PluginResult execute(String action, JSONArray inputs, String callbackId) { + PluginResult result = null; + if (ACTION_CREATE_BANNER_VIEW.equals(action)) { + result = executeCreateBannerView(inputs); + } else if (ACTION_REQUEST_AD.equals(action)) { + result = executeRequestAd(inputs); + } else { + Log.d(LOGTAG, String.format("Invalid action passed: %s", action)); + result = new PluginResult(Status.INVALID_ACTION); + } + return result; + } + + /** + * Parses the create banner view input parameters and runs the create banner + * view action on the UI thread. If this request is successful, the developer + * should make the requestAd call to request an ad for the banner. + * + * @param inputs The JSONArray representing input parameters. This function + * expects the first object in the array to be a JSONObject with the + * input parameters. + * @return A PluginResult representing whether or not the banner was created + * successfully. + */ + private PluginResult executeCreateBannerView(JSONArray inputs) { + String publisherId; + String size; + + // Get the input data. + try { + JSONObject data = inputs.getJSONObject(0); + publisherId = data.getString("publisherId"); + size = data.getString("adSize"); + this.positionAtTop = data.getBoolean("positionAtTop"); + } catch (JSONException exception) { + Log.w(LOGTAG, String.format("Got JSON Exception: %s", exception.getMessage())); + return new PluginResult(Status.JSON_EXCEPTION); + } + + // Create the AdView on the UI thread. + return executeRunnable(new CreateBannerViewRunnable( + publisherId, adSizeFromSize(size))); + } + + /** + * Parses the request ad input parameters and runs the request ad action on + * the UI thread. + * + * @param inputs The JSONArray representing input parameters. This function + * expects the first object in the array to be a JSONObject with the + * input parameters. + * @return A PluginResult representing whether or not an ad was requested + * succcessfully. Listen for onReceiveAd() and onFailedToReceiveAd() + * callbacks to see if an ad was successfully retrieved. + */ + private PluginResult executeRequestAd(JSONArray inputs) { + boolean isTesting; + JSONObject inputExtras; + + // Get the input data. + try { + JSONObject data = inputs.getJSONObject(0); + isTesting = data.getBoolean("isTesting"); + inputExtras = data.getJSONObject("extras"); + } catch (JSONException exception) { + Log.w(LOGTAG, String.format("Got JSON Exception: %s", exception.getMessage())); + return new PluginResult(Status.JSON_EXCEPTION); + } + + // Request an ad on the UI thread. + return executeRunnable(new RequestAdRunnable(isTesting, inputExtras)); + } + + /** + * Executes the runnable on the activity from the plugin's context. This + * is a blocking call that waits for a notification from the runnable + * before it continues. + * + * @param runnable The AdMobRunnable representing the command to run. + * @return A PluginResult representing the result of the command. + */ + private PluginResult executeRunnable(AdMobRunnable runnable) { + synchronized (runnable) { + cordova.getActivity().runOnUiThread(runnable); + try { + runnable.wait(); + } catch (InterruptedException exception) { + Log.w(LOGTAG, String.format("Interrupted Exception: %s", exception.getMessage())); + return new PluginResult(Status.ERROR, "Interruption occurred when running on UI thread"); + } + } + return runnable.getPluginResult(); + } + + /** + * Represents a runnable for the AdMob plugin that will run on the UI thread. + */ + private abstract class AdMobRunnable implements Runnable { + protected PluginResult result; + + public PluginResult getPluginResult() { + return result; + } + } + + /** Runnable for the createBannerView action. */ + private class CreateBannerViewRunnable extends AdMobRunnable { + private String publisherId; + private AdSize adSize; + + public CreateBannerViewRunnable(String publisherId, AdSize adSize) { + this.publisherId = publisherId; + this.adSize = adSize; + result = new PluginResult(Status.NO_RESULT); + } + + @Override + public void run() { + if (adSize == null) { + result = new PluginResult(Status.ERROR, "AdSize is null. Did you use an AdSize constant?"); + } else { + adView = new AdView(cordova.getActivity(), adSize, publisherId); + adView.setAdListener(new BannerListener()); + LinearLayoutSoftKeyboardDetect parentView = + (LinearLayoutSoftKeyboardDetect) webView.getParent(); + if (positionAtTop) { + parentView.addView(adView, 0); + } else { + parentView.addView(adView); + } + // Notify the plugin. + result = new PluginResult(Status.OK); + } + synchronized (this) { + this.notify(); + } + } + } + + /** Runnable for the requestAd action. */ + private class RequestAdRunnable extends AdMobRunnable { + private boolean isTesting; + private JSONObject inputExtras; + + public RequestAdRunnable(boolean isTesting, JSONObject inputExtras) { + this.isTesting = isTesting; + this.inputExtras = inputExtras; + result = new PluginResult(Status.NO_RESULT); + } + + @SuppressWarnings("unchecked") + @Override + public void run() { + if (adView == null) { + result = new PluginResult(Status.ERROR, "AdView is null. Did you call createBannerView?"); + } else { + AdRequest request = new AdRequest(); + if (isTesting) { + // This will request test ads on the emulator only. You can get your + // hashed device ID from LogCat when making a live request. Pass + // this hashed device ID to addTestDevice request test ads on your + // device. + request.addTestDevice(AdRequest.TEST_EMULATOR); + } + AdMobAdapterExtras extras = new AdMobAdapterExtras(); + Iterator extrasIterator = inputExtras.keys(); + boolean inputValid = true; + while (extrasIterator.hasNext()) { + String key = extrasIterator.next(); + try { + extras.addExtra(key, inputExtras.get(key)); + } catch (JSONException exception) { + Log.w(LOGTAG, String.format("Caught JSON Exception: %s", exception.getMessage())); + result = new PluginResult(Status.JSON_EXCEPTION, "Error grabbing extras"); + inputValid = false; + } + } + if (inputValid) { + extras.addExtra("cordova", 1); + request.setNetworkExtras(extras); + adView.loadAd(request); + result = new PluginResult(Status.OK); + } + } + synchronized (this) { + this.notify(); + } + } + } + + /** + * This class implements the AdMob ad listener events. It forwards the events + * to the JavaScript layer. To listen for these events, use: + * + * document.addEventListener('onReceiveAd', function()); + * document.addEventListener('onFailedToReceiveAd', function(data)); + * document.addEventListener('onPresentScreen', function()); + * document.addEventListener('onDismissScreen', function()); + * document.addEventListener('onLeaveApplication', function()); + */ + private class BannerListener implements AdListener { + @Override + public void onReceiveAd(Ad ad) { + webView.loadUrl("javascript:cordova.fireDocumentEvent('onReceiveAd');"); + } + + @Override + public void onFailedToReceiveAd(Ad ad, ErrorCode errorCode) { + webView.loadUrl(String.format( + "javascript:cordova.fireDocumentEvent('onFailedToReceiveAd', { 'error': '%s' });", + errorCode)); + } + + @Override + public void onPresentScreen(Ad ad) { + webView.loadUrl("javascript:cordova.fireDocumentEvent('onPresentScreen');"); + } + + @Override + public void onDismissScreen(Ad ad) { + webView.loadUrl("javascript:cordova.fireDocumentEvent('onDismissScreen');"); + } + + @Override + public void onLeaveApplication(Ad ad) { + webView.loadUrl("javascript:cordova.fireDocumentEvent('onLeaveApplication');"); + } + } + + @Override + public void onDestroy() { + if (adView != null) { + adView.destroy(); + } + super.onDestroy(); + } + + /** + * Gets an AdSize object from the string size passed in from JavaScript. + * Returns null if an improper string is provided. + * + * @param size The string size representing an ad format constant. + * @return An AdSize object used to create a banner. + */ + public static AdSize adSizeFromSize(String size) { + if ("BANNER".equals(size)) { + return AdSize.BANNER; + } else if ("IAB_MRECT".equals(size)) { + return AdSize.IAB_MRECT; + } else if ("IAB_BANNER".equals(size)) { + return AdSize.IAB_BANNER; + } else if ("IAB_LEADERBOARD".equals(size)) { + return AdSize.IAB_LEADERBOARD; + } else if ("SMART_BANNER".equals(size)) { + return AdSize.SMART_BANNER; + } else { + return null; + } + } +} + diff --git a/Android/AdMobPlugin/AdMobPlugin.js b/Android/AdMobPlugin/AdMobPlugin.js new file mode 100644 index 00000000..cc8638fa --- /dev/null +++ b/Android/AdMobPlugin/AdMobPlugin.js @@ -0,0 +1,129 @@ +/** + * This class defines an AdMob object that is used to show ads natively in a + * native Android application. + * @constructor + */ +var AdMob = function() { +}; + +/** + * This enum represents AdMob's supported ad sizes. Use one of these + * constants as the adSize when calling createBannerView. + * @const + */ +AdMob.AD_SIZE = { + BANNER: 'BANNER', + IAB_MRECT: 'IAB_MRECT', + IAB_BANNER: 'IAB_BANNER', + IAB_LEADERBOARD: 'IAB_LEADERBOARD', + SMART_BANNER: 'SMART_BANNER' +}; + +/** This piece of code adds AdMob as a Cordova plugin. */ +cordova.addConstructor(function() { + if (!window.plugins) { + window.plugins = {}; + } + window.plugins.AdMob = new AdMob(); +}); + +/** + * Creates a new AdMob banner view. + * + * @param {!Object} options The options used to create a banner. They should + * be specified similar to the following. + * + * { + * 'publisherId': 'MY_PUBLISHER_ID', + * 'adSize': AdSize.BANNER, + * 'positionAtTop': false + * } + * + * publisherId is the publisher ID from your AdMob site, adSize + * is one of the AdSize constants, and positionAtTop is a boolean to + * determine whether to create the banner above or below the app content. + * A publisher ID and AdSize are required. The default for postionAtTop + * is false, meaning the banner would be shown below the app content. + * @param {function()} successCallback The function to call if the banner was + * created successfully. + * @param {function()} failureCallback The function to call if create banner + * was unsuccessful. + */ +AdMob.prototype.createBannerView = + function(options, successCallback, failureCallback) { + var defaults = { + 'publisherId': undefined, + 'adSize': undefined, + 'positionAtTop': false + }; + var requiredOptions = ['publisherId', 'adSize']; + + // Merge optional settings into defaults. + for (var key in defaults) { + if (typeof options[key] !== 'undefined') { + defaults[key] = options[key]; + } + } + + // Check for and merge required settings into defaults. + requiredOptions.forEach(function(key) { + if (typeof options[key] === 'undefined') { + failureCallback('Failed to specify key: ' + key + '.'); + return; + } + defaults[key] = options[key]; + }); + + cordova.exec( + successCallback, + failureCallback, + 'AdMobPlugin', + 'createBannerView', + new Array(defaults) + ); +}; + +/** + * Requests an AdMob ad for the banner. This call should not be made until + * after the banner view has been successfully created. + * + * @param {!Object} options The options used to request an ad. They should + * be specified similar to the following. + * + * { + * 'isTesting': true|false, + * 'extras': { + * 'key': 'value' + * } + * } + * + * isTesting is a boolean determining whether or not to request a + * test ad on an emulator, and extras represents the extras to pass + * into the request. If no options are passed, the request will have + * testing set to false and an empty extras. + * @param {function()} successCallback The function to call if an ad was + * returned successfully. + * @param {function()} failureCallback The function to call if an ad failed + * to return. + */ +AdMob.prototype.requestAd = + function(options, successCallback, failureCallback) { + var defaults = { + 'isTesting': false, + 'extras': {} + }; + + for (var key in defaults) { + if (typeof options[key] !== 'undefined') { + defaults[key] = options[key]; + } + } + + cordova.exec( + successCallback, + failureCallback, + 'AdMobPlugin', + 'requestAd', + new Array(defaults) + ); +}; diff --git a/Android/AdMobPlugin/README.md b/Android/AdMobPlugin/README.md new file mode 100644 index 00000000..6c659328 --- /dev/null +++ b/Android/AdMobPlugin/README.md @@ -0,0 +1,75 @@ +AdMob Cordova Plugin for Android + +This plugin provides a way to request AdMob ads natively from JavaScript. +This plugin was written and tested with the Google AdMob SDK version 6.1.0, +and Cordova 2.0.0. + +Requirements: + +- Cordova SDK jar for Android +- Cordova JS for Android +- Google AdMob Ads SDK for Android +- Android SDK 3.2 or higher (to compile with AdMob) +- Android runtime 2.1 or higher (Cordova only supports 2.1+) +- AdMob publisher ID from www.admob.com + +Setup: + +1. Place Cordova SDK jar, Google AdMob SDK jar, and the AdMob Cordova plugin + jar inside libs/ +2. Place Cordova JS and AdMobPlugin.js inside assets/www/ +3. Place cordova.xml and plugins.xml into res/xml +4. Add + to your plugins.xml +5. Complete the Google AdMob SDK setup for Android at + https://developers.google.com/mobile-ads-sdk/docs + +Using the Plugin: + +There are two calls needed to get AdMob Ads: + +1. createBannerView + + Takes in a object containing a publisherId and adSize, as well as success + and failure callbacks. An example call is provided below: + + window.plugins.AdMob.createBannerView( + { + 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', + 'adSize': AdSize.BANNER + }, + successCallback, + failureCallback + ); + +2. requestAd + + Takes in an object containing an optional testing flag, and an optional + list of extras. This method should only be invoked once createBannerView + has invoked successCallback. An example call is provided below: + + window.plugins.AdMob.requestAd( + { + 'isTesting': false, + 'extras': { + 'color_bg': 'AAAAFF', + 'color_bg_top': 'FFFFFF', + 'color_border': 'FFFFFF', + 'color_link': '000080', + 'color_text': '808080', + 'color_url': '008000' + }, + }, + successCallback, + failureCallback + ); + + +This plugin also allows you the option to listen for ad events. The following +events are supported: + +document.addEventListener('onReceiveAd', callback); +document.addEventListener('onFailedToReceiveAd', callback); +document.addEventListener('onPresentScreen', callback); +document.addEventListener('onDismissScreen', callback); +document.addEventListener('onLeaveApplication', callback); diff --git a/iOS/AdMobPlugin/AdMobPlugin.h b/iOS/AdMobPlugin/AdMobPlugin.h new file mode 100644 index 00000000..f1d7e3ee --- /dev/null +++ b/iOS/AdMobPlugin/AdMobPlugin.h @@ -0,0 +1,33 @@ +#import +#import +#import + +#import "GADBannerViewDelegate.h" + +#pragma mark - JS requestAd options + +#define KEY_PUBLISHER_ID_ARG @"publisherId" +#define KEY_AD_SIZE_ARG @"adSize" +#define KEY_POSITION_AT_TOP_ARG @"positionAtTop" +#define KEY_EXTRAS_ARG @"extras" +#define KEY_IS_TESTING_ARG @"isTesting" + +@class GADBannerView; + +#pragma mark AdMob Plugin + +@interface AdMobPlugin : CDVPlugin { + @private + // Value set by the javascript to indicate whether the ad is to be positioned + // at the top or bottom of the screen. + BOOL positionAdAtTop_; +} + +@property(nonatomic, retain) GADBannerView *bannerView; + +- (void)createBannerView:(NSMutableArray *)arguments + withDict:(NSMutableDictionary *)options; +- (void)requestAd:(NSMutableArray *)arguments + withDict:(NSMutableDictionary *)options; + +@end diff --git a/iOS/AdMobPlugin/AdMobPlugin.js b/iOS/AdMobPlugin/AdMobPlugin.js new file mode 100644 index 00000000..7d4831f4 --- /dev/null +++ b/iOS/AdMobPlugin/AdMobPlugin.js @@ -0,0 +1,132 @@ +/** + * This class defines an AdMob object that is used to show ads natively in a + * native iOS application. + * @constructor + */ +var AdMob = function() { +}; + + +/** + * This enum represents AdMob's supported ad sizes. Use one of these + * constants as the adSize when calling createBannerView. + * @const + */ +AdMob.AD_SIZE = { + BANNER: 'BANNER', + IAB_MRECT: 'IAB_MRECT', + IAB_BANNER: 'IAB_BANNER', + IAB_LEADERBOARD: 'IAB_LEADERBOARD', + SMART_BANNER: 'SMART_BANNER' +}; + +/** This piece of code adds AdMob as a Cordova plugin. */ +cordova.addConstructor(function() { + if (!window.plugins) { + window.plugins = {}; + } + window.plugins.AdMob = new AdMob(); +}); + + +/** + * Creates a new AdMob banner view. + * + * @param {!Object} options The options used to create a banner. They should + * be specified similar to the following. + * + * { + * 'publisherId': 'MY_PUBLISHER_ID', + * 'adSize': AdMob.AD_SIZE.AD_SIZE_CONSTANT, + * 'positionAtTop': false + * } + * + * publisherId is the publisher ID from your AdMob site, adSize + * is one of the AdSize constants, and positionAtTop is a boolean to + * determine whether to create the banner above or below the app content. + * A publisher ID and AdSize are required. The default for postionAtTop + * is false, meaning the banner would be shown below the app content. + * @param {function()} successCallback The function to call if the banner was + * created successfully. + * @param {function()} failureCallback The function to call if create banner + * was unsuccessful. + */ +AdMob.prototype.createBannerView = + function(options, successCallback, failureCallback) { + var defaults = { + 'publisherId': undefined, + 'adSize': undefined, + 'positionAtTop': false + }; + var requiredOptions = ['publisherId', 'adSize']; + + // Merge optional settings into defaults. + for (var key in defaults) { + if (typeof options[key] !== 'undefined') { + defaults[key] = options[key]; + } + } + + // Check for and merge required settings into defaults. + requiredOptions.forEach(function(key) { + if (typeof options[key] === 'undefined') { + failureCallback('Failed to specify key: ' + key + '.'); + return; + } + defaults[key] = options[key]; + }); + + cordova.exec( + successCallback, + failureCallback, + 'AdMobPlugin', + 'createBannerView', + new Array(defaults) + ); +}; + + +/** + * Request an AdMob ad. This call should not be made until after the banner + * view has been successfully created. + * + * @param {!Object} options The options used to request an ad. They should + * be specified similar to the following. + * + * { + * 'isTesting': true|false, + * 'extras': { + * 'key': 'value' + * } + * } + * + * isTesting is a boolean determining whether or not to request a + * test ad on an emulator, and extras represents the extras to pass + * into the request. If no options are passed, the request will have + * testing set to false and an empty extras. + * @param {function()} successCallback The function to call if an ad was + * requested successfully. + * @param {function()} failureCallback The function to call if an ad failed + * to be requested. + */ +AdMob.prototype.requestAd = + function(options, successCallback, failureCallback) { + var defaults = { + 'isTesting': false, + 'extras': {} + }; + + for (var key in defaults) { + if (typeof options[key] !== 'undefined') { + defaults[key] = options[key]; + } + } + + cordova.exec( + successCallback, + failureCallback, + 'AdMobPlugin', + 'requestAd', + new Array(defaults) + ); +}; diff --git a/iOS/AdMobPlugin/AdMobPlugin.m b/iOS/AdMobPlugin/AdMobPlugin.m new file mode 100644 index 00000000..105c1264 --- /dev/null +++ b/iOS/AdMobPlugin/AdMobPlugin.m @@ -0,0 +1,298 @@ +#import "AdMobPlugin.h" +#import "GADAdMobExtras.h" +#import "GADAdSize.h" +#import "GADBannerView.h" + +@interface AdMobPlugin () + +- (void)createGADBannerViewWithPubId:(NSString *)pubId + bannerType:(GADAdSize)adSize; +- (void)requestAdWithTesting:(BOOL)isTesting + extras:(NSDictionary *)extraDict; +- (void)resizeViews; +- (GADAdSize)GADAdSizeFromString:(NSString *)string; +- (void)deviceOrientationChange:(NSNotification *)notification; + +@end + +@implementation AdMobPlugin + +@synthesize bannerView = bannerView_; + +#pragma mark Cordova JS bridge + +- (CDVPlugin *)initWithWebView:(UIWebView *)theWebView { + self = (AdMobPlugin *)[super initWithWebView:theWebView]; + if (self) { + positionAdAtTop_ = NO; + // These notifications are required for re-placing the ad on orientation + // changes. Start listening for notifications here since we need to + // translate the Smart Banner constants according to the orientation. + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(deviceOrientationChange:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + } + return self; +} + +// The javascript from the AdMob plugin calls this when createBannerView is +// invoked. This method parses the arguments passed in. +- (void)createBannerView:(NSMutableArray *)arguments + withDict:(NSMutableDictionary *)options { + CDVPluginResult *pluginResult; + NSString *callbackId = [arguments pop]; + GADAdSize adSize = [self GADAdSizeFromString: + [options objectForKey:KEY_AD_SIZE_ARG]]; + // We don't need positionAtTop to be set, but we need values for adSize and + // publisherId if we don't want to fail. + if (![options objectForKey:KEY_PUBLISHER_ID_ARG]) { + // Call the error callback that was passed in through the javascript + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR + messageAsString:@"AdMobPlugin:" + @"Invalid publisher Id"]; + [self writeJavascript:[pluginResult toErrorCallbackString:callbackId]]; + return; + } else if (GADAdSizeEqualToSize(adSize, kGADAdSizeInvalid)) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR + messageAsString:@"AdMobPlugin:" + @"Invalid ad size"]; + [self writeJavascript:[pluginResult toErrorCallbackString:callbackId]]; + return; + } + if ([options objectForKey:KEY_POSITION_AT_TOP_ARG]) { + positionAdAtTop_= + (BOOL)[[options objectForKey:KEY_POSITION_AT_TOP_ARG] boolValue]; + } + + NSString *publisherId = [options objectForKey:KEY_PUBLISHER_ID_ARG]; + [self createGADBannerViewWithPubId:publisherId + bannerType:adSize]; + + // Call the success callback that was passed in through the javascript. + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self writeJavascript:[pluginResult toSuccessCallbackString:callbackId]]; +} + +- (void)requestAd:(NSMutableArray *)arguments + withDict:(NSMutableDictionary *)options { + CDVPluginResult *pluginResult; + NSString *callbackId = [arguments pop]; + + if (!self.bannerView) { + // Try to prevent requestAd from being called without createBannerView first + // being called. + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR + messageAsString:@"AdMobPlugin:" + @"No ad view exists"]; + [self writeJavascript:[pluginResult toErrorCallbackString:callbackId]]; + return; + } + + NSDictionary *extrasDictionary = nil; + if ([options objectForKey:KEY_EXTRAS_ARG]) { + extrasDictionary = [NSDictionary dictionaryWithDictionary: + [options objectForKey:KEY_EXTRAS_ARG]]; + } + BOOL isTesting = (BOOL)[[options objectForKey:KEY_IS_TESTING_ARG] boolValue]; + [self requestAdWithTesting:isTesting + extras:extrasDictionary]; + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + [self writeJavascript:[pluginResult toSuccessCallbackString:callbackId]]; +} + +- (GADAdSize)GADAdSizeFromString:(NSString *)string { + if ([string isEqualToString:@"BANNER"]) { + return kGADAdSizeBanner; + } else if ([string isEqualToString:@"IAB_MRECT"]) { + return kGADAdSizeMediumRectangle; + } else if ([string isEqualToString:@"IAB_BANNER"]) { + return kGADAdSizeFullBanner; + } else if ([string isEqualToString:@"IAB_LEADERBOARD"]) { + return kGADAdSizeLeaderboard; + } else if ([string isEqualToString:@"SMART_BANNER"]) { + // Have to choose the right Smart Banner constant according to orientation. + UIDeviceOrientation currentOrientation = + [[UIDevice currentDevice] orientation]; + if (UIInterfaceOrientationIsPortrait(currentOrientation)) { + return kGADAdSizeSmartBannerPortrait; + } + else { + return kGADAdSizeSmartBannerLandscape; + } + } else { + return kGADAdSizeInvalid; + } +} + +#pragma mark Ad Banner logic + +- (void)createGADBannerViewWithPubId:(NSString *)pubId + bannerType:(GADAdSize)adSize { + self.bannerView = [[[GADBannerView alloc] initWithAdSize:adSize] autorelease]; + self.bannerView.adUnitID = pubId; + self.bannerView.delegate = self; + self.bannerView.rootViewController = self.viewController; +} + +- (void)requestAdWithTesting:(BOOL)isTesting + extras:(NSDictionary *)extrasDict { + GADRequest *request = [GADRequest request]; + request.testing = isTesting; + if (extrasDict) { + GADAdMobExtras *extras = [[[GADAdMobExtras alloc] init] autorelease]; + NSMutableDictionary *modifiedExtrasDict = + [[NSMutableDictionary alloc] initWithDictionary:extrasDict]; + [modifiedExtrasDict removeObjectForKey:@"cordova"]; + [modifiedExtrasDict setValue:@"1" forKey:@"cordova"]; + extras.additionalParameters = modifiedExtrasDict; + [request registerAdNetworkExtras:extras]; + } + [self.bannerView loadRequest:request]; + // Add the ad to the main container view, and resize the webview to make space + // for it. + [self.webView.superview addSubview:self.bannerView]; + [self resizeViews]; +} + +- (void)resizeViews { + // If the banner hasn't been created yet, no need for resizing views. + if (!self.bannerView) { + return; + } + + BOOL adIsShowing = + [self.webView.superview.subviews containsObject:self.bannerView]; + // If the ad is not showing or the ad is hidden, we don't want to resize + // anything. + if (!adIsShowing || self.bannerView.hidden) { + return; + } + + UIDeviceOrientation currentOrientation = + [[UIDevice currentDevice] orientation]; + // Handle changing Smart Banner constants for the user. + BOOL adIsSmartBannerPortrait = + GADAdSizeEqualToSize(self.bannerView.adSize, + kGADAdSizeSmartBannerPortrait); + BOOL adIsSmartBannerLandscape = + GADAdSizeEqualToSize(self.bannerView.adSize, + kGADAdSizeSmartBannerLandscape); + if ((adIsSmartBannerPortrait) && + (UIInterfaceOrientationIsLandscape(currentOrientation))) { + self.bannerView.adSize = kGADAdSizeSmartBannerLandscape; + } else if ((adIsSmartBannerLandscape) && + (UIInterfaceOrientationIsPortrait(currentOrientation))) { + self.bannerView.adSize = kGADAdSizeSmartBannerPortrait; + } + + // Frame of the main Cordova webview. + CGRect webViewFrame = self.webView.frame; + // Frame of the main container view that holds the Cordova webview. + CGRect superViewFrame = self.webView.superview.frame; + CGRect bannerViewFrame = self.bannerView.frame; + CGRect frame = bannerViewFrame; + // The updated x and y coordinates for the origin of the banner. + CGFloat yLocation = 0.0; + CGFloat xLocation = 0.0; + + if (positionAdAtTop_) { + // Move the webview underneath the ad banner. + webViewFrame.origin.y = bannerViewFrame.size.height; + // Center the banner using the value of the origin. + if (UIInterfaceOrientationIsLandscape(currentOrientation)) { + // The superView has not had its width and height updated yet so use those + // values for the x and y of the new origin respectively. + xLocation = (superViewFrame.size.height - + bannerViewFrame.size.width) / 2.0; + } else { + xLocation = (superViewFrame.size.width - + bannerViewFrame.size.width) / 2.0; + } + } else { + // Move the webview to the top of the screen. + webViewFrame.origin.y = 0; + // Need to center the banner both horizontally and vertically. + if (UIInterfaceOrientationIsLandscape(currentOrientation)) { + yLocation = superViewFrame.size.width - + bannerViewFrame.size.height; + xLocation = (superViewFrame.size.height - + bannerViewFrame.size.width) / 2.0; + } else { + yLocation = superViewFrame.size.height - + bannerViewFrame.size.height; + xLocation = (superViewFrame.size.width - + bannerViewFrame.size.width) / 2.0; + } + } + frame.origin = CGPointMake(xLocation, yLocation); + bannerView_.frame = frame; + + if (UIInterfaceOrientationIsLandscape(currentOrientation)) { + // The super view's frame hasn't been updated so use its width + // as the height. + webViewFrame.size.height = superViewFrame.size.width - + bannerViewFrame.size.height; + } else { + webViewFrame.size.height = superViewFrame.size.height - + bannerViewFrame.size.height; + } + self.webView.frame = webViewFrame; +} + +- (void)deviceOrientationChange:(NSNotification *)notification { + [self resizeViews]; +} + +#pragma mark GADBannerViewDelegate implementation + +- (void)adViewDidReceiveAd:(GADBannerView *)adView { + NSLog(@"%s: Received ad successfully.", __PRETTY_FUNCTION__); + [self writeJavascript:@"cordova.fireDocumentEvent('onReceiveAd');"]; +} + +- (void)adView:(GADBannerView *)view + didFailToReceiveAdWithError:(GADRequestError *)error { + NSLog(@"%s: Failed to receive ad with error: %@", + __PRETTY_FUNCTION__, [error localizedFailureReason]); + // Since we're passing error data back through Cordova, we need to set this + // up. + NSString *jsString = + @"cordova.fireDocumentEvent('onFailedToReceiveAd'," + @"{ 'error': '%@' });"; + [self writeJavascript:[NSString stringWithFormat:jsString, + [error localizedFailureReason]]]; +} + +- (void)adViewWillPresentScreen:(GADBannerView *)adView { + [self writeJavascript: + @"cordova.fireDocumentEvent('onPresentScreen');"]; +} + +- (void)adViewDidDismissScreen:(GADBannerView *)adView { + [self writeJavascript: + @"cordova.fireDocumentEvent('onDismissScreen');"]; +} + +- (void)adViewWillLeaveApplication:(GADBannerView *)adView { + [self writeJavascript: + @"cordova.fireDocumentEvent('onLeaveApplication');"]; +} + +#pragma mark Cleanup + +- (void)dealloc { + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIDeviceOrientationDidChangeNotification + object:nil]; + bannerView_.delegate = nil; + [bannerView_ release]; + [super dealloc]; +} + +@end diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md new file mode 100644 index 00000000..46b09147 --- /dev/null +++ b/iOS/AdMobPlugin/README.md @@ -0,0 +1,78 @@ +AdMob Cordova Plugin for iOS + +This is the AdMob Cordova Plugin for iOS. It provides a way to request +AdMob ads natively from JavaScript. This plugin was written and tested with +the Google AdMob SDK version 6.1.4 for iOS, and Cordova 2.0.0. + +Requirements: + +- Cordova SDK for iOS +- Cordova JS for iOS +- Google AdMob Ads SDK for iOS +- iOS version 3.2 or later as well as XCode 4.2 or later +- AdMob publisher ID from www.admob.com + +Setup: + +1. Import Cordova SDK binary and Google AdMob SDK binary into your project (with + their associated header files). +2. Place Cordova JS and AdMobPlugin.js inside www/ folder. This should be where + your index.html lives. +3. Place AdMobPlugin.h and AdMobPlugin.m into the plugins/ folder. +4. Add AdMobPlugin to Cordova.plist. The row should have values (AdMobPlugin, + String, AdMobPlugin) corresponding to (Key, Type, Value). +5. Add an entry under ExternalHosts in Cordova.plist. Make the entry (String, *) + corresponding to (Type, Value). +6. Complete the Google AdMob SDK setup for iOS at + https://developers.google.com/mobile-ads-sdk/docs. + +Implementation: + +There are two calls needed to get AdMob Ads: + +1. createBannerView + + Takes in a object containing a publisherId and adSize, as well as success + and failure callbacks. An example call is provided below: + + window.plugins.AdMob.createBannerView( + { + 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', + 'adSize': AdMob.AdSize.BANNER + }, + successCallback, + failureCallback + ); + +2. requestAd + + Takes in an object containing an optional testing flag, and an optional + list of extras. This method should only be invoked once createBannerView + has invoked successCallback. An example call is provided below: + + logCreateBannerSuccess(); + window.plugins.AdMob.requestAd( + { + 'isTesting': false, + 'extras': { + 'color_bg': 'AAAAFF', + 'color_bg_top': 'FFFFFF', + 'color_border': 'FFFFFF', + 'color_link': '000080', + 'color_text': '808080', + 'color_url': '008000' + }, + }, + successCallback, + failureCallback + ); + + +This plugin also allows you the option to listen for ad events. The following +events are supported: + +document.addEventListener('onReceiveAd', callback); +document.addEventListener('onFailedToReceiveAd', callback); +document.addEventListener('onDismissScreen', callback); +document.addEventListener('onPresentScreen', callback); +document.addEventListener('onLeaveApplication', callback); From 5410d5dc2f019742c6aab1edeb0f37de0cf02e98 Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Sat, 22 Sep 2012 18:15:34 -0700 Subject: [PATCH 2/7] Updating the Readme files to make them look better in github --- Android/AdMobPlugin/README.md | 29 +++++++++++++++-------------- iOS/AdMobPlugin/README.md | 25 +++++++++++++------------ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Android/AdMobPlugin/README.md b/Android/AdMobPlugin/README.md index 6c659328..8fe85a30 100644 --- a/Android/AdMobPlugin/README.md +++ b/Android/AdMobPlugin/README.md @@ -1,54 +1,55 @@ AdMob Cordova Plugin for Android +================================ This plugin provides a way to request AdMob ads natively from JavaScript. This plugin was written and tested with the Google AdMob SDK version 6.1.0, and Cordova 2.0.0. -Requirements: +##Requirements: - Cordova SDK jar for Android - Cordova JS for Android - Google AdMob Ads SDK for Android - Android SDK 3.2 or higher (to compile with AdMob) - Android runtime 2.1 or higher (Cordova only supports 2.1+) -- AdMob publisher ID from www.admob.com +- AdMob publisher ID from [AdMob](www.admob.com) -Setup: +##Setup: 1. Place Cordova SDK jar, Google AdMob SDK jar, and the AdMob Cordova plugin jar inside libs/ 2. Place Cordova JS and AdMobPlugin.js inside assets/www/ 3. Place cordova.xml and plugins.xml into res/xml -4. Add - to your plugins.xml +4. Add `` + to your `plugins.xml` 5. Complete the Google AdMob SDK setup for Android at https://developers.google.com/mobile-ads-sdk/docs -Using the Plugin: +##Using the Plugin: There are two calls needed to get AdMob Ads: -1. createBannerView +1. `createBannerView` Takes in a object containing a publisherId and adSize, as well as success and failure callbacks. An example call is provided below: - window.plugins.AdMob.createBannerView( + `window.plugins.AdMob.createBannerView( { 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', 'adSize': AdSize.BANNER }, successCallback, failureCallback - ); + );` -2. requestAd +2. `requestAd` Takes in an object containing an optional testing flag, and an optional list of extras. This method should only be invoked once createBannerView has invoked successCallback. An example call is provided below: - window.plugins.AdMob.requestAd( + `window.plugins.AdMob.requestAd( { 'isTesting': false, 'extras': { @@ -62,14 +63,14 @@ There are two calls needed to get AdMob Ads: }, successCallback, failureCallback - ); + );` This plugin also allows you the option to listen for ad events. The following events are supported: -document.addEventListener('onReceiveAd', callback); +`document.addEventListener('onReceiveAd', callback); document.addEventListener('onFailedToReceiveAd', callback); document.addEventListener('onPresentScreen', callback); document.addEventListener('onDismissScreen', callback); -document.addEventListener('onLeaveApplication', callback); +document.addEventListener('onLeaveApplication', callback);` diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md index 46b09147..855de8c6 100644 --- a/iOS/AdMobPlugin/README.md +++ b/iOS/AdMobPlugin/README.md @@ -1,18 +1,19 @@ AdMob Cordova Plugin for iOS +================================ This is the AdMob Cordova Plugin for iOS. It provides a way to request AdMob ads natively from JavaScript. This plugin was written and tested with the Google AdMob SDK version 6.1.4 for iOS, and Cordova 2.0.0. -Requirements: +##Requirements: - Cordova SDK for iOS - Cordova JS for iOS - Google AdMob Ads SDK for iOS - iOS version 3.2 or later as well as XCode 4.2 or later -- AdMob publisher ID from www.admob.com +- AdMob publisher ID from [AdMob](www.admob.com) -Setup: +##Setup: 1. Import Cordova SDK binary and Google AdMob SDK binary into your project (with their associated header files). @@ -26,31 +27,31 @@ Setup: 6. Complete the Google AdMob SDK setup for iOS at https://developers.google.com/mobile-ads-sdk/docs. -Implementation: +##Implementation: There are two calls needed to get AdMob Ads: -1. createBannerView +1. `createBannerView` Takes in a object containing a publisherId and adSize, as well as success and failure callbacks. An example call is provided below: - window.plugins.AdMob.createBannerView( + `window.plugins.AdMob.createBannerView( { 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', 'adSize': AdMob.AdSize.BANNER }, successCallback, failureCallback - ); + );` -2. requestAd +2. `requestAd` Takes in an object containing an optional testing flag, and an optional list of extras. This method should only be invoked once createBannerView has invoked successCallback. An example call is provided below: - logCreateBannerSuccess(); + `logCreateBannerSuccess(); window.plugins.AdMob.requestAd( { 'isTesting': false, @@ -65,14 +66,14 @@ There are two calls needed to get AdMob Ads: }, successCallback, failureCallback - ); + );` This plugin also allows you the option to listen for ad events. The following events are supported: -document.addEventListener('onReceiveAd', callback); +`document.addEventListener('onReceiveAd', callback); document.addEventListener('onFailedToReceiveAd', callback); document.addEventListener('onDismissScreen', callback); document.addEventListener('onPresentScreen', callback); -document.addEventListener('onLeaveApplication', callback); +document.addEventListener('onLeaveApplication', callback);` From a5ae333897f9e7f3ca12b452e1ad59b86821be9e Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Sat, 22 Sep 2012 18:19:05 -0700 Subject: [PATCH 3/7] Updating codeblocks in readme files. --- Android/AdMobPlugin/README.md | 56 ++++++++++++++++----------------- iOS/AdMobPlugin/README.md | 58 +++++++++++++++++------------------ 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Android/AdMobPlugin/README.md b/Android/AdMobPlugin/README.md index 8fe85a30..8c3ab6a2 100644 --- a/Android/AdMobPlugin/README.md +++ b/Android/AdMobPlugin/README.md @@ -34,14 +34,14 @@ There are two calls needed to get AdMob Ads: Takes in a object containing a publisherId and adSize, as well as success and failure callbacks. An example call is provided below: - `window.plugins.AdMob.createBannerView( - { - 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', - 'adSize': AdSize.BANNER - }, - successCallback, - failureCallback - );` + window.plugins.AdMob.createBannerView( + { + 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', + 'adSize': AdSize.BANNER + }, + successCallback, + failureCallback + ); 2. `requestAd` @@ -49,28 +49,28 @@ There are two calls needed to get AdMob Ads: list of extras. This method should only be invoked once createBannerView has invoked successCallback. An example call is provided below: - `window.plugins.AdMob.requestAd( - { - 'isTesting': false, - 'extras': { - 'color_bg': 'AAAAFF', - 'color_bg_top': 'FFFFFF', - 'color_border': 'FFFFFF', - 'color_link': '000080', - 'color_text': '808080', - 'color_url': '008000' - }, - }, - successCallback, - failureCallback - );` + window.plugins.AdMob.requestAd( + { + 'isTesting': false, + 'extras': { + 'color_bg': 'AAAAFF', + 'color_bg_top': 'FFFFFF', + 'color_border': 'FFFFFF', + 'color_link': '000080', + 'color_text': '808080', + 'color_url': '008000' + }, + }, + successCallback, + failureCallback + ); This plugin also allows you the option to listen for ad events. The following events are supported: -`document.addEventListener('onReceiveAd', callback); -document.addEventListener('onFailedToReceiveAd', callback); -document.addEventListener('onPresentScreen', callback); -document.addEventListener('onDismissScreen', callback); -document.addEventListener('onLeaveApplication', callback);` + document.addEventListener('onReceiveAd', callback); + document.addEventListener('onFailedToReceiveAd', callback); + document.addEventListener('onPresentScreen', callback); + document.addEventListener('onDismissScreen', callback); + document.addEventListener('onLeaveApplication', callback); diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md index 855de8c6..63970ae9 100644 --- a/iOS/AdMobPlugin/README.md +++ b/iOS/AdMobPlugin/README.md @@ -36,14 +36,14 @@ There are two calls needed to get AdMob Ads: Takes in a object containing a publisherId and adSize, as well as success and failure callbacks. An example call is provided below: - `window.plugins.AdMob.createBannerView( - { - 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', - 'adSize': AdMob.AdSize.BANNER - }, - successCallback, - failureCallback - );` + window.plugins.AdMob.createBannerView( + { + 'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE', + 'adSize': AdMob.AdSize.BANNER + }, + successCallback, + failureCallback + ); 2. `requestAd` @@ -51,29 +51,29 @@ There are two calls needed to get AdMob Ads: list of extras. This method should only be invoked once createBannerView has invoked successCallback. An example call is provided below: - `logCreateBannerSuccess(); - window.plugins.AdMob.requestAd( - { - 'isTesting': false, - 'extras': { - 'color_bg': 'AAAAFF', - 'color_bg_top': 'FFFFFF', - 'color_border': 'FFFFFF', - 'color_link': '000080', - 'color_text': '808080', - 'color_url': '008000' - }, - }, - successCallback, - failureCallback - );` + logCreateBannerSuccess(); + window.plugins.AdMob.requestAd( + { + 'isTesting': false, + 'extras': { + 'color_bg': 'AAAAFF', + 'color_bg_top': 'FFFFFF', + 'color_border': 'FFFFFF', + 'color_link': '000080', + 'color_text': '808080', + 'color_url': '008000' + }, + }, + successCallback, + failureCallback + ); This plugin also allows you the option to listen for ad events. The following events are supported: -`document.addEventListener('onReceiveAd', callback); -document.addEventListener('onFailedToReceiveAd', callback); -document.addEventListener('onDismissScreen', callback); -document.addEventListener('onPresentScreen', callback); -document.addEventListener('onLeaveApplication', callback);` + document.addEventListener('onReceiveAd', callback); + document.addEventListener('onFailedToReceiveAd', callback); + document.addEventListener('onDismissScreen', callback); + document.addEventListener('onPresentScreen', callback); + document.addEventListener('onLeaveApplication', callback); From d073e8c810dc35bea1b75c320254087339ed757e Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Fri, 19 Apr 2013 10:57:30 -0700 Subject: [PATCH 4/7] Updating plugin to support Cordova 2.5 Updating plugin to support new API for Cordova 2.5 --- iOS/AdMobPlugin/AdMobPlugin.h | 19 ++++++------- iOS/AdMobPlugin/AdMobPlugin.js | 4 +-- iOS/AdMobPlugin/AdMobPlugin.m | 51 ++++++++++++++++++++-------------- iOS/AdMobPlugin/README.md | 10 +++---- 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/iOS/AdMobPlugin/AdMobPlugin.h b/iOS/AdMobPlugin/AdMobPlugin.h index f1d7e3ee..70c23e1e 100644 --- a/iOS/AdMobPlugin/AdMobPlugin.h +++ b/iOS/AdMobPlugin/AdMobPlugin.h @@ -1,4 +1,4 @@ -#import +#import #import #import @@ -6,16 +6,17 @@ #pragma mark - JS requestAd options -#define KEY_PUBLISHER_ID_ARG @"publisherId" -#define KEY_AD_SIZE_ARG @"adSize" -#define KEY_POSITION_AT_TOP_ARG @"positionAtTop" -#define KEY_EXTRAS_ARG @"extras" -#define KEY_IS_TESTING_ARG @"isTesting" +#define PUBLISHER_ID_ARG_INDEX 0 +#define AD_SIZE_ARG_INDEX 1 +#define POSITION_AT_TOP_ARG_INDEX 2 +#define IS_TESTING_ARG_INDEX 0 +#define EXTRAS_ARG_INDEX 1 @class GADBannerView; #pragma mark AdMob Plugin +// This version of the AdMob plugin has been tested with Cordova version 2.5.0. @interface AdMobPlugin : CDVPlugin { @private // Value set by the javascript to indicate whether the ad is to be positioned @@ -25,9 +26,7 @@ @property(nonatomic, retain) GADBannerView *bannerView; -- (void)createBannerView:(NSMutableArray *)arguments - withDict:(NSMutableDictionary *)options; -- (void)requestAd:(NSMutableArray *)arguments - withDict:(NSMutableDictionary *)options; +- (void)createBannerView:(CDVInvokedUrlCommand *)command; +- (void)requestAd:(CDVInvokedUrlCommand *)command; @end diff --git a/iOS/AdMobPlugin/AdMobPlugin.js b/iOS/AdMobPlugin/AdMobPlugin.js index 7d4831f4..a6c22821 100644 --- a/iOS/AdMobPlugin/AdMobPlugin.js +++ b/iOS/AdMobPlugin/AdMobPlugin.js @@ -81,7 +81,7 @@ AdMob.prototype.createBannerView = failureCallback, 'AdMobPlugin', 'createBannerView', - new Array(defaults) + [defaults['publisherId'], defaults['adSize'], defaults['positionAtTop']] ); }; @@ -127,6 +127,6 @@ AdMob.prototype.requestAd = failureCallback, 'AdMobPlugin', 'requestAd', - new Array(defaults) + [defaults['isTesting'], defaults['extras']] ); }; diff --git a/iOS/AdMobPlugin/AdMobPlugin.m b/iOS/AdMobPlugin/AdMobPlugin.m index 105c1264..016e6c1b 100644 --- a/iOS/AdMobPlugin/AdMobPlugin.m +++ b/iOS/AdMobPlugin/AdMobPlugin.m @@ -24,7 +24,6 @@ @implementation AdMobPlugin - (CDVPlugin *)initWithWebView:(UIWebView *)theWebView { self = (AdMobPlugin *)[super initWithWebView:theWebView]; if (self) { - positionAdAtTop_ = NO; // These notifications are required for re-placing the ad on orientation // changes. Start listening for notifications here since we need to // translate the Smart Banner constants according to the orientation. @@ -40,46 +39,45 @@ - (CDVPlugin *)initWithWebView:(UIWebView *)theWebView { // The javascript from the AdMob plugin calls this when createBannerView is // invoked. This method parses the arguments passed in. -- (void)createBannerView:(NSMutableArray *)arguments - withDict:(NSMutableDictionary *)options { +- (void)createBannerView:(CDVInvokedUrlCommand *)command { CDVPluginResult *pluginResult; - NSString *callbackId = [arguments pop]; + NSString *callbackId = command.callbackId; GADAdSize adSize = [self GADAdSizeFromString: - [options objectForKey:KEY_AD_SIZE_ARG]]; + [command argumentAtIndex:AD_SIZE_ARG_INDEX]]; + positionAdAtTop_ = NO; // We don't need positionAtTop to be set, but we need values for adSize and // publisherId if we don't want to fail. - if (![options objectForKey:KEY_PUBLISHER_ID_ARG]) { + if (![command argumentAtIndex:PUBLISHER_ID_ARG_INDEX]) { // Call the error callback that was passed in through the javascript pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"AdMobPlugin:" @"Invalid publisher Id"]; - [self writeJavascript:[pluginResult toErrorCallbackString:callbackId]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; return; } else if (GADAdSizeEqualToSize(adSize, kGADAdSizeInvalid)) { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"AdMobPlugin:" @"Invalid ad size"]; - [self writeJavascript:[pluginResult toErrorCallbackString:callbackId]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; return; } - if ([options objectForKey:KEY_POSITION_AT_TOP_ARG]) { + if ([command argumentAtIndex:POSITION_AT_TOP_ARG_INDEX]) { positionAdAtTop_= - (BOOL)[[options objectForKey:KEY_POSITION_AT_TOP_ARG] boolValue]; + [[command argumentAtIndex:POSITION_AT_TOP_ARG_INDEX] boolValue]; } - NSString *publisherId = [options objectForKey:KEY_PUBLISHER_ID_ARG]; + NSString *publisherId = [command argumentAtIndex:PUBLISHER_ID_ARG_INDEX]; [self createGADBannerViewWithPubId:publisherId bannerType:adSize]; // Call the success callback that was passed in through the javascript. pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self writeJavascript:[pluginResult toSuccessCallbackString:callbackId]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; } -- (void)requestAd:(NSMutableArray *)arguments - withDict:(NSMutableDictionary *)options { +- (void)requestAd:(CDVInvokedUrlCommand *)command { CDVPluginResult *pluginResult; - NSString *callbackId = [arguments pop]; + NSString *callbackId = command.callbackId; if (!self.bannerView) { // Try to prevent requestAd from being called without createBannerView first @@ -87,21 +85,22 @@ - (void)requestAd:(NSMutableArray *)arguments pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"AdMobPlugin:" @"No ad view exists"]; - [self writeJavascript:[pluginResult toErrorCallbackString:callbackId]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; return; } NSDictionary *extrasDictionary = nil; - if ([options objectForKey:KEY_EXTRAS_ARG]) { + if ([command argumentAtIndex:EXTRAS_ARG_INDEX]) { extrasDictionary = [NSDictionary dictionaryWithDictionary: - [options objectForKey:KEY_EXTRAS_ARG]]; + [command argumentAtIndex:EXTRAS_ARG_INDEX]]; } - BOOL isTesting = (BOOL)[[options objectForKey:KEY_IS_TESTING_ARG] boolValue]; + BOOL isTesting = + [[command argumentAtIndex:IS_TESTING_ARG_INDEX] boolValue]; [self requestAdWithTesting:isTesting extras:extrasDictionary]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self writeJavascript:[pluginResult toSuccessCallbackString:callbackId]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; } - (GADAdSize)GADAdSizeFromString:(NSString *)string { @@ -141,7 +140,17 @@ - (void)createGADBannerViewWithPubId:(NSString *)pubId - (void)requestAdWithTesting:(BOOL)isTesting extras:(NSDictionary *)extrasDict { GADRequest *request = [GADRequest request]; - request.testing = isTesting; + + if (isTesting) { + // Make the request for a test ad. Put in an identifier for the simulator as + // well as any devices you want to receive test ads. + request.testDevices = + [NSArray arrayWithObjects: + GAD_SIMULATOR_ID, + // TODO: Add your device test identifiers here. They are + // printed to the console when the app is launched. + nil]; + } if (extrasDict) { GADAdMobExtras *extras = [[[GADAdMobExtras alloc] init] autorelease]; NSMutableDictionary *modifiedExtrasDict = diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md index 63970ae9..f01899a1 100644 --- a/iOS/AdMobPlugin/README.md +++ b/iOS/AdMobPlugin/README.md @@ -3,7 +3,7 @@ AdMob Cordova Plugin for iOS This is the AdMob Cordova Plugin for iOS. It provides a way to request AdMob ads natively from JavaScript. This plugin was written and tested with -the Google AdMob SDK version 6.1.4 for iOS, and Cordova 2.0.0. +the Google AdMob SDK version 6.4.0 for iOS, and Cordova 2.5.0. ##Requirements: @@ -20,10 +20,10 @@ the Google AdMob SDK version 6.1.4 for iOS, and Cordova 2.0.0. 2. Place Cordova JS and AdMobPlugin.js inside www/ folder. This should be where your index.html lives. 3. Place AdMobPlugin.h and AdMobPlugin.m into the plugins/ folder. -4. Add AdMobPlugin to Cordova.plist. The row should have values (AdMobPlugin, - String, AdMobPlugin) corresponding to (Key, Type, Value). -5. Add an entry under ExternalHosts in Cordova.plist. Make the entry (String, *) - corresponding to (Type, Value). +4. Add AdMobPlugin to Config.xml under the element. The entry should + be . +5. To make sure there are no domain whitelisting issues, make sure you've set + the origin attribute of the element to "*". 6. Complete the Google AdMob SDK setup for iOS at https://developers.google.com/mobile-ads-sdk/docs. From 9adfde56ff04b8bead565b899554f611ff2da8cd Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Fri, 19 Apr 2013 11:00:59 -0700 Subject: [PATCH 5/7] Updating Readme file --- iOS/AdMobPlugin/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md index f01899a1..9e356603 100644 --- a/iOS/AdMobPlugin/README.md +++ b/iOS/AdMobPlugin/README.md @@ -20,10 +20,10 @@ the Google AdMob SDK version 6.4.0 for iOS, and Cordova 2.5.0. 2. Place Cordova JS and AdMobPlugin.js inside www/ folder. This should be where your index.html lives. 3. Place AdMobPlugin.h and AdMobPlugin.m into the plugins/ folder. -4. Add AdMobPlugin to Config.xml under the element. The entry should - be . +4. Add AdMobPlugin to Config.xml under the \ element. The entry should + be \. 5. To make sure there are no domain whitelisting issues, make sure you've set - the origin attribute of the element to "*". + the origin attribute of the \ element to "*". 6. Complete the Google AdMob SDK setup for iOS at https://developers.google.com/mobile-ads-sdk/docs. From da3902f28d724d6b1399d5464a6c5cc86994a6ac Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Fri, 19 Apr 2013 11:01:43 -0700 Subject: [PATCH 6/7] Minor README error fix --- iOS/AdMobPlugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md index 9e356603..38c28ec0 100644 --- a/iOS/AdMobPlugin/README.md +++ b/iOS/AdMobPlugin/README.md @@ -21,7 +21,7 @@ the Google AdMob SDK version 6.4.0 for iOS, and Cordova 2.5.0. your index.html lives. 3. Place AdMobPlugin.h and AdMobPlugin.m into the plugins/ folder. 4. Add AdMobPlugin to Config.xml under the \ element. The entry should - be \. + be \. 5. To make sure there are no domain whitelisting issues, make sure you've set the origin attribute of the \ element to "*". 6. Complete the Google AdMob SDK setup for iOS at From e8b9f4f49a926466d757d7783a26550291c18f9a Mon Sep 17 00:00:00 2001 From: Raj Parameswaran Date: Fri, 19 Apr 2013 11:02:34 -0700 Subject: [PATCH 7/7] Another minor README fix --- iOS/AdMobPlugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS/AdMobPlugin/README.md b/iOS/AdMobPlugin/README.md index 38c28ec0..dd1b089f 100644 --- a/iOS/AdMobPlugin/README.md +++ b/iOS/AdMobPlugin/README.md @@ -21,7 +21,7 @@ the Google AdMob SDK version 6.4.0 for iOS, and Cordova 2.5.0. your index.html lives. 3. Place AdMobPlugin.h and AdMobPlugin.m into the plugins/ folder. 4. Add AdMobPlugin to Config.xml under the \ element. The entry should - be \. + be \. 5. To make sure there are no domain whitelisting issues, make sure you've set the origin attribute of the \ element to "*". 6. Complete the Google AdMob SDK setup for iOS at