How to use the Vungle listener? Does it work?

I can’t see anything wrong after a quick read.

Here’s my adnetwork module I use. It has references to other modules, but I hope you’ll be able to make some sense out of it.

One tip: My module temporarily fixes the Chartboost problem of not filling the background of devices with wider and taller displays (iPhone5//iPad) when using letterbox mode (you shouldn’t mess with the width/height settings in config.lua as it will mess up the aspect ratio of the screen which will affect any splash screens you have).

Here’s my module:

-- adnetworks.lua -- created: 2013-07-27 -- -- Ingemar Bergmark -- www.swipeware.com local M = {}; local app = require("appglobals"); local directives = require("directives"); local iap = require("inapp"); local ads = require("ads"); local flags = app.getFlags(); local settings = app.getSettings(); local screen = app.getScreen(); M.isActive = false; -- true if any ad network is showing an ad M.adTapped = false; -- used to prevent new ad from showing when coming back from a tapped ad -- ------------------------------------------------------------------------ -- Vungle -- ------------------------------------------------------------------------ local VUNGLE\_APPID = { Apple = {ID = "xxx"}, Google = {ID = "com.swipeware.freemium.appname"} } local vungleListener = function(event) local eventType = event.type; local isError = event.isError; if (eventType == "adStart") then if (isError) then M.showRevmobPopup(); else audio.pause(flags.chatterChannel); M.isActive = true; flags.cancelAllTouches(); end elseif (eventType == "adEnd") then audio.resume(flags.chatterChannel); M.isActive = false; end end local vungleInit = function() if (directives.STORE ~= "Amazon") then ads.init("vungle", VUNGLE\_APPID[directives.STORE].ID, vungleListener); M.showVungleFullscreen = function() if (not M.isActive) then ads.show("interstitial"); else print("vungle: ad is active") end end end end M.isVungleAvailable = function() if (type(ads.isAdAvailable) == "function") then return ads.isAdAvailable(); end return false; end -- ------------------------------------------------------------------------ -- revmob -- ------------------------------------------------------------------------ local REVMOB\_APPID = { Apple = {ID = "xxx"}, Google = {ID = "yyy"}, Amazon = {ID = "zzz"} } local revmob = nil; -- RebMob handle local revmobFullScreenAd = nil; -- revmob fullscreen ad local revmobPopupAd = nil; -- revmob popup ad local revmobAndroidKey = "Google" -- revmob key for android (must be defined even on iOS builds) local revmobFallback; -- fallback popup/full in case chartboost ad not available if (directives.TARGET == "Android") then revmobAndroidKey = directives.STORE; end local showRevmobAd = function(adType) M.isActive = true; flags.cancelAllTouches(); if (adType == "fullscreen") then revmobFullScreenAd:show(); else -- popup --revmobPopupAd:show(); end end local hideRevmobAd = function() if (revmobFullScreenAd) then M.isActive = false; revmobFullScreenAd:hide(); revmobFullScreenAd = nil; end if (revmobPopupAd) then M.isActive = false; revmobPopupAd:hide(); revmobPopupAd = nil; end end local revmobListener = function(event) local eventType = event.type; local adType = event.ad; if (eventType == "adReceived") then if (flags.canShowAds()) then flags.pauseGame(); showRevmobAd(adType); else hideRevmobAd(); end elseif (eventType == "adClicked") then M.adTapped = true; M.isActive = false; elseif (eventType == "adClosed") then hideRevmobAd(); elseif (eventType == "adNotReceived") then hideRevmobAd(); end end local revmobInit = function() revmob = require("revmob"); local locationHandler = function(event) -- Check for error (user may have turned off Location Services) if (event.errorCode) then print("Location error: "..tostring(event.errorMessage)); else revmob.setUserLocationLatitude(event.latitude); revmob.setUserLocationLongitude(event.longitude); revmob.setUserLocationAccuracy(event.accuracy); end Runtime:removeEventListener("location", locationHandler); end local revmobIDs = {["Android"] = REVMOB\_APPID[revmobAndroidKey].ID, ["iPhone OS"] = REVMOB\_APPID.Apple.ID}; if (flags.TEST\_MODE) then revmob.startSession(revmobIDs); revmob.setTestingMode(revmob.TEST\_WITH\_ADS); revmob.printEnvironmentInformation(revmobIDs); else revmob.startSession(revmobIDs); revmob.printEnvironmentInformation(revmobIDs); end Runtime:addEventListener("location", locationHandler); M.showRevmobFullscreen = function() if (not M.isActive) then revmobFullScreenAd = revmob.createFullscreen(revmobListener); else print("revmob fullscreen: ad is active") end end M.showRevmobPopup = function() if (not M.isActive) then revmobPopupAd = revmob.showPopup(revmobListener); else print("revmob popup: ad is active") end end end -- ------------------------------------------------------------------------ -- ChartBoost -- ------------------------------------------------------------------------ local CHARTBOOST\_APPID = { Apple = {ID = "xxx", SIG = "xxx2"}, Google = {ID = "yyy", SIG = "yyy2"}, Amazon = {ID = "zzz", SIG = "zzz2"} } local chartboost = nil; -- Chartboost handle local overlay1 = nil; -- temporary overlays for chartboost background local overlay2 = nil; local removeOverlays = function() local destroyOverlay = function(object) object:removeEventListener("touch", object); object:removeEventListener("tap", object); object:removeSelf(); end if (overlay1) then destroyOverlay(overlay1) end; if (overlay2) then destroyOverlay(overlay2) end; overlay1 = nil; overlay2 = nil; end local createOverlays = function() local configOverlay = function(object) function object:touch(event) return true; end function object:tap(event) return true; end object:setFillColor(0, 160); object:addEventListener("touch", object); object:addEventListener("tap", object); object:toFront(); transition.from(object, {time=600, alpha=0}); end removeOverlays(); -- remove old overlays in case they are still there if (screen.left \< 0) then overlay1 = display.newRect(screen.left, screen.top, math.abs(screen.left), screen.height); overlay2 = display.newRect(screen.right+screen.left, screen.top, math.abs(screen.left), screen.height); end if (screen.top \< 0) then overlay1 = display.newRect(screen.left, screen.top, screen.width, math.abs(screen.top)); overlay2 = display.newRect(screen.left, screen.bottom+screen.top, screen.width, math.abs(screen.top)); end if (overlay1) then configOverlay(overlay1) end; if (overlay2) then configOverlay(overlay2) end; end local chartboostDelegate = { shouldRequestInterstitial = function(location) return true; end, shouldRequestInterstitialsInFirstSession = function() return true; end, shouldDisplayInterstitial = function(location) if (flags.canShowAds()) then createOverlays(); flags.pauseGame(); flags.cancelAllTouches(); M.isActive = true; return true; else return false; --ignore ad end end, didDismissInterstitial = function(location) timer.performWithDelay(600, removeOverlays); M.isActive = false; return; end, didCloseInterstitial = function(location) M.isActive = false; return; end, didFailToLoadInterstitial = function(location) M.isActive = false; if (revmobFallback == "popup") then M.showRevmobPopup(); else M.showRevmobFullscreen(); end return; end, didClickInterstitial = function(location) M.adTapped = true; M.isActive = false; return; end } local chartboostInit = function() chartboost = require("ChartboostSDK.chartboost"); flags.bundleid = "com.swipeware.freemium.appname"; chartboost.create{ appId = CHARTBOOST\_APPID[directives.STORE].ID, appSignature = CHARTBOOST\_APPID[directives.STORE].SIG, delegate = chartboostDelegate, appVersion = settings.version, appBundle = flags.bundleid }; M.showChartboostFullscreen = function(fallback) revmobFallback = fallback; if (not M.isActive) then chartboost.showInterstitial(); else print("chartboost: ad is active"); end end end M.startChartboostSession = function() chartboost.startSession(); end -- ------------------------------------------------------------------------ M.hideAds = function() hideRevmobAd(); end if (not iap.isBought()) then revmobInit(); vungleInit(); chartboostInit(); end return M;

@Mo I initialize the ad networks in mainmenu, that way I have a window to cache ads if they fail initially. So if a user returns to menu I can re-cache them. And yes I use M table to return.

Fantastic share i am having a great time looking into it. My code is some complex because I basically put everything in main.lua! I really like you guys modular approach. Naomi suggested that as well but did not get a chance to look into it. Thanks guys, that really, really help.

Mo 

ps: I did switch to “live” mode. It is so much easier to test the failures of not showing an ad! Thanks.

@ingemar you were right, your code is quite complicated. With less time, I wouldn’t do all that. But that’s a good piece, thank you!!

@Sagarpawaskar Cool! That make sense.

Thanks.

Mo

@Mo glad you like that approach.

@ingemar I was wondering why do you check (type(ads.isAdAvailable)==function) for a function?

@sagarpawaskar

I do that so that I don’t get a runtime error when running in the Corona Simulator.

@ingemar attempt to call ads.isAdAvailable() a nil value? I’m getting this error… If I get this to work, there’s nothing else I’ve to look into.

If you test for it being a function before calling it (as I do) you’ll get around this :-).

