A few weeks ago I posted about the Ads module within the RMobio ruby gem (which is posted on RubyForge). The ads module allows developers to easily add advertising to their mobile apps written in Ruby (actually it should work for any web app written in Ruby app, but the advertising networks supported are mobile focused). You make calls to the get_ad method within your app and can configured the ad network and your publisher ID as you go.

Some of our apps at Mobio are written in Java however. We needed a way to allow those apps to use the ads module as well. So we needed to create a REST interface to the Ads module. However the ads service goes further and allows developers and administrators to manage their list of configured ad networks as well as their apps and pages within their apps. Specifically it lets the appropriate ad network and keywords to be used for any app, or specific page within the app, to be configured. Then developers simply call get_ad and identify the app and/or page that they are calling get_ad from. The service then determines the appropriate ad network to connect to.

Administrator Usage

The administrator (or developer) that wants to set up the ads service for an app has two primary tasks: set up the ad network and then configure apps and/or pages to work with those ad networks. First they will need to connect to the ads service from their browser. The ads service currently hosted at http://marge.qa.mobiolabs.com/hub/ads/pages/

Setting Up Ad Networks

After clicking on Manage Networks the administrator should add networks for the mobile advertising networks they wish to use. Their are currently four types supported: Google (AdSense), mKhoj, Smaato and AdMobs. More advertising networks will be added soon.

First enter an arbitrary name for your network that is unique to you. Then choose the type of network (from those just discussed). Then enter the URL to connect to. Some networks may not use this argument, they may just always be available at the same URL. So this is optional for example with Google AdSense.

Then enter the login (client or publisher ID) for your network. Many ad networks (such as Google AdSense) don’t require a password.

Configuring Apps and Pages

The developer will call the ad retrieval method from their app, typically supplying the call with their app name and the page within their app. If it is planned to use a single ad network AND keywords for retrieval for the entire application, then only apps need to be configured.

In either case, first click on Manage Apps and add the name of your application. Then choose a network for it (generally the one you entered above). If you choose a network that isn’t “yours” (your login ID) you’ll just end up making money for someone else! (hence the lack of “security” for this choice).

If you wish some or all pages of your application to use a different ad network and/or keywords than the one configured for the overall app, then enter some pages as well. Supply the URLs of the page in the “page” argument. Or just supply a symbolic name for the page, such as “Home Page” or “Options Page”. The “page” name will only be used to look up pages when the developer makes the get_ad call.

Developer Usage

Once networks and apps and pages have been configured the ads service can be used from your applications. Simply make a call to the get_ad method on the pages controller. Supply arguments of the “app” and/or the “page” within your application. These should match values that have been configured in the previous steps.

If the ads service can’t find the page supplied then it will drop back and use the ad network and keywords set up for the app. The page argument does not even need to be supplied if you are using the same network and keywords for all pages in your app. The app argument also doesn’t need to be supplied if you’re just going to use pages for lookups. In other words it can be as “simple as you want it to be”, though many developers find having a hierarchy of pages with specific ad networks and keywords and overall apps when pages can’t be found to be a helpful set of abstractions.

Terms of Service

This is a developer testing instance of the ads service. We do keep it running. But we don’t guarantee any terms of service for it. Also note that its not “multitenant”. The assumption is that any developer using it will create their own app. The only thing that will happen by using someone else’s configured app in your code is that you will end up crediting their publisher ID and giving them money. So if you do choose to use this for development and experimental purposes you’ll want to set up your own app. If you want to use this in a production app, contact me and we can arrange for use of one of our production instances.

In general we will be making all of our platform available for other mobile app developers soon. So access to a production ready ads service will just be a natural outgrowth of that.

You may have noticed in the previous post that we used the RMobio ads module merely by doing “require rmobio/ads” inside our controller class. This is terser than and less repetitive (in the spirit of Don’t Repeat Yourself) than doing a require followed by doing an include inside the module.

What this does is build up the specific class for the ad_network that is configured in the generic RMobio configuration file (RMobio.yml). If no ad network is configured, we still want to have calls to getAd and getAdByPage not fail. So there is a module called no_network.rb with those calls stubbed out.

We then do the require of whatever ad library is chosen. Finally we generate the code dynamically (using “eval”) to do the include of the module name (using the handy camelize function to get the module name from the filename). This generic technique of dynamically determining the right module to include can make your code a briefer and terser. We use it in the RMobio gem and I’m hoping it catches on wider in the Ruby community.

We posted our RMobio gem for mobile Rails development on RubyForge about a month ago. I’ll be doing a series of blog posts describing how to use the various goodies inside it over the next few weeks.

