App-Pi

The Idea

LogoI had previously worked on Ti-Browser, a way to create Native UI Demos using just XML. It worked great. So great, in fact, that I realized that it’s hard to tell the difference between a High Fidelity UI demo and a real app. Problem was, to make highly interactive “Apps”, you had to install and run code on the server to send a dynamic XML response. Since I was footing the bill for the servers, I didn’t want to open it up and let users put whatever code they wanted on it. That was a recipie for disaster. I disaster I’d have to clean up myself.

Enter Raspberry Pi

The solution to the problem was obvious, once it hit me. Put the whole server environment on a Raspberry Pi. That way, each developer would have their own isolated server to do whatever they wanted to with.

This would allow users to have their own private, isolated development server for App-Pi. This allows them to put whatever information might be necessary, such as userid’s/passwords without a worry that their system might be hacked. This is assuming, of course, developers don’t open up their Pi’s to the world. And at USD$35 for a Pi (B+), the price point made it very feasible.

Mobile Run Time Engine

App-Pi works by having a mobile “Run Time Engine” that sends/receives XML from a server. After receiving XML, it the Native UI on the fly. When events fire, the event info is sent back to the server (Raspberry Pi) encoded as JSON.

For instance, when the mobile RTE starts up, you put in the URL of a Raspberry Pi server, or any server that can send the correct XML. The RTE then sends an HTTP request to that URL and renders a UI based on the XML that comes back. When events fire, the event information is encoded as JSON and sent back to the server, which interprets the event information and sends back more XML. The new XML can either modify the existing window elements or open a new Window.

Building a Mobile Run Time Engine to download XML and build a 100% Native UI certainly has it’s challenges. Performance and off-line operation are just two of them. I’ll spend the rest of this article describing how I overcame these using my favorite development tool, Titanium by Appcelerator.

Enter Titanium

Titanium was uniquely qualified to help me build the App-Pi runtime engine. Some of the features of Titanium that helped me bring this to life were:

  • Creating apps using JavaScript. This allowed me to get things “up and running” quickly and use existing JavaScript libraries.
  • Use Titanium modules to quickly add functionality to the run-time engine, such as iBeacon and Barcode scanning support.
  • Creating a Sqlite Database to help support content caching and optimize the user experience while online. Titanium’s Database API made it easy to get this feature working quickly.

Multiple Cache Techniques

Since the App-Pi RTE is dependent on the back end server to send it XML and tell it what to do, I wanted to have some form of caching to help improve performance. This would also help not having to make an HTTP call for each and every action. I implemented a few types of caching to help reduce network calls and make the Apps a bit snappier.

Output Caching

This form of caching will cache an HTTP response. When another request is made to the same URL with the same data POSTed, the cached result will be used. This is where the entire response is cached. When a URL is called, a ‘signature’ is generated which is composed of the URL, and any data that is posted to the URL. This creates a unique key that is stored in a Sqlite database, along with the response from the HTTP call, if the XML indicates that it should be cached, and how long the cache should be considered valid.

When another HTTP call is about to be made, this ‘cache signature’ is built and the database is queried to see if a cache entry exists that has not expired yet. If there is a valid cache entry, that is used and the HTTP call is not made.

This form of caching, along with some of the XML templating described below helps reduce network calls and the amount of XML that needs to be sent.

Native Windows from XML

App-Pi creates native screens from XML. For instance, you might have a simple XML snippet such as:

<Alloy>
    <Window>
        <Button text="Hello World" width="125" 
            height="45" borderColor="blue" title="Hello World"  />    
    </Window>
</Alloy>

The App-Pi run-time engine receives this XML and builds up native components on the fly and presents the 100% Native UI instantly. What first seemed like a daunting task became more manageable because of Titanium.

Due to the consistent parameter interface to create Titanium objects (windows, button, slider, etc.) It became easier to do this than I originally thought. I was able to use the Titanium naming convention for object properties and use those in the XML to represent the screens. I then had a path to take the XML for an object and create a 100% native object in Titanium based on that XML.

A nice side effect of this approach is that the XML that App-Pi uses is very close the XML format used by Titanium Alloy. This means that App-Pi can be used to build these types of server-based Apps. If at some time the App needs to be converted to a more traditional Titanium Alloy App, the XML can be re-used. This will help get the Alloy App built much faster than starting from scratch.

UI Templating

Once I got the basic “objects from XML” working, I began building more complex screens. I ran into situations where the same basic XML was required for an onscreen object, but I didn’t want to repeat all the XML over and over. It’s simply bad design and it would increase the overall download times.

