Twitter LinkedIn E-mail RSS
Home Development Namespace to CommonJS Titanium Refactoring
formats

Namespace to CommonJS Titanium Refactoring

Appcelerator TitanWith commonJS now being included in the appcelerator titanium framework and the issue with loading files for Android. I decided that a bit of refactoring was required on one of my apps.

The Issues.

I have recently started taking the iPhone code and making it work on Android. One of the first issues I faced was to do with file loading. I have a routine which loads the abstracted code files at time of requirement instead of loading all the files in the app.js file, and when run on Android issues occurred with functions not being found. This turned out to be due to the files being lazy loaded into memory on the Android platform.

The application itself had been written using the namespace architecture and the only solution without using commonJS was to load all the files at run time in the app.js file. This meant that the app took way to long to load.

The Potential Solution.

CommonJS appeared to offer a solution to this and after investigation of the implementation within titanium I set about refactoring the code. This was not straight forward nor did it work on IOS and Android immediately.

Namespaces.

An application using the namespace architecture, basically enables code abstraction by making available functions across the whole application without the need to continually use event handlers.

The full commonJS solution enables the use of functions across the application by using event handlers. My solution combines this and the namespace architecture enabling me to have a common code base for multiple platforms.

The Process.

Firstly I read up on the Titanium commonJS implementation. Then I sat down and considered the best way to implement it. One decision I made very early on was that the common global reference files and tools I would include using Ti.include in the app.js file as these were already included here.

This didn’t break any rules as I was doing a direct include and the files had namespace variables and functions which were used across the whole application and didn’t have any dependencies on other files.

appceleratorThis being done I then had to implement the commonJS require into my file load function. I had an advantage; I didn’t include sub files in my files so this made it easy. A full commonJS implementation would have required me to code sub files for the major functions, but I was refactoring and this was a step to far.

The actual rewrite of the load function was pretty easy and I already had the calling code and the files loaded in the correct order. So I switched the Ti.include to be a require statement. Now because of the architecture of the app, which uses namespace functions loaded using anonymous functions, this meant that the required files had to be modified.

I already had the namespaces declared in my app.js file and I modified this to have a namespace for each file type, screen, tool, data model etc, and then created sub namespaces for each file. This meant within the files themselves I changed.

FSAP.CTL.FF.startfunction = function () { ……. } to exports.startfunction () { …… }

and this I did to all the functions within the files. I then loaded them as the .FF of the namespace was specific to the file name and I had been consistent with the namespace naming quite easily.

FSAP.CTL[param] = require(‘FSAP.CTL’ + param);

And this worked great as all the functions through out the application could still be accessed by there original namespace reference, without having to rename them or code a load of event handler solutions. I then hit various issues….

I had been a good coder with naming conventions and where I set values or got values I had called them set…. and get…. and a third one init….. YOU CANNOT DO THIS. commonJS will fall over if you have these three words in the name of functions. But studio came to my rescue with its global search and replace.

So I replaced set with load, get with retrieve and init with create in all function names. I made the mistake of doing this globally without checking each one individually.

What did get me was that in a couple of instances I couldn’t find certain variables when the application ran but this was due to me not loading a couple of critical files at run time, worked great on IOS but Android objected, so I switched the files to load in the app.js and this resolved all loading issues.

Now the app didn’t work properly and just kept hanging with no real errors. TIME TO DEBUG.. but how as it was virtually impossible to try to fix a debug point for studio to stop at. Well again studio came to my rescue, if you run an application through the debugger the app will stop at the offending line of code. A little trick, make sure you have the debugger view in studio displaying and just run your app. Works for both IOS and Android. So a couple of hours later I had a working IOS and Android version with the same code base, architecture and structure.

It is vital if you are going to do something similar to allow time, this took me 3days but I have an app with over 10000 lines of code. Also make sure your current architecture can handle the changes and finally ONLY DO IT IF YOU NEED TO. I had to or our Android version would have been unusable.

Summary.

In conclusion I have found that the Titanium installation of commonJS is pretty good and stable, there are differences between IOS and Android, well in my case because I refactored. I will certainly be using this going forward and implementing a much more structured solution, although I think I will still use it in conjunction with the namespace architecture. Beware this is new and as yet not fully tried out, so you will hit unexpected and undocumented issues which will need some careful debugging and maybe a creative solution or two. But it works and works well.

Do not unless you have to refactor your current apps over too commonJS it can be just to much work, but DO implement it going forward for new apps.

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
Comments Off on Namespace to CommonJS Titanium Refactoring  comments