Appcelerator Titanium - Understanding the Namespace Pattern

A couple of people have asked me to write an explanation on the namespace pattern in Titanium - otherwise known as "Tweetanium" - however for the purposes of this example I'm going to continue to call it the "Namespace" pattern as that is its proper name in Javascript. Appcelerator is also currently pushing the CommonJS pattern which is fine, however I find the namespace pattern simpler to understand and if you can implement this properly in your apps you'll go a long way to acheiving better performance, stability and memory management.

There are three main reasons for using this kind of pattern;

  1. It stops you polluting the global scope. It does this by creating one (ideally) global object that all the functionality for your app is added to, 
  2. It helps you avoid naming collisions or excessive variable prefixing (ie creating stacks of vars that look like item1, item1_1, __item1, etc),
  3. Memory management - by putting everything into the same global object namespace, you avoid multiple Ti.include() statements, which are essentially including files over and over again unnecessarily. This is particularly prevelant when you start opening multiple window objects and have all your Ti.include() calls at the top; this rapidly leads to memory starvation and your app crashing.

Let's create a basic example application that reads in a couple of RSS feeds and shows them on two separate views, which have 2 separate JS files, and use the same context.

Create a new project in Ti Studio, call it whatever you want (I've called mine NamespaceMethod). Delete the pre-set code out of the app.js file, and then create two new files called feed1.js and feed2.js respectively, and add these to your Resources folder.


Now let's create the TableView for feed1.js...


...and feed2.js and save both of those files:


Run your app in the simulator now and you'll (hopefully) see a screen that looks like this:


Now let's fill those two TableViews with some data from 2 separate remote RSS feeds. We're going to define the feed URL's in app.js, then create a new javascript module file called api.js which is going to handle calling and returning our JSON data. Note here that you will probably want to structure your app a bit differently to this, but this example is more about showing you how to keep everything in that single namespace context.

Edit your app.js file by adding the following couple of lines to it, right after the RSSAPP declaration at the top. Note that I've used YQL to automatically do the XML Feed -> JSON conversion for us.


Now create the api.js file and save it to your Resources directory. Type or paste in the following code. This simple module just accepts a URL and creates a HTTPRequest and passes back the JSON-formatted response data via the 'success' function, or throws any errors back via the 'error' function.


Now we can call our "grabFeed" method from within the api.js file from anywhere in our app that utilizes the RSSAPP namespace. Let's populate the table1 object first - open up feed1.js and enter in the following code, just before the final line where you are adding the table1 object to the window. It should look like this:


Run your app in the simulator again and you should see that the first tableView (top of screen) is populated with RSS data from http://boydlee.com/feed.html.

As we're on mobile devices and we want to avoid using too much bandwidth (not to mention HTTPRequest collisions) we're going to populate the second table only when the first table has finished its data request/population. Add the following function call to feed1.js directly after the line "RSSAPP.table1.setData(rows);"


And now let's update feed2.js so it looks like the following:


Finally, run the app in your simulator. You should see table1 populated by data from http://boydlee.com/feed.html, via YQL, and when it has finished you'll see the data from the Appcelerator Developer Blog feed populate table2.

So what have we learnt from this sample? Firstly, you can see we no longer need to import the same file a hundred times - both the feed1.js and feed2.js files can access the webservice functions from api.js without multiple inclusions. This means less redundant code and less memory usage.

You also now have a convenient global structure - properties and objects added to the RSSAPP namespace can be accessed from within any part of your app at any time.

App-wide data can be instantiated once, and used over and over again. You can see this happening from the properties we created to hold the feed URL's - these were defined in the namespace from within app.js, and then accessed and passed around throughout our files.

Functions can now be defined as belonging to our namespace, meaning they can be executed from anywhere. You can see this happening when we call the loadFeed2Data function - it is declared within feed2.js but we're calling it directly from feed1.js, essentially removing the need for firing off multiple events or doing unnecessary Ti.include()'s.

Because all your windows and views exist in the same namespace they can be immediately instantiated - giving you faster app performance.

You can download the sample project here, and please comment if there's any mistakes in it (I wrote this fairly quickly!).



Write a comment

  • Required fields are marked with *.


If you have trouble reading the code, click on the code itself to generate a new random code.
 

Boydlee
Posts: 6
Comment
RE: memory management
Reply #7 on : Thu December 22, 2011, 09:25:28
Yeah, I don't disagree with Ivan... this was only meant to be a really simple example written in a way that people could hopefully understand. Much of the way you structure your code, either with CommonJS or using this kind of Namespace method, comes down to how your app is designed.
Ivan Škugor
Posts: 6
Comment
re: memory management
Reply #6 on : Thu December 22, 2011, 09:14:01
That was me, sorry, I forgot to write my name.


Ivan
Anonymous
Posts: 6
Comment
Re:
Reply #5 on : Thu December 22, 2011, 09:13:13
@Lance - no, that's just one thing. What about table views?

Anyway, in this given example, you won't have any problems, since there is one window and two table views. I think that any device could handle that. But, that's not my point. In general there won't be one window and two table views. There can be many windows and components, much more than some device can handle at one time. By using this approach you would eventually create all components that your app will use and they would remain in memory because they are added to global object. On other hand, by using function constructors, they will be created on demand and will be released when they are no longer needed. That way average memory usage will be constant over time (and will not rise until all components in app are created).

Also, from OOP point of view, function constructors are much better. For example, if you create blue button and store it in namespace, how can you reuse it in same window? By using function constructor that creates blue buttons, you can create as many buttons as you like.
Lance Spellman
Posts: 6
Comment
re: memory management
Reply #4 on : Thu December 22, 2011, 08:50:49
@Ivan,

In the given example, if Ti.Network.createHttpClient were moved out of the grabfeed function in api.js and supplied as an argument to it instead, then closed in the response function, would that satisfy your concern here?

Since there's only 1 window, I don't see the stability issue. It looks like the intent is to use only 1 window and to bring views in and out as needed. Or am I missing the point completely?
admin
Posts: 1
Comment
RE: Old Style - No Longer Recommended Approach
Reply #3 on : Thu December 22, 2011, 08:29:50
I actually said that Appcelerator is pushing the CommonJS pattern as a standard right at the top of this article, however I'd been asked how the single context / namespace pattern works hence the reason for this post. Writing your apps with the namespace method or the CommonJS method is still better than the alternative.
Aaron K. Saunders
Posts: 6
Comment
Old Style - No Longer Recommended Approach
Reply #2 on : Thu December 22, 2011, 08:19:39
This is not the recommend approach for implementing solutions with appcelerator. I would recommend reviewing the documenation listed on the website regarding using the commonJS patterns.

CommonJS Modules in Titanium - Documentation & Guides - Appcelerator Wiki http://bit.ly/v5MyOF
Ivan Škugor
Posts: 6
Comment
Memory management
Reply #1 on : Thu December 22, 2011, 08:03:55
I think it's better to put function constructors to namespace object instead of Titanium components because if you put Titanium components directly to namespace object (which is global object that will remain in memory), whey won't be garbage collected. It won't create memory leaks, but those components will remain in memory all the time app runs. In my opinion, from memory point of view, it's better to use function constructors that are creating Titanium components. That way Titanium components will be garbage collected once window closes. When window opens again, they will be re-created. Also, from stability point of view, reusing Titanium components in different windows is very unstable in < 1.7 SDKs. 1.8.0.1 seems much better, but still, I wouldn't rely on that (yet).