To solve this I came up with a way to have “Template XML” in the response XML. These templates wouldn’t be rendered directly but would be referenced in the “main” XML. The XML templates had “tokens” (such as ~1~, ~2~) that would be replaced when they were used. This allowed the majority of the XML from the template to be used, but still allow some variable parts.

<Alloy>
    <Template id="templ1" >
      <ImageView class="wi1" >
        <Label class="wlbl1" text="~1~"  />
        <Label class="wpct" text="~2~" />
        <Label class="wlbl2" text="~3~" /> 
        <ImageView     class="wiv2" />
      </ImageView>
    </Template>

    <Window  title="Weather">
        <Tpl templId="templ1" repl='{"~1~":"9AM","~2~":"30%","~3~":"45"}' />
    </Window>
</Alloy>

In the image below you can see an example of where I used Template XML to reduce the total XML content. The first thing I want to point out is that this isn’t the built in Weather app for iOS. This is a replica of it that I made using App-Pi. As I was doing it there were 2 opportunities for templating the XML, one in the daily weather “icon” and each entry in the day of week list below.

The XML above the image gives you a feel for the savings in XML achieved by templating. The <Tpl ... > element is where you ‘instantiate’ a instance of a Template. The repl attribute contains the values for the replacement tokens. This allows you to create an instance with customized variables where you need them.

Weather Demo

Give your Apps some Class

Once I was able to reduce the redundant XML via ‘Template XML’ fragments, I still had another issue. There were many properties that were repeated on many different objects. To solve this issue, I took a lead from Titanium Alloy and implemented a “css-like” way of containing attribute values in “classes”.

Using the below syntax, you can apply a set of attribute/value pairs to a object type (button, table view row, etc.) or define a ‘class’ and attach that class to any object type.

".wi1":{
     "left":"5dp",
     "width":"47dp",
     "top":"0",
     "bottom":"0" 
}

<ImageView class="wi1" >
</ImageView>

As you can see in the Weather App example above, the XML required is drastically reduced by combining XML Templating and Classes to eliminate redundant attributes. This helps you abstract out the look and feel from the core XML code and reduce redundant XML and attributes, which speeds up the overall responsiveness of the App.

Events

To make the leap from a static UI demo to an App, the RTE needs to do something with events. Included in the UI XML are attributes indicating what events to respond to, and what URL to post the event info back to. The server then can see the event info and respond with more XML.

This became achievable with Titanium as well. Due to the consistent data model for events, I was able to have a single handler for just about any event fired. Since the application code was in JavaScript and the event data was already in JSON, it was a simple path to pull it all together.

When an event fires, the event handler basically packages up a sub-set of the actual event information into JSON. It then uses the Titanium HTTPClient to send the data to the indicated URL. The server then analyzes that and returns more XML, which the mobile RTE processes.

How Titanium Helped

Appcelerator’s Titanium made building the Mobile RTE much easier and faster than going with traditional tools like XCode. Cordova/PhoneGap wasn’t an option as I wanted a fully native client on iOS and Android. Although my early work was mainly on iOS, I have begun making the necessary tweaks to run on Android as well.

Being able to rapidly iterate through functionality, along with Titanium Studio’s integration with GIT made my development cycles much faster. I can’t image getting this far this fast using any other dev tool.

Conclusion

With App-Pi, I’m trying to show an alternative way to build Apps quickly and easily. App-Pi won’t be used to create every app under the sun, but it fills a void. Right now, there’s a significant hurdle to overcome if you want to experiment with Mobile Apps, even with time-saving tools like Titanium.

App-Pi.com (and it’s related product Ti-Browser.com) is aiming to allow you to get up and running experimenting with fully interactive Mobile Apps easily. Without having to download and install SDKS, development tools, etc. You can simply start making Apps right on the mobile devices you already own. Download the free RTE from the App Store, put in a URL and you’re off and running to building your App.

To help make all this a reality, I’m running a Kickstarter Project that will deliver a complete, plug and play development environment on an SD card tailed for a Raspberry Pi. If you like this idea and want to help bring it to life, head on over to the Kickstarter Page and give it some love.

Code Strong!

John Anderson has been involved in mobile development for the past 3 1/2 years. After seeing the writing on the wall when the first iPhone came out, he quit his job and dove into mobile. Using tools such as PhoneGap/Cordova, Sencha Touch, jQuery Mobile, and of course Titanium John has been able to make some cool apps for clients. Most recently wrapping up a high profile iPad app for Gulfstream Aerospace in Savannah Gerogia, John had some spare time and turned his attention to Ti-Browser.


Comments