The first one that I’d like to discuss is the “ads module”. This lets you easily add mobile advertising to your Rails apps without being familiar with the syntax for the API of each particular ad network. The networks that we support include: Google’s Mobile AdSense, AdMobs, mKhoj (an India-based mobile advertising network) and Smaato (an ad aggregator which serves up mobile ads from many other ad networks).

You will need to work with one or more of these ad networks to get a “publisher ID” before using our ads module in your Rails apps. But you will not need to learn any of their APIs. You’ll simply embed calls to either “getAd” (which takes a keywords argument) or “getAdByPage” (which assumes that the ad network “scrapes” your page to determine appropriate content) in your controller methods. Then just use the @ad variable inside your views. The specific ad network used is configured by setting the ad_network: variable in the rmobio.yml file used to configure all rmobio gem capabilities (the specific instructions appear below).

This whole approach makes it very easy to both start monetizing your applications with ad networks and also switch it easily later without making code changes.

Steps to Add Advertising to Your Apps

Follow the specific steps below to add the ads module to your apps:

In environment.rb, add the following two lines to the bottom of the file (we want to load the configuration statically):

require 'rmobio/config_manager'

Edit the file rmobio.yml in the config directory (creating it if necessary) and add the ad_network property in the appropriate section (development:, test:, or production:). For example the following sets the ad_network to ad_sense in the development: instance.

Embed the ad module in your controller. Specifically add “require mobio/ads” to the inside of your controller. Note that your ads module does some “tricks” to not have you have to do the “include” as well. We’ll describe this technique for making “requires” and “includes” DRYer in a later post. For now here’s an example of how to use it:

Call ad retrieval functions from your controller methods. The function “getAd(keywords,adClient)” takes a set of keywords separated by spaces. It also takes your publisher ID. For example the call below will invoke Google’s Mobile AdSense (if the ad_network is set to that value in rmobio.yml) for ads related to the keywords “India” and “cricket”. You can also call “getAdByPage(adClient)”

def index
getAd("India cricket",MOBIO_CONFIG['ad_client'])
end

Use the ad variable in your view. The getAd method populates an instance variable called @ad. You can that use that variable in your view. For example:

Last week Yahoo announced their new mobile platform, Blueprint. It was very gratifying to see that what they have built, is, like our platform, derived from XForms.

There are a few significant differences:

1) nothing concrete is available today but the XML schema for controls and elements.

That’s not a bad thing. I applaud Yahoo for publishing their roadmap in advance.

2) in “phase 1” of the Blueprint platform, no Model-View-Controller capabilities of XForms are present

This is a bit surprising. MVC is the source of much of XForms’ power. Clearly its coming eventually. But many developers may decide that the learning curve of another syntax is not worthwhile before they see the key benefits of the XForms approach.

3) the documentation says that XPath is not available now for data binding

Confusingly they say “the current Blueprint implementation, however, has a limitation of one model and one instance per page, so there is no need to include such details”. Even with one model, I still want to be able to use XPath to perform data binding. In other words, XPath is not only useful in a case of more complex MVC separation, where a view or controller may use multiple models. Its also useful to grab data from more complex single models, especially where the model (data) may be coming from an existing web service with a nontrivial mapping to your view.

4) unnecessary deviation from the XForms standard

Where XForms has a working syntax for controls or containers, we use it. We add plenty of proprietary controls and extensions as we need to.

5) the current set of controls is fairly simplistic.

As they put it “there are no spinning image cubes”. Well and good. They are phasing things right. We couldn’t use Blueprint today though to give the look and feel of the applications that we’ve built.

Overall I think Blueprint is a great thing for both the industry and for Yahoo. If I was a mobile developer without benefit of the Mobio platform, I would certainly start using the Yahoo platform over, for example, using a procedural Java-oriented, statically compiled approach like Android.

As much as I would love to stay on Rails-based blogging software, I’ve been experiencing a bunch of strange Mephisto bugs recently. And the project seems to not really be actively maintained. So I’m switching over to WordPress. There aren’t many good options for getting all of the content over, so the comments are lost here.

I took some time over the last week to port our CheapGas application (which finds the lowest priced stations near a given vicinity) to Android. I wrote this application in Rails originally. It supports both our runner and arbitrary WAP clients (using just one controller via techniques described in this blog). This port was to just build an Android client and call back to the my Rails-based controller of the production CheapGas app.

