Post originally published on Appcelerator’s blog.
We’d like to share with you our story on how we built one of our iPhone apps – ArtistBox – and give you some insights on how we solved the (quite a few) issues that we had.
Artistbox is an iPhone application (built with Titanium Appcelerator) that finds the most complete information about your favorite artists: their biography, discography, news, concerts in your area and worldwide, videos, pictures and similar artists.
We strive to gather way more information than any other music discovery app on the market – for example by adding up-to-date news or hi-res pictures – and for the next versions we will add more cool features.
Why Titanium and why not native?
The app has two components: a client side – the app itself – and a server side. The whole app was build in five months by just two programmers @dan_tamas and @nosoloweb and we felt that coding it in objC wouldn’t have given us such an advantage from the time point of view.
There are many other reasons we chose Titanium:
- we might want to go cross platform and build an Android version. In this case we will only have to work on the UI side of the app while anything else will remain untouched and (fingers crossed) working out of the box.
- the fact that with a few lines of code we could have a working proof of concept was an amazing advantage over doing mockups and then implementing them in the code.
- we are very proficient with Appcelerator but we don’t know objC so we used what we knew best
- we bootstrapped this project so the development cost was only in hours of work – not having to pay one or more objC programmers was a real boost.
What issues we had to overcome
At this point we’d like to get a little more technical and explain how we managed to overcome the problems we had with the app.
One issue was the amount of the XHR calls we had to make. When the app opens it fetches all the artists in the device’s music library and also basic data for each of them.
As you can see in the screenshot the application is very visual, we have a lot of images and each artist page will have to display a lot of information (pics, latest album, latest video, news).
Way too many XHR calls
Our main goal was to make a very responsive app and due to the amount of server calls we had to find a balance between the information sent from the server and the number of calls. So we decided to go with many calls that return a small amount of information. The overall time the user has to wait might be bigger in this case but the app doesn’t lock and the feedback received is really fast.
We hit a wall here because the ASIHttpRequest – the objC library that Titanium uses on the native side – has a limit of 4 concurrent requests. The rest of the requests are put in a queue and executed when the previous calls finish.
What ASI does is perfectly correct, there is no point in overloading the network with too may concurrent requests but in our case the user would have had to wait for ALL the images from the previous windows to load in order to be able to receive the current window information.
We modified the XHR library to be able to handle a queue and priorities and we set the images to have the lowest priority while the artist information (JSON data) has the highest priority. At the JS level we limit the simultaneous requests for the images at only 3 so we always have a free slot on the native side for the data – higher priority requests are passed to ASI immediately.
Of course we take advantage of the caching that XHR does and we have a request to the server only once: the first time a new resources is requested or when the time to live expired. This way after the initial load the number of global requests decreases drastically.
Blocking the UI
The images are displayed in tableViewRows and if we had put the source of the image directly in the imageView the UI would have locked until the image was loaded.
What we did was create the image **but without** the source property, download the image locally and save it, then populate the source with the local file URL. This way the table will scroll normally and the pictures will be loaded one by one giving the user a way better experience.
We have to display lots of videos from Youtube which can be done in two ways:
- open the clip in mobile Safari or the Youtube app. This meant making the user leave ArtistBox and it was not an acceptable option.
- use webviews to load the clip – not a good approach as we had to keep the memory footprint as low as possible.
We came with a different approach: each time the user taps on a clip the app makes a call to the mobile version of the Youtube site, finds the streaming link and opens a video player with the source URL set to this streaming link.
The disadvantage is that the user will have to wait for an extra request to the Youtube servers but the overhead is not too big. The fact that he/she can see the video right inside the app makes it worth it.
There were a few more aspects we had to take care of. The first one was to show very clearly that the videos are coming from Youtube so we designed the thumbnails with the big “Youtube” watermark. We also had to filter the results within the Youtube APIs to return only the videos allowed to run on mobile and also in the user’s country.
You can download the module from Github, it is MIT licensed.
We believe that the complexity of ArtistBox pushed the Titanium framework to the limits as we are using a large number of its APIs in our app (tableViews, videoPlayer, audioPlayer, lots of imageViews, scrollableViews, httpClient, localStorage, UI transtions, webviews, etc) and not always in a common way. But we also believe that Titanium was the right choice and it reached our expectations
Titanium was the right choice and it reached our expectations 🙂
There are also a few modules we used and we want to thank their creators:
Enough talking, let’s see some action
ArtistBox is a very complex application that has to deal with a huge amount of information while also being memory leaks free. Making it stable and very fast were our main purposes because the users are very sensitive when it comes to huge loading times and repeated crashes.
Being able to offer them so much info about their favorite artists while displaying the UI in an instant were two very challenging tasks that we hope we completed successfully. You can see we’re not trying to be modest here, test the app for yourselves and let us know what you think.