Admob Interstitial on ios

Monkey Targets Forums/iOS/Admob Interstitial on ios

erebel55(Posted 2014) [#1]
I am attempting to get Admob Interstitial working on ios. I have absolutely zero objective c experience, so please be kind.

FINAL code
admobInterstitial.ios.cpp


FINAL code
therevills' admobInterstitial.monkey file modified:



erebel55(Posted 2014) [#2]
This is compiling successfully, however I am not seeing the Interstitial ad in the simulator.

Can someone with more experience please help me finish this?


erebel55(Posted 2014) [#3]
I am calling showAd after the player dies and clicks on the replay button.

_interstitialAd.isReady is coming back False.

I assume that is because of this
"You may invoke loadRequest: at any time, however, you must wait for GADInterstitialDelegate's interstitialDidReceiveAd: to be called before displaying the creative."

Can someone with objective-c knowledge look at this?


therevills(Posted 2014) [#4]
Good on you for trying! :)

What does your game monkey code look like?


erebel55(Posted 2014) [#5]
I will write up a simple example right now, instead of posting all of my game. :)


erebel55(Posted 2014) [#6]
Here is my monkey code, I apologize for the horribly written button class. That is still a work in progress. I didn't include the Ad Unit ID in the paste below. I just replaced the digits with x characters.

Edit: Added autofit back into the example


Also, here is the "retry_placeholder.png" image, I apologize for not making the code imageless.



therevills(Posted 2014) [#7]
Sometimes Ads do take a bit of time to load, so if it isn't ready you might have to wait a bit.

Also when your showing the ad:
For Local i% = 1 to Floor(numTicks)
	' update button
	restartButton.CheckClick()

	If restartButton.clicked = True
		#If TARGET="android" Or TARGET="ios"
			game.admobI.ShowAd()
		#End
	Endif
Next


Can you check how many times you are calling ShowAd? Make sure you are only calling it once.


erebel55(Posted 2014) [#8]
It looks like ShowAd is being called three times for some reason. However, I don't think that is the main issue. In the native code I don't think _interstitialAd.isReady will ever be True; because it is being called directly after loadRequest.

Also, I have waited for about 5 min and no ad shows.


erebel55(Posted 2014) [#9]
I have updated the native code again, now it shows the Ad the 1st time I call ShowAd(). However, doesn't show it anytime I call ShowAd() after this. In other words, the 1st time the player dies they see an Ad, but it isn't showing the Ad the 2nd time they die or anytime after that.

I think it is almost there tho :)

I'm thinking I need to call loadAd again when the following event occurs interstitialDidDismissScreen


therevills(Posted 2014) [#10]
I'm thinking I need to call loadAd again when the following event occurs interstitialDidDismissScreen

That sounds right. With the Android one, I call LoadAd again once the Ad has been closed (onDismissScreen):
		// set listener so we load a new ad when the user closes one
		interstitialAd.setAdListener(new AdListener() {
		
			public void onDismissScreen(Ad ad) {
				loadAd();
			}



erebel55(Posted 2014) [#11]
Yeah, I have been trying to figure out how to replicate that in my ios.cpp.

I'm not experienced in this native stuff tho


therevills(Posted 2014) [#12]
Try importing GADInterstitialDelegate.h, into your native code and implementing interstitialDidDismissScreen, something like this:

// Simple Admob Interstitial support for Monkey - IOS

// admobInterstitial.ios.h

#import "GADInterstitial.h"
#import "GADInterstitialDelegate.h"

class AdmobInterstitial {

    // the kind of "singleton"
    static AdmobInterstitial *_admob;
    // the ad
    GADInterstitial *_interstitialAd;
    // ad Unit ID
    NSString *adUnitId;
    
    void loadAd();
    
public:
    AdmobInterstitial();
    
    // creates an instance of the object and start the thread
    static AdmobInterstitial *GetAdmobInterstitial(String adUnitId);
    
    // displays the ad to the user if it is ready
    void ShowAd();
};


// admobInterstitial.ios.cpp

AdmobInterstitial *AdmobInterstitial::_admob;

AdmobInterstitial::AdmobInterstitial():_interstitialAd(0) {

}

AdmobInterstitial *AdmobInterstitial::GetAdmobInterstitial(String adUnitId) {
    if( !_admob ) _admob=new AdmobInterstitial();
    _admob->adUnitId = adUnitId.ToNSString();
    _admob->loadAd();
    return _admob;
}

void AdmobInterstitial::loadAd() {
    _interstitialAd = [[GADInterstitial alloc] init];
    
    if (_interstitialAd) {
        _interstitialAd.adUnitID = adUnitId;
        [_interstitialAd loadRequest:[GADRequest request]];
    }
}

- (void)interstitialDidDismissScreen:(GADInterstitial *)interstitial {
    _admob->loadAd();
}

void AdmobInterstitial::ShowAd() {
    // create ad (should this go here or earlier?)
    //_interstitialAd = [[GADInterstitial alloc] init];
    
    if (_interstitialAd) {
        //_interstitialAd.adUnitID = adUnitId;
        //[_interstitialAd loadRequest:[GADRequest request]];
        
        if (_interstitialAd.isReady) {
            BBMonkeyAppDelegate *appDelegate=(BBMonkeyAppDelegate*)[[UIApplication sharedApplication] delegate];
            UIViewController *rootViewController = appDelegate->viewController;
            [_interstitialAd presentFromRootViewController:rootViewController];
        }
    }
}


This code has not been tested...


erebel55(Posted 2014) [#13]
GADInterstitial.h already imports GADInterstitialDelegate.h

But the rest of this looks good :)

I will play around with this, thanks!!


therevills(Posted 2014) [#14]
I was going off this example:

https://github.com/googleads/googleads-mobile-ios-examples/blob/master/admob/InterstitialExample/Classes/MainController.m

BTW I hate Objective C and how the whole work flow is set up for iOS... that's the reason I have stopped developing for it :)


erebel55(Posted 2014) [#15]
Thanks for the link. I hate Objective-C as well.

I am getting the following.
error: missing context for method declaration
- (void)interstitialDidDismissScreen:(GADInterstitial *)interstitial

I don't think it can be free floating like that. I think i need @implementation?


erebel55(Posted 2014) [#16]
I never figured out how to use interstitialDidDismissScreen in my ios.cpp code.

However, I realized I could just call loadAd() at the end of my ShowAd() method and everything would be fine.

So it is working now :) My 1st post on this thread has the final code.

This has only been tested in the simulator as I don't have an apple dev account yet.


rIKmAN(Posted 2014) [#17]
Hey erebel,

First well done on getting this to work! :)

I tried this on my device last night, using your new final code, and while the ad does indeed show the first time, once you dismiss it and try to show another advert it crashes.

I was using your final admobInterstitial.ios.cpp and your modified admobInterstitial.monkey, but I tried it along with the example code from therevills android demo where you tap the screen to show the ad - could this be the issue?


erebel55(Posted 2014) [#18]
I will give it a go with therevills example code and see what is going on.


erebel55(Posted 2014) [#19]
Here is the example code I am using. I am not getting any crash, however I can only test this in the simulator (not a real device).
I replaced the digits in my Ad ID with x's.

Let me know if this crashes, if so can you let me know what error you are getting?

Also, I am compiling using version 78c of Monkey.




rIKmAN(Posted 2014) [#20]
I am using Monkey v76d, and the latest XCode, and it works to show the first advert.
Then you close it, press the screen again and I get a hard crash, as in the app quits and I get returned to the iPad home screen.

I will try and run it through XCode in debug mode and see if I can catch an error message with the crash, but the code below is essentially the same as yours except I use different AdMob IDs to serve ads depending on the target.

This is the example code I am using...
Strict

Import mojo

#If TARGET="android" OR TARGET="ios"
        Import admobInterstitial
#End

Function Main:Int()
	New AdmobInterstitialExample()
	Return True
End

Class AdmobInterstitialExample Extends App
	#If TARGET="android" OR TARGET="ios"
		Field admob:AdmobInterstitial
	#End
	
	Method OnCreate:Int()
		#If TARGET="android"
			admob = AdmobInterstitial.GetAdmobInterstitial("ca-app-pub-xxxxxxxxxxxxxx/xxxxxxxxx")
			DebugLog "GetAdmobInterstitial() Android"
		#End
		
		#If TARGET="ios"
			admob = AdmobInterstitial.GetAdmobInterstitial("ca-app-pub-xxxxxxxxxxxxxx/xxxxxxxxx")
			DebugLog "GetAdmobInterstitial() IOS"
		
		#End
		
		SetUpdateRate(60)
		Return True
	End
	
	Method OnUpdate:Int()
		If MouseHit()
			#If TARGET="android" OR TARGET="ios"
				admob.ShowAd()
			#End		
		End
		Return True
	End

	Method OnRender:Int()
		Cls
		DrawText("Testing Admob Interstitial...", 10, 10)
		DrawText("Touch to Show Ad!", 10, 30)
		Return True
	End
		
End


I use separate AdMob ID's for iOS/Android as within AdMob you have to specify which target you are creating ads for.
Does it work on both devices with your code for iOS or android showing the same ads / using the same AdMob ID?


erebel55(Posted 2014) [#21]
No, you should use separate Ad IDs like you are doing there.

Are you testing this with the simulator or on a real device? I'm not seeing any crash on my end. I am using the latest XCode as well.

Also, any chance you could try with the latest version of Monkey?


rIKmAN(Posted 2014) [#22]
Here is a screenshot of the error when running through XCode onto my device.
It's an iPad Air 16gb running iOS7.

Here is what happens:

1) Run app
2) Touch screen
3) Ad appears correctly
4) Press X button to close the ad
5) Ad closes correctly
6) Touch the screen again
7) Crash

Linky to screenshot


erebel55(Posted 2014) [#23]
The error is thrown in the touch events. I don't think this has to do with my admob code.

Can you please try upgrading to the latest Monkey?


rIKmAN(Posted 2014) [#24]
Yep I am just about to do that, but I'm going slow as I'm watching the football at the same time (Man Utd fan here!)
Will report back once I've tested with the latest stable version.


rIKmAN(Posted 2014) [#25]
Hey erebel,

I retried using version 78c, and it does indeed run without crashing - I think I need to keep my eye out for updates a little more, sorry about that!

One thing I noticed is that after closing the ad, I have to press the screen twice for the next ad to show.
Looking at the example code the ad should show on the first touch?

Just to add to the above:

1) On first run, the ad shows on the first touch
2) Press X to close the ad
3) From now on you have to touch the screen twice for an ad to show after closing it.


erebel55(Posted 2014) [#26]
I get the same results and I'm not sure why. If you find out why let me know.


rIKmAN(Posted 2014) [#27]
Will do, although I won't be using touch events to show my ads so it won't be high on my priority list unfortunately.

Great work! :)


erebel55(Posted 2014) [#28]
That is why I haven't looked into it ;)

Thanks :D


rIKmAN(Posted 2014) [#29]
haha, I thought that might be the case :)

Just one thing, are your interstitials updating properly?
I have added interstitials to my game code and the ad shows and displays fine, but it always shows the same ad.
It does the same with the example code.

I have 3 providers set in admob, and the banners seem to be working fine.
This is on iOS, on an iPad Air.


erebel55(Posted 2014) [#30]
Hmm I was getting a few different ads earlier; but now I am just getting a Clash of Clans ad. May want to contact admob support and see if they have any ideas? Is the therevills android version giving different ads?

Also, feel free to take a look through my native code and let me know if you see anything wrong.

Edit:
Actually, I clicked through about 40 times and I did see a few other ads. I got a verizon ad, a samsung ad, and some Filipino girls ad. But 95% of the time it was the Clash of Clans ad.

Also, if you are adding different Mediation networks I don't think those will work without the adapter? I could be wrong on that though.
https://developers.google.com/mobile-ads-sdk/docs/admob/mediation-networks


rIKmAN(Posted 2014) [#31]
Yeah I'm just constantly getting Empire: Four Kingdoms on iPad and a McLaren 650s one on iPhone.
I can't remember the ad but it also did the same on Android when I just tested, so I maybe it is Admob problem?

When I mentioned mediation networks, I just added the Admob eFloor beta and iAds to the default admob provider in the admob settings.


erebel55(Posted 2014) [#32]
Yeah, I just tested on android and am getting the same behavior. Most of the time it's the same ad.


SLotman(Posted 2014) [#33]
Edit: Never mind - I see the crash is removed in the latest monkey.

Now thinking about it: maybe the problem of "having to touch twice" is because the app/view is losing its focus and its not restored once the ad is closed?

Edit2: Its something along those lines, alright. Just added a Print "showad" in the mousehit() and it only shows once - when touching the screen for the second time!

Edit3: Now I'm lost again... I added a counter in the test example, and while showing the ad, the counter keeps increasing! So the game does *not* pause while showing the ads (and it should, the android version does that).

This is the test code I'm working here:



SLotman(Posted 2014) [#34]
Just confirmed that the "touch twice to show ads" bug happens on real devices too: tested on my iPad2, and the app doesn't pause either when showing the interstitial ad :(


rIKmAN(Posted 2014) [#35]
I never looked into the "two click" problem as they were shown in my game based on game conditions (# of player deaths), and it was before a menu / stats screen so the not pausing wasn't an issue either.

For the pausing, not sure if it will work on iOS, but have you tried using:
MOJO_AUTO_SUSPEND_ENABLED=True



SLotman(Posted 2014) [#36]
Well, you can reproduce the "two click" problem with the code above... I've spent all night trying to find some sort of fix, but nothing I tried worked; The only option left I see is to implement a "delegate" and see when the ads loads and gets removed from the screen.

But I'm going to test the auto_suspend thing, good call! :)


SLotman(Posted 2014) [#37]
Nope, #MOJO_AUTO_SUSPEND_ENABLED=True does not stop the app when the ad is visible... and the "two clicks" problem persists :(


rIKmAN(Posted 2014) [#38]
Its not ideal, but as a workaround you could set a bool when you display the ads.
Then enclose your game code within an if test and if the ads are showing, do not update.

Just curious, but why would u want ads to appear while the game is still in play?


SLotman(Posted 2014) [#39]
It's not while the game is on play - it's when I show my level selection screen. But this "having to touch twice" worries me.
The only way I know to check if the ad is on screen or not is to set a "delegate", but I'm not really sure how to implement it :/


rIKmAN(Posted 2014) [#40]
If it is a level selection screen, then why does it matter if it pauses or not when the ads show?

Show the ads based off game logic (rather than a touch), then the user has to close the ad or click to follow the link, then the ad closes and you are back to your level selection screen.

This is exactly how I used ads in my game and it worked great.


SLotman(Posted 2014) [#41]
For once, I think my game checks for touches to start a level - what if when the player touches the screen, if it starts a level and the ad remains on screen?
Or worse, the ad opens, and at the same time, the game starts?

I'm not very comfortable dealing with unknown variables :(


rIKmAN(Posted 2014) [#42]
Have you tested that - is that what happens?

I've just tested my game on my iPad and I can't seem to get a click on the full screen ad to press the game buttons behind, although I only tested a few times as I don't want to be banned from AdMob, and am roughly guessing the locations of the buttons as they are behind the ad.