google admob ios: Request Error: No ad to show - ios

I found a related thread AdMob Ios Error: Failed to receive ad with error: Request Error: No ad to show but it does not solve my problem.
I am trying to create an Interstitial ad using the latest example project from google code: https://google-mobile-dev.googlecode.com/files/InterstitialExample_iOS_3.0.zip.
I have changed kSampleAdUnitID to that of my ad id.
Yesterday, when I clicked on Load Interstitial, I got Request Error: No ad to show. I had to click 4-5 times for it to work.
Today, I am using the same code unchanged but no matter how many times I click on Load Interstitial, I get the error mentioned above.
Any help here?

My implementation as follows - I hope it helps:
#interface ViewController () <GADInterstitialDelegate>
#property (strong, nonatomic) GADInterstitial *interstitial;
#end
#implementation ViewController
#define MY_INTERSTITIAL_UNIT_ID #"...."
- (void)preLoadInterstitial {
//Call this method as soon as you can - loadRequest will run in the background and your interstitial will be ready when you need to show it
GADRequest *request = [GADRequest request];
self.interstitial = [[GADInterstitial alloc] init];
self.interstitial.delegate = self;
self.interstitial.adUnitID = MY_INTERSTITIAL_UNIT_ID;
[self.interstitial loadRequest:request];
}
- (void)interstitialDidDismissScreen:(GADInterstitial *)ad
{
//An interstitial object can only be used once - so it's useful to automatically load a new one when the current one is dismissed
[self preLoadInterstitial];
}
- (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error
{
//If an error occurs and the interstitial is not received you might want to retry automatically after a certain interval
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:#selector(preLoadInterstitial) userInfo:nil repeats:NO];
}
- (void) showInterstitial
{
//Call this method when you want to show the interstitial - the method should double check that the interstitial has not been used before trying to present it
if (!self.interstitial.hasBeenUsed) [self.interstitial presentFromRootViewController:self];
}
#end

Related

GADInterstitial presentFromRootViewController causes current View Controller to close

I'm attempting to show a GADInterstitial ad when a user of my app clicks a certain button to go to a certain ViewController. In the new ViewController's viewDidLoad method I check to see if the GADInterstitial ad is ready, and if it is I attempt to present it. The problem is, when I dismiss the ad I notice that the ViewController that presented the ad is no longer there and instead it has sent me back to the ViewController that launched the ViewController that presented the ad.
Here's my code:
- (void)viewDidLoad {
[super viewDidLoad];
BTRInterstitialHelper *helper = [BTRInterstitialHelper sharedHelper];
if([helper isInterstitialReady]) {
[helper.interstitial presentFromRootViewController:self];
}
My helper method just looks like this:
-(BOOL)isInterstitialReady {
if ([self.interstitial isReady]) {
return YES;
} else {
return NO;
}
}
I do notice thought that when I present the ad, this message shows up in the logs:
Presenting view controllers on detached view controllers is discouraged BTRIndividualLocationViewController: 0x7fd63bcd9c00.
Same problem occurs if I try to present it in viewWillAppear.
What am I doing wrong here?
EDIT:
I have also tried the following, to try to pass in my app's actual rootViewController:
UINavigationController *nav=(UINavigationController *)((BTRAppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
UIViewController *rootController=(UIViewController *)[nav.viewControllers objectAtIndex:0];
[helper.interstitial presentFromRootViewController:rootController];
Still the same result though, except that message doesn't pop up in the logs.
VC2.h
#import "GADInterstitial.h"
#import "GADInterstitialDelegate.h"
set delegate
#interface VC2 : UIViewController <GADInterstitialDelegate>
and a property
#property(nonatomic, strong) GADInterstitial *interstitial;
VC2.m
in viewdidappear
self.interstitial = [[GADInterstitial alloc] init];
self.interstitial.adUnitID = #"ca-app-pub-yourNumber";
self.interstitial.delegate = self;
GADRequest *request = [GADRequest request];
for test ads in simulator
request.testDevices = #[ GAD_SIMULATOR_ID ];
coud also add location and keywords in the request (optional)
then do request
[self.interstitial loadRequest:request];
listen to delegate
-(void)interstitialDidReceiveAd:(GADInterstitial *)ad {
if ([self.interstitial isReady]) {
[self.interstitial presentFromRootViewController:self];
}
}
If you want to show the interstitial only when pressed from a certain button use NSUserdefaults.
In VC1 when button pressed
[[NSUserDefaults standardUserDefaults] setValue:#"yes" forKey:#"showInterstitial"];
[[NSUserDefaults standardUserDefaults] synchronize];
and wrap all the code for the interstitial in VC2 in viewdidappear in:
if ([[[NSUserDefaults standardUserDefaults] valueForKey:#"showInterstitial"] isEqualToString:#"yes"]) {
}
and add to -(void)interstitialDidReceiveAd:(GADInterstitial *)ad {
[[NSUserDefaults standardUserDefaults] setValue:#"no" forKey:#"showInterstitial"];
[[NSUserDefaults standardUserDefaults] synchronize];
p.s. you could also use a Bool for NSUserdefaults of course, I do use strings caus I had some errors with Bools, but Bools would be more correct I guess
A very similar scenario for me in 2018.
My current ViewControllers look like this:
ViewController 1
-> ViewController 2 (via presentViewController:animated:completion)
-> GADOInterstitialViewController (presentFromRootViewController:)
When GADOInterstitialViewController is dismissed via rewardBasedVideoAdDidClose:, ViewController 2 is instantly dismissed also.
A simple solution to this issue that I have figured out. Simply override ViewController 2 function dismissViewControllerAnimated like this:
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
if(self.presentedViewController != nil){
[self.presentedViewController dismissViewControllerAnimated:flag completion:completion];
} else {
[super dismissViewControllerAnimated:flag completion:completion];
}
}
This code block checks if ViewController 2 has a presented view controller and dismisses it, if not then ViewController 2 gets dismissed.
This works perfectly in my case :)

webViewDidFinishLoad not working?

In my app, I am trying to make a splash image appear as my UIWebView loads so it is not just a blank screen. However my webViewDidFinishLoad method will not work. This means that the splash image appears but does not disappear from the screen once the UIWebView has loaded.
My code for the method is:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"content loading finished");
[loadingImageView removeFromSuperview];
}
Any help on why the method will not work would be appreciated greatly.
My .h:
#interface ViewController : UIViewController
-(IBAction)makePhoneCall:(id)sender;
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#property(nonatomic, strong) UIImageView *loadingImageView;
#end
My ViewDidLoad and webViewDidFinishLoading:
- (void)viewDidLoad {
UIWebView *mWebView = [[UIWebView alloc] init];
mWebView.delegate = self;
mWebView.scalesPageToFit = YES;
[super viewDidLoad];
}
//**************** Set website URL for UIWebView
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.sleafordpizza.com/food"]]];
//**************** Add Static loading image to prevent white "flash" ****************/
UIImage *loadingImage = [UIImage imageNamed:#"LittleItalyLogo.png"];
loadingImageView = [[UIImageView alloc] initWithImage:loadingImage];
loadingImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"LittleItalyLogo.png"],
nil];
[self.view addSubview:loadingImageView];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"content loading finished");
// Remove loading image from view
[loadingImageView removeFromSuperview];
}
Hi probably you do not set proper delegate.
This is small code tip for you.
-(void)viewDidLoad {
mWebView = [[UIWebView alloc] init];
mWebView.delegate = self;
mWebView.scalesPageToFit = YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[loadingImageView removeFromSuperview];
NSLog(#"finish");
}
In you're .h file add.
#interface MyView: UIViewController <UIWebViewDelegate> {
UIWebView *webView;
}
Code fixes.
For .h file
#interface ViewController : UIViewController<UIWebViewDelegate>
-(IBAction)makePhoneCall:(id)sender;
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#property(nonatomic, strong) UIImageView *loadingImageView;
#end
For .m file
- (void)viewDidLoad
{
[super viewDidLoad];
webView.delegate = self;
//**************** Set website URL for UIWebView
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.sleafordpizza.com/food"]]];
//**************** Add Static loading image to prevent white "flash" ****************/
UIImage *loadingImage = [UIImage imageNamed:#"LittleItalyLogo.png"];
loadingImageView = [[UIImageView alloc] initWithImage:loadingImage];
loadingImageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"LittleItalyLogo.png"],
nil];
[self.view addSubview:loadingImageView];
}
At certain times, this delegate method actually never gets fired. I have had severe problems with the same thing in some of my projects.
At one occasion, I actually had to solve it with a timer, checking the state of the web view every second or so to see if I could proceed.
In that particular case, I just needed a certain element to be present. Still, the view did not trigger the finish loading event, due to external script errors being injected.
So, I just started a trigger when the web view begun loading, then called a method every now and then to see if the web view contained the element in question.
- (void)methodCalledByTimer {
if (<I still do not have what I need>) {
//The web view has not yet finished loading; keep checking
} else {
//The web view has finished loading; stop the timer, hide spinners and proceed
}
}
You could also check if the web view is actually loading, if that is absolutely necessary:
- (void)methodCalledByTimer {
if (self.webView.isLoading) {
//The web view has not yet finished loading; keep checking
} else {
//The web view has finished loading; stop the timer, hide spinners and proceed
}
}
Then, naturally, I'd check for the finishedLoading event as well, just to be sure. Remember to also implement the webView:didFailLoadWithError: method as well.
When waiting for a web page to finish loading, there are some things to keep in mind.
For instance, do you really need it to stop loading, or is there anything else you can do? In my case, I needed an element. Being able to properly execute a script is another thing that may be required.
Second, is the loading page using any external resources? I once had external script errors causing the webViewDidFinishLoad: method to not being called at all. If I removed the external scripts, it worked.
Third, if the page is using external resources, you are exposed not only to the loading capacity of your own resources, but that of the external resources as well. Tracking scripts, ads etc...if one resource provider is delivering content sloooowly (or not at all), you could page could be stuck in loading state forever.
So, I'd go with checking for something else. :)
I see you aren't handling errors. If there is an error, all subsequent delegate calls will not happen. I was surprised to find that this is true when the webview uses a plugin too. It calls this error method telling you that the webview handed off to the delegate, in my case the movie player.
implement this and see if that is it.
-(void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
if (error.code == 204) {
//request was handled by a plugin instead of by the webview directly
...
}
else
{
NSLog(#"didFailLoadWithError. ERROR: %#", error);
}
}
I was able to do all the remaining loading work in this method instead of the webviewdidfinishLoad

AdMob Ios Error: Failed to receive ad with error: Request Error: No ad to show

i would add ADMOB to my xcode project, but when a test it on iphone and simulator i receive this error :
AdMob Ios Error: Failed to receive ad with error: Request Error: No ad to show.
my code Banner.h:
#import <UIKit/UIKit.h>
#import "GADBannerViewDelegate.h"
#class GADBannerView, GADRequest;
#interface BannerExampleViewController : UIViewController
<GADBannerViewDelegate> {
GADBannerView *adBanner_;
}
#property (nonatomic, retain) GADBannerView *adBanner;
- (GADRequest *)createRequest;
#end
Banner.m
#import "BannerExampleViewController.h"
#import "GADBannerView.h"
#import "GADRequest.h"
#import "SampleConstants.h"
#implementation BannerExampleViewController
#synthesize adBanner = adBanner_;
#pragma mark init/dealloc
// Implement viewDidLoad to do additional setup after loading the view,
// typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// Initialize the banner at the bottom of the screen.
CGPoint origin = CGPointMake(0.0,
self.view.frame.size.height -
CGSizeFromGADAdSize(kGADAdSizeBanner).height);
// Use predefined GADAdSize constants to define the GADBannerView.
self.adBanner = [[[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner
origin:origin]
autorelease];
// Note: Edit SampleConstants.h to provide a definition for kSampleAdUnitID
// before compiling.
self.adBanner.adUnitID = kSampleAdUnitID;
self.adBanner.delegate = self;
[self.adBanner setRootViewController:self];
[self.view addSubview:self.adBanner];
self.adBanner.center =
CGPointMake(self.view.center.x, self.adBanner.center.y);
[self.adBanner loadRequest:[self createRequest]];
}
- (void)dealloc {
adBanner_.delegate = nil;
[adBanner_ release];
[super dealloc];
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
#pragma mark GADRequest generation
// Here we're creating a simple GADRequest and whitelisting the application
// for test ads. You should request test ads during development to avoid
// generating invalid impressions and clicks.
- (GADRequest *)createRequest {
GADRequest *request = [GADRequest request];
// 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:#"6a47e320f03fe2ab9854afe2e5708321", nil];
return request;
}
#pragma mark GADBannerViewDelegate impl
// We've received an ad successfully.
- (void)adViewDidReceiveAd:(GADBannerView *)adView {
NSLog(#"Received ad successfully");
}
- (void)adView:(GADBannerView *)view
didFailToReceiveAdWithError:(GADRequestError *)error {
NSLog(#"Failed to receive ad with error: %#", [error localizedFailureReason]);
}
#end
One more thing to point out - if your banner space width/height is set ot 0, you'll receive exactly the same error. I'm currently trying to make a workaround about this because I want to animate ad view on screen only if it successfully load ad.
This is because the server have not update yet.
You should wait for 15 minutes and try again, it will work correctly.
PS: Remember replace kSampleAdUnitID with your App ID in Admob
This code work correctly when I am testing with my ID

How to display Full Screen iad for ipad

I just recently read that full screen iAd only works on iPad. ADInterstitialAd This Class To Use Developing Full Screen iAd. How To Implement Delegate Methodes in ADInterstitialAdDelegate?
You can use this for creating Full screen iAd
in .H file
Import
#import <iAd/iAd.h>
#interface ViewController : UIViewController<ADInterstitialAdDelegate>
{
ADInterstitialAd *interstitial;
}
in. M file
#interface ViewController ()
// Interstitials
- (void)cycleInterstitial;
#implementation ViewController
- (void)cycleInterstitial
{
// Clean up the old interstitial...
interstitial.delegate = nil;
// and create a new interstitial. We set the delegate so that we can be notified of when
interstitial = [[ADInterstitialAd alloc] init];
interstitial.delegate = self;
}
#pragma mark ADInterstitialViewDelegate methods
// When this method is invoked, the application should remove the view from the screen and tear it down.
// The content will be unloaded shortly after this method is called and no new content will be loaded in that view.
// This may occur either when the user dismisses the interstitial view via the dismiss button or
// if the content in the view has expired.
- (void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd
{
[self cycleInterstitial];
}
// This method will be invoked when an error has occurred attempting to get advertisement content.
// The ADError enum lists the possible error codes.
- (void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error
{
[self cycleInterstitial];
}
// if you want to show iAd while pushing view controller just use
- (IBAction)onSearchClick:(id)sender {
if (interstitial.loaded) {
// [interstitial presentFromViewController:self]; // deprecated in iOS 6.
[self requestInterstitialAdPresentation]; // it will load iAD Full screen mode.
}
// do whatever you want to do.
}
Have a happy coding. Cheers.

Hiding Ad Banner causes no further Ads to be requested/shown

I have a Test application setup with AdMob Mediation service being used, only on testing device at the moment. I have setup all the required methods per the documentation. I am having an issue where when the Fail to Receive Ad error occurs, no more ads are requested or shown?
Header:
#import <UIKit/UIKit.h>
#import "GADBannerViewDelegate.h"
#class GADBannerView, GADRequest;
#interface AdTestViewController : UIViewController
<GADBannerViewDelegate> {
GADBannerView *bannerView_;
}
#property (nonatomic, retain) GADBannerView *bannerView;
- (GADRequest *)createRequest;
#end
Imp File
#import "AdTestViewController.h"
#import "Constants.h"
#import "GADBannerView.h"
#import "GADRequest.h"
#implementation AdTestViewController
#synthesize bannerView = bannerView_;
- (void)viewDidLoad {
[super viewDidLoad];
// Create a view of the standard size at the top of the screen.
// Available AdSize constants are explained in GADAdSize.h.
//bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
// Initialize the banner at the bottom of the screen.
//CGPoint origin = CGPointMake(0.0,
// self.view.frame.size.height -
// CGSizeFromGADAdSize(kGADAdSizeBanner).height);
self.bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
//origin:origin];
self.bannerView.adUnitID = kAdMobPublisherID;
self.bannerView.delegate = self;
[self.bannerView setRootViewController:self];
[self.view addSubview:self.bannerView];
self.bannerView.center =
CGPointMake(self.view.center.x, self.bannerView.center.y);
[bannerView_ loadRequest:[self createRequest]];
bannerView_.backgroundColor = [UIColor blueColor];
// 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.
GADRequest *request = [GADRequest request];
request.testDevices = [NSArray arrayWithObjects:
#"4D047EB9-A3A7-441E-989E-C5437F05DB04",
#"YOUR_DEVICE_IDENTIFIER",
nil];
}
- (GADRequest *)createRequest {
GADRequest *request = [GADRequest request];
// 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:
#"4D047EB9-A3A7-441E-989E-C5437F05DB04",
#"YOUR_DEVICE_IDENTIFIER",
nil];
return request;
}
- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error;
{
NSLog(#"Error - did Fail to Receive an Ad");
bannerView_.hidden = YES;
}
- (void)adViewDidReceiveAd:(GADBannerView *)view;
{
NSLog(#"Ad Received");
bannerView_.hidden = NO;
}
#end
What I am seeing in my logs is the 'Ad Received' a few times, then 'Error - did Fail to Receive an Ad'... After this log there are no further entries it is like it stops requesting? Testing only on simulator at present.
Any ideas how to solve this, or potentially an alternative method on hiding the view when an error/no ad is received?
I find the same thing – when the GADBannerView is hidden, no more requests are sent out.
One thing I tried successfully is to move the GADBannerView offscreen instead of hiding it. Of course, you only want to do this as a consequence of didFailToReceiveAdWithError, and then move it back onscreen when adViewDidReceiveAd. I got this working so the user sees a nice animation when ads come and go, much like iAd encourages.
In short, the code below will place your GADBannerView (here called mAdBannerView) either at the bottom of the screen or offscreen, depending on the boolean adIsLoaded.
CGRect bannerFrame = mAdBannerView.frame;
bannerFrame.origin.y = self.view.bounds.size.height - (adIsLoaded * bannerFrame.size.height);
mAdBannerView.frame = bannerFrame;
in the method that's called when there is an error put in some thing like
bannerView_.hidden = 1;
that will hide the view if there's an error and it will probably automatically be displayed if an ad was received with no error
Think you're better off just hiding the bannerView_ with the hidden property.
- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error {
bannerView_.hidden = YES;
}
Of course you have to remember to set hidden back to YES when an ad is successfully received.
Simple solution, set the bannerView_.hidden true in adView:didFailToReciewvwAdWithError method. And to retrieve the view use adViewDidReceiveAd method. Example code:
These are ADmob's delegate method:
- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error
{
bannerView_.hidden = YES;
}
- (void)adViewDidReceiveAd:(GADBannerView *)view
{
bannerView_.hidden = NO;
}
I had the same problem, this worked for me:
Do not use the .hidden property to hide AdMob ads.
Just set the alpha to 0 (invisible) or 1 (visible).
So in your GADBannerView delegate method...
-(void)adView:(GADBannerView *)bannerView didFailToReceiveAdWithError:(GADRequestError *)error {
// Hide the ad banner.
[UIView animateWithDuration:0.5 animations:^{
self.myADBanner.alpha = 0.0;
}];
}
-(void)adViewDidReceiveAd:(GADBannerView *)bannerView {
//Show the ad banner.
[UIView animateWithDuration:0.5 animations:^{
self.myADBanner.alpha = 1.0;
}];
}
With regards to "After this log there are no further entries it is like it stops requesting?"
This happens to me as well when I remove an ad from the view hierarchy. However, requests continue when I add the ad back to the view hierarchy. The only time they didn't continue was when I was using the .hidden property.

Resources