Ludicrous Software

Admob Ad Support in Corona

(February 1, 2011 Update: I’ve made a minor change to the code below to improve the reliability of ad display, which had been an issue with the previous version. If you’re using this code in your apps, please check the modification I’ve made below - it’s commented so you’ll see what’s new - and update your code to match. It should improve things for you. I’ve also updated the code in the zip file.)

(June 3, 2010 Update: Matt Pringle sent me an email to let me know that the sample files I provide in this post don’t work with beta 5 of the Corona SDK. It turns out that as a result of some bugs that were fixed in recently-released beta 5 of the Corona SDK, it’s necessary to include the following line of code in the html document:

1
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>

I’ve updated the html file in the zip package to include this code.)

Yesterday I spent some time trying to integrate Admob ads into a Corona application, and I thought I’d share the code required to make it work. I’ve implemented this in a free version of Knight’s Puzzle that I’ve submitted for approval to the App Store, so there should be a real-life working version of this out there soon (knock on wood). There’s a bit of hackery involved since the Corona SDK does not have native support for any kind of ad model at the moment, but the results are quite good and the actual process is quite simple. You can download this zip file to see the code required to make this work.

Right now, Admob provides support for two methods of serving ads: one is Objective-C-based, for apps built in Xcode, and the other is html/javascript-based, for web apps. This method actually uses the html/js code, even though your app may be distributed through the App Store. In a nutshell, the method is to display html ads inside your Corona app using the native.webPopUp() method. A new feature in the Corona SDK is the ability to specify a custom size/location for the web pop-up, rather than having it take over the entire screen. We can use this feature to create a pop-up that is the same size as the mobile ads that Admob serves, and position it wherever we want in our app.

To get this working, you’ll need to sign up with Admob and create a new ‘site or app’ - you want to create is an ‘iPhone web’ site/app. Once you’ve done that, Admob will provide you with a chunk of html code that you’ll need - I won’t walk you through this process, but it’s very straightforward. You can see an example of the code that’s generated in the html document that’s in the zip package; the only thing that will be different for you is the value of ‘pubid’ (I’ve removed mine).

Next, the code to create the actual web pop-up and to handle the ‘clicks’ on the ad. This is all contained in the main.lua file provided in the zip package:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
local adSpace

local function showAd(event)
     -- Is the url a remote call?
     if string.find(event.url, "http://", 1, false) == 1 then
          -- Is it a call to the admob server?
          if string.find(event.url, "c.admob.com", 1, false) == nil then
               adSpace.url = event.url
          else
               -- an actual click on an ad, so open in Safari
               system.openURL(event.url)
          end
     else
          -- Feb 1, 2011: if using the old version of this code, remove the
          -- following line:
          -- adSpace.url = event.url
          -- and put in this line instead:
          return true
     end
end

adSpace = native.showWebPopup(0, 432, 320, 48, "ad.html", {baseUrl = system.ResourceDirectory, urlRequest = showAd})

The basic code to create the web pop-up and show an ad is the very last line. It creates a pop-up that’s 320 pixels wide by 48 pixels high, which is the size of an Admob iPhone web ad, and positions it at the very bottom of the screen. The return value of the native.webPopUp() call is stored in the adSpace variable for later reference. It displays the ad.html file in the pop-up. The baseUrl value is set so that the app knows to look for the html document in the app bundle. The urlRequest value is where the hackery comes in.

If urlRequest were not set, this would all work fine and the ad would load as it should. However, when the user clicked on the ad, the resulting web page would be opened inside the pop-up, which is only 48 pixels high. This, as you can imagine, is not an optimal browsing experience. So, the showAd function is called to see whether the requested url needs to be loaded in Safari, or whether it can be loaded inside the pop-up.

The basic logic is to check whether the url requested is a remote url (begins with http://). If it is, the next check is whether the request is going to c.admob.com; if it is, then it’s a request for the ad, and so the url gets sent back to the pop-up. If it’s not going to c.admob.com, then it’s an actual click on an ad, so the url gets redirected to Safari, using system.openURL(event.url). Finally, if the requested url does not being with http://, we can redirect the url back to the pop-up.

The code is generally pretty straightforward, so you shouldn’t have any problems following it. One neat thing I discovered while figuring this out, which I don’t think is in the Corona documentation, is that after you’ve created a web pop-up, you can provide a new url to that pop-up, rather than having to dismiss the current one and create a new one.

Also, although I used Admob for this example, the basic concept should work fine with any ad provider that serves mobile ads. You would have to modify the urlRequest listener to account for the different urls, and the size of the web pop-up would have to change, but those are pretty basic changes.