However you should only run in to this problem on the Simulator. A device should have this function if the plugin has been able to initialize properly…

all good, thanks @ingemar that worked , will test this app once on the device.

@ingemar where do you init vungle - main or menu?

…on line #329 of the module I posted :slight_smile:

That code is automatically run when it’s 'require’d in my game module.

Hey all you Vungle users,

Has anyone figured out how to use the “incentivized” ad unit type from Vungle?  It seems to require server to server communication via callbacks and a username but the docs are sparse and none of the examples I’ve found show how to use it. Any ideas how to harness it using Corona?  Does it require backend infrastructure or can it be accessed using Corona alone?

Ok, made some progress. I can see now the event listerner triggering and the print out of the name and type.

But no luck. The bizarre thing is that I also try to print the event.isError status but it is not displayed in the xcode console for some reason?

Aslo,  i need to figure out how to show another ad network if Vungle fail to show an ad. I can see this (Xcode console)  when it is showing an ad

event.name = adRequest

event.type = adStart

event.name = adRequest

event.type = adview

event.name = adRequest

event.type = adEnd

BUT the ad is not show the only event I see are:

event.name = adRequest

event.type = adStart

I tried using:

[lua]

if event.type == “adStart” and event.isError then               

 showRevmob()

end

[/lua]

Mo

EDIT: it is working now! The code above seems to display Revmob if Vungle has nothing to show. I also see now the isError status. I was printing using print("error = "…isError) instead of print("error = " , isError) !!!

Hi Mo,

I think this is not the best way to handle it.

Did you take a look at their example at github ?

-- show an ad if one has been downloaded and is available for playback function showAd() &nbsp;&nbsp;&nbsp;&nbsp;ads.show( "interstitial", { isBackButtonEnabled = true } ) end -- event table includes: --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;'adsRequest' --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.provider&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;'vungle' --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(string - e.g. 'adStart', 'adView', 'adEnd') --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.isError&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(boolean) --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event.response&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(string) -- create a 'function' ad listener function functionAdListener( event ) &nbsp;&nbsp;&nbsp;&nbsp;-- video ad not yet downloaded and available &nbsp;&nbsp;&nbsp;&nbsp;if event.type == "adStart" and event.isError then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statusText.text = "Downloading video ad ..." &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statusText.x = display.contentWidth \* 0.5 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-- wait 5 seconds before retrying to display ad &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer.performWithDelay(5000, showAd) &nbsp;&nbsp;&nbsp;&nbsp;-- video ad displayed and then closed &nbsp;&nbsp;&nbsp;&nbsp;elseif event.type == "adEnd" then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statusText.text = "Hope you enjoyed the video!" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statusText.x = display.contentWidth \* 0.5 &nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print( "Received event:") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vardump( event ) &nbsp;&nbsp;&nbsp;&nbsp;end end &nbsp;

They wait a bit if this is true and then try to call the ad again.

if event.type == "adStart" and event.isError then &nbsp;

Guess this is because a video ad takes time to load.

If I was you, I would call showRevmob() if you get the event.isError the second time.

Anyway, I think they miss a call that would pre-cash the video ad, something like ad.cache().

Then we could call if(ads.isAdAvailable()) ads.show() at any time we think is best for the user experience.

The problem I see right now is that if I call the ads.show() at game start, the user switches to the game-play screen and starts playing, and suddenly the video ad shows is not the best experience.

With ads.cache() we could call it on game start and the call ads.show() e.g. when the user finish playing.

Regards,

Damir.

I’ve just started playing with this myself, and as I understand it they’re already pre-caching their ads automatically after calling init().

I use if(ads.isAdAvailable()) ads.show() which is working very well so far. (I don’t try to show a vungle ad immediately on startup though, I use RevMob for that)

I have my own gamestate variable that I check and if the user is in any game-play state I don’t show/ignore that particular ad.

So far vungle looks great.

Thank you guys! @ubj3d: How you would you check for a second error? a flag, counter?  I believe ingemar is right about caching. I do call the caching function but i should try:

[lua]

if (ads.isAdAvailable()) then

ads.show()

else

showRevmob()

end

[/lua]

As ingemar, I do not use Vungle at app launch or resume. I use Chartboost first and if it fails then I use Revmob. In that order because Revmob has basically 100% fill rate. So I want to give Chartboost a first bite at the apple because I can control the minimum CPI i will accept!

I am still having issues with the show ad logic but it seems to work relatively well. When i try to show Vungle and nothing is there, it tries Chartboost. If Chartboost fails then it shows Revmob. Later on I will add cross promotion for my first app since I will soon have a second app!

If anybody has tried to integrate multiple ad networks logic)  I will love to hear about it!

Thanks again,

Mo

Hi Mo,

yes I was thinking about using a counter variable to check for the second error.

Another way would be to use if(ads.isAdAvailable()) ads.show().

Guess if you then get an error in the listener it is a “real” error (e.g. no ad available).

About using multiple ad networks, we have implemented a sophisticated method which involves a server with a database and a special made app also made in Corona where we can switch ads on/off, give each ad network a percentage of “ad space”, change the frequency of interstitilas etc.

We have integrated almost all ad networks available in Corona which deserved our attention during testing.

Now we are waiting for Apple to recover from the attack…

Regards,

Damir.

When I call .isAdAvailable() I get en error stating it’s a nil value.

Could you assist me with my code please?

--- main.lua: local ads = require "ads" local provider = "vungle" local appId = "someID" storyboard.state.showVungle = function() ads.show( "interstitial", { isBackButtonEnabled = true } ) end storyboard.state.hasCachedVungle = function() ads.isAdAvailable() end local function functionAdListener( event ) end ads.init( provider, appId, functionAdListener ) --- storyboardScene.lua: --- when I call it I get an error saying that isAdAvailable = nil if storyboard.state.hasCachedVungle() then storyboard.state.showVungle() end

When I call to show vungle without checking ads.isAdAvailable() value - it works fine.

Olaf

You have to run it on a device (or iPhone Simulator).

To avoid the error in the Corona Simulator, just test if system.getInfo(“environment”) == “simulator” and skip the call.