This article is cross-posted from my personal blog.
Background
In preparation for the upcoming DotNetNuke Hackathon in St. Louis, I have been busy working on a new mobile application for the Android and iPhone platforms. Nik Kalyani and I have been playing with the Appcelerator Titanium product for the past several months and have been intrigued by it’s promise to allow you to quickly develop mobile applications for multiple platforms using the coding skills that many web developers already possess. When Nik started planning for the St. Louis Hackathon he decided to focus on building apps which bridge the mobile and DotNetNuke space. He immediately thought that Appcelerator was a natural tool to use.
What attracted Nik and I to Titanium was the ability to program in JavaScript with a light sprinkling of HTML and CSS to create native iPhone and Android applications. It also helped that Titanium is an Open Source product which is a big plus for the DotNetNuke community. The real Titanium magic happens when you compile your application using Titanium Developer. At that point a native application is generated for either Android or iPhone, and coming soon the BlackBerry as well. Titanium Developer lets you run your app on the various platform emulators as well as allowing you to push your application directly to a physical device. As a final step, Titanium Developer even assists with publishing your finished application to the Android Market and the iPhone App store.
When we started planning for the St. Louis Hackathon event we wanted to be able to provide some ideas for applications that Hackathon participants could build. We also wanted to find a nice simple mobile application that we could build prior to the event to help people get up to speed before the Hackathon kickoff. Our original idea for our sample app was to create a user group application which would help people find user groups in their area. We thought that this application had the ability for us to showcase many of the really sexy features of mobile development like XmlHttpRequests, geolocation and mapping – all of which are available within Titanium.
Like all good developers without a project manager around, we were able to quickly blow up the scope until we actually ended up with a rather full featured community application. Over the coming week I’ll be showcasing much of the code from the User Group portion of the application with the intention of showing off the complete application at the Hackathon. Chris Hammond discusses how to get started with Appcelerator Titanium and will have additional posts about mobile development and Appcelerator during this time as well so that hopefully by the time the Hackathon starts people are able to hit the ground running.
My posts over the coming week are an opportunity to help you avoid some of the pitfalls of developing mobile applications with Appcelerator. Like every development platform, the correct approach is not always obvious and can often require a lot of effort to figure out. I hope that by showing you some of my own hard learned lessons that you can experience more of the joy of mobile development and less of the pain. Most programmers I know love that first time feeling of successfully completing a project on a new platform and I hope that with a little guidance you can be up and running quickly with your own mobile application that works well with your DotNetNuke website or module.
Using Webservices
During development of our sample application, I ran into a number of areas where I had to dig into the documentation and figure out how things actually worked. Titanium has pretty decent documentation, but because of the rapid pace of change in the platform, it is not always up to date, or does not reflect bugs in the platform which prevent it from working as documented. As I cover different aspects of development I’ll try to point out some pitfalls which will help smooth out your development experience and minimize your learning curve. If all else fails though you can always post a question in their Q&A forums.
One of the first tasks I had to figure out was how to call webservices using Titanium. Using the Mobile API Reference and their KitchenSink sample application I was able to quickly determine that calling webservices was very similar to using the AJAX methods in jQuery. The KitchenSink sample includes the following code for making a webservice call.
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function()
{
var doc = this.responseXML.documentElement;
var elements = doc.getElementsByTagName("screen_name");
var screenName = elements.item(0);
var screenname = Ti.UI.createLabel({
textAlign:'center',
height:'auto',
width:'auto',
top:20,
text:screenName.text
});
Ti.UI.currentWindow.add(screenname);
var textarea = Ti.UI.createTextArea({
borderRadius:5,
borderWidth:2,
borderColor:'#999',
backgroundColor:'#111',
color:'yellow',
bottom:10,
left:10,
right:10,
height:300,
font:{
fontFamily:'courier',
fontSize:10
}
});
textarea.value = this.responseText;
Ti.UI.currentWindow.add(textarea);
};
// open the client
xhr.open('GET','http://twitter.com/statuses/show/123.xml');
// send the data
xhr.send();
As you can see, this is not so complicated. It is mostly creating an XHR object, opening the request, sending the data and then waiting for the return call to occur in the onload event. It’s not quite as clean as the jQuery implementation, but it is workable. Where things start to get a little tricky is when you want to send data to a webservice using a Post request. Looking at the API it seems that it should be as simple as creating an object and passing that object in the xhr.send() method:
xhr.open('POST','http://myapp.com/mywebservice.asmx');
var data = {
lat: '37.549528',
lng: '-122.316826',
radius: 50
};
xhr.send(data);
Unfortunately, this did not seem to work and always generated errors on the server. The problem turned out to be one that bites a lot of people doing webservice calls with JavaScript, whether they are using Titanium or jQuery. Dave Ward posted a really good blog post which explains the problem. The bottom line is that I needed to send my data as a string and not as an object. Regardless of what the Titanium documentation says, if you try to send the data as an object you will get an error. Once I figured this out. Everything started working and I was able to move forward. Unfortunately for me my Bing skills were failing me that day and I wasted many hours on this silly little problem. Now that I have pointed it out you should be able to avoid it in your own apps.
Of course this is just the tip of the iceberg when developing mobile apps which talk to webservices. You will want to make sure that you include error handling since you never know when someone might hold their phone incorrectly and drop the data connection. The Titanium HTTPClient allows you to hook up the onerror, ondatastream, onreadystatechange, onsendstream and onload functions. Using these functions provides you with plenty of visibility of what is happening with any individual request. I definitely recommend looking through the various XHR examples provided in the KitchenSink sample app.