In the bigger picture, the tag-based approach that our platform would be a better way to do this. We could just send out tags and a “forms runner” running on Android could spew out the appropriate Android widgets dynamically. This has the obvious advantage of allowing a single codebase for multiple platforms. But, more fundamentally, it allows for a more dynamically changing user interface on the device, driven by server-based business logic. This also happens to be the approach taken by ZK Mobile. Certainly this is part of the appeal of web-based applications in general, and given Google as the standard-bearer of web-based apps versus “thick desktop” equivalents, it’s curious to see the out of the box Android bias towards statically designed interfaces.

Exploring that apparent paradox might be another post. Today I’ll just provide some more tactical feedback on what I’ve seen in building a single application, with conventional upfront XML-based layout and the application running locally (as opposed to a runner interpreting server-delivered UI elements and forms). To start off with, let me say that, given the constraints of wanting to build an application that is laid out up front, I like the Android toolkit. I was able to build a functioning application fairly quickly. The overall Eclipse-based environment is easy to use and debugging was a breeze. That said, I have several bits of feedback of areas for improvement:

The API is just not completely documented. I found myself guessing and experimenting many times to determine the precise behavior and requirements of an API call. Example: setting underline paint style doesn’t work to create underlined text (e.g. “textField.setPaintFlags(android.graphics.Paint.UNDERLINE_TEXT_FLAG);”). Instead it creates a strange, faintly visible font. There may be some other way to do it, but it just plain isn’t documented. There are ways to set bold and italic styles, but apparently not underline (or its just not done yet)

The componentry is a strange mix of simple low level “simple individual controls” (editable text, spinner, checkbox, radio buttons) and “high level” controls such as imageswitcher and gallery (which are somewhat overlapping). What is needed is more of the “intermediate controls”. For example, more advanced list and grid behavior (such as our “fisheye” control). One guesses that they are waiting for third parties to supply these. Or they just haven’t done them yet themselves.

Would be nice to have XPath with DOM usage instead of being forced to use just DOM navigation methods (e.g. getElementsByTagName). This is a potential memory and performance hog.

The Android emulator is astonishingly slow. Yet despite Android’s own slowness, calls to other systems which take reasonable amounts of time result in timeout dialogs popping up. These include not just calls to my own server-based backends over the Internet, but also calls to other Android activities such as their contacts list and phone dialer.

Linkify.addLinks() is a very handy utility method to create links from text (though I’m not even sure how I found it). It would be even cooler if that utility could optionally create onClickListener() methods for those links. The code for creating those onClickListener() methods to respond to those links is repetitive and should be automatable.

It would be very useful to be able to create indexed arrays of elements (that can then be iterated through) through XML layout

Given Android’s lightly documented state, a drag and drop layout designer would obviously be desirable. DroidDraw is a useful utility but doesn’t expose all options.

[Posted Later By Adam in Response to DroidDraw Developer Brendan – Since Mephisto Comments Mysteriously Stopped Working] As far as “unexposed properties” it would be nice to have “maxlines” on TextView control (that’s one that springs to mind, I think there may be a few others). What would also be nice to have is either dropdowns on control height and width properties for wrap_content and fill_parent options. It would also be useful to be able to specify width in other units available (px, ems, etc.) by switching between units from a dropdown list.

At Mobio, we’re all about supporting every phone in the universe from our apps. Our platform enables one app to target the plethora of J2ME devices, Windows Mobile and Blackberry smartphones – all from a single app and codebase. So we tend not to be too centric on a single device. I carry a varying set of devices around with me. This fall I had the pleasure of creating and co-teaching a course on mobile application development at Carnegie Mellon West with Todd Sedano and Vidya Setlur (more on the content of that class later). Nokia graciously supplied all of the students and myself with Nokia N95s just as they arrived on the US market.In a short time, this has become my favorite featurephone (a phone emphasizing lightweight and usually sporting a T9 keyboard versus smartphones which feature QWERTY keyboards). It features a 5 megapixel camera with Carl Zeiss optics. It has support for Wifi, Bluetooth, GPS and microSD . Among its many other markets, this is the outdoorsman’s device par excellence. I never do an ultra without it. I would take an N95 over a iPhone any day.

Specifically here’s what I liked about this phone:

high megapixel camera, which can be easily activated by just opening up the lens

upload to Flickr

GPS with a nice mapping application

very lightweight

video output (this was great for students demonsrating their projects)

What could be improved:

a better oncamera tagging and photo arranging capability, using all device capabilities, such as GPS and phone contacts (more on this later)

batch upload of photos

Somehow the camera keeps ending up in video mode although I’ve never specifically set it to do so

The phone app should appear on the home screen. When I’ve leant the phone to people they’ve had a hard time figuring out how to make a phone call

Apparently an 8GB version for North American is on the way with support for 3G networks as well.