Best Practices in apps development with Titanium Appcelerator


Published on

Published in: Technology
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Best Practices in apps development with Titanium Appcelerator

 in apps development using
@alessioricco !1
  2. 2. Software Quality characteristicsBy the user point of view

Adaptability: is the app able to run in differentenvironments ?
Accuracy: how well your app does the job ?
Correctness: your app does the job ?
Efficiency: minimizing system resources
Integrity: your app is secure ? 
Reliability: does it crash ?
Robustness: your app handle invalid inputs ?
Usability: its easy to learn how to use it ?USERS notice STABILITY and PERFORMANCE !2
  3. 3. Software Quality characteristicsBy the developer point of view

Flexibility: can you adapt the app for other uses ?
Maintanability: debug, improve, modify the app
Portability: adapting the app for other platforms
Readability: source code is easy to understand
Reusability: using parts of your code in other apps
Testability: the degree to which you can test the app
Understandability: can you understand what the app doesand how it does it ?DEVELOPERS needs RAPIDITY and READABILITY !3
  4. 4. A good software project must beUser side:
STABLE (applications must have a predictive behaviour)
PERFORMANT (speed must approach the speed of nativecode applications)

Developer side:
RAPID (development must be fast)
READABLE (code must be easy to understand) !4
The software works in a reliable way, and the output isdeterministic

The software runs consistently without a crash

If the platform is stable, writing stable software is easier.
(also our libraries are part of the platform)
  6. 6. PerformanceRESPONSIVENESS
The app must complete the assigned task within a given(short) time. User must receive feedback.

Apps must be approaching the native platform speed

Apps must avoid memory leaks and release the resourcesASAP !6
  7. 7. Rapid developmentREUSABILITY
Dont design twice the same piece of software.
Dont write twice the same routine. 

Known problems always have known solutions. 
Google them!

Writing good, correct, tested and smart code is faster thanwriting quick and dirty spaghetti code to debug later !7
  8. 8. ReadabilityMEANINGFUL COMMENTS
Comment your code. Comments are tools for saving time

Write code you can read and understand at different levelof granularity (from big picture to statement level)

Use meaningful names for your variables and functions. !8
  9. 9. Appcelerator Best Practices !9
  10. 10. Avoid the global scopeNO GARBAGE COLLECTION
In the global scope not null objects cannot be collected 

app.js is not accessible within CommonJS modules
app.js is not accessible within other contexts (windows)
- Always declare variables
- Always declare variables inside modules or functions
- Assign global objects to null after the use
  11. 11. Nulling out object references// create ui objectsvar window = Ti.UI.createWindow();var myView = myLibrary.createMyView(); win.add(myView);; // remove objects and release memorywin.remove(myView);myView = null;// the view could be removed by the GC !11
  12. 12. Keep local your temp vars// immediate functions help us to avoid 
// global scope pollutionvar sum = (function() { var tmpValue = 0; // local scope for (var i = 0; i < 100; i++) { tmpValue += i; } return tmpValue; })(); 
// i, tmpValue are ready for GC ! !12
  13. 13. use self-calling functions// self calling function(function() { var priv = Im local!;})();//undefined in the global scope alert(priv); !13
  14. 14. Dont Re-use your temp vars Javascript is loosely typed.
 You can repurpose objects any time via assignment
 dont do it!
 var i = 5;
 i = “let me change my type”; // BAD! !14
  15. 15. Use namespaces Enclose your applications API functions and properties into a single variable (namespace).
 - this prevent the global scope pollution
 - this protect your code from colliding with other code or libraries
 // declare it in the global scope
 var mynamespace = {}; 
 mynamespace.myvar = “hello”;
 mynamespace.myfunction = function(param) {}
  16. 16. Namespaces are extendable // extend and encapsulate by using self-calling functions (function() { function helper() { // this is a private function not directly accessible 
 // from the global scope } = function(msg) { // added to the apps namespace, so a public function helper(msg); }; })();
 // you could then call your function with World);
  17. 17. Understanding the closuresA closure is a function together with a referencingenvironment for the non local variables of that function// Return a function that approximates the derivative of f// using an interval of dx, which should be appropriately small.function derivative(f, dx) { return function (x) { return (f(x + dx) - f(x)) / dx; };}the variable f, dx lives after the function derivative returns.

Variables must continue to exist as long as any existingclosures have references to them !17
  18. 18. Avoid memory leaks in global event listenersfunction badLocal() { // local variables var table = Ti.UI.createTableView(); var view = Ti.UI.createView(); // global event listener Ti.App.addEventListener(myevent, function(e) { // table is local but not locally scoped table.setData(; }); view.add(table); return view;};
- consider to use callback functions instead of customglobal events
- place global event handlers in app.js
rule : global events handle global objects !18
  19. 19. Lazy script loadingLOAD SCRIPTS ONLY WHEN THEY ARE NEEDED

JavaScript evaluation is slow. Avoid loading scripts if they are not necessary// load immediatelyvar _window1 = require(lib/window1).getWindow;var win1 = new _window1();, function(){ // load when needed var _window2 = require(lib/window2).getWindow; var win2 = new _window2();})BE AWARE: Some bugs could not be discovered until you load the script... !19
  20. 20. D.R.Y. (dont repeat yourself)Dont repeat the same code
code repeated N times could be buggy in N different places
Reuse your code
if your code was correct until now, probably it will be correct in future
Instantiate your code using the factory pattern
hiding the class details to make future improvements easier 

Create libraries
functions called in N different places could be improved in just oneplace

  21. 21. Test your code and Reuse itCoding is about Testing and Trusting

“I test my code and I trust several other things:
- the platform correctness
- the compiler correctness
- the 3th party libraries
- the samples I copied from forums
… etc...”butif you write correct code you can trust YOUR code 
and re-use it !!!!

  22. 22. Test your code and Reuse itfunction foo (param){...statement #1...statement #2...statement #3myfunctioncall(); // 3 years old function tested several times}foo() is correct when statements are correct 
myfunctioncall() is correct

short code and high level of trust in tested libraries make coding anddebugging easier


  23. 23. Meaningful WrappingWrap your general-pourpose library functions and make themspecialized.exports.getLeaderBoard = function(callbackSuccess, callbackError){ var headers = null; exports.beintooREST(GET,,headers,callbackSuccess, callbackError); }exports.submitScore = function(playerGuid, score, contest, callbackSuccess,callbackError){ var headers = [ {key : guid, value : exports.getPlayer().guid}, {key : codeID, value : contest} ]; exports.beintooREST(GET, + score,headers,callbackSuccess, callbackError);} 
exports.beintooREST is a specialized REST query function 
if they change something i should change just one function 

  24. 24. Multiplatform programmingBRANCHINGuseful when your code is mostly the same across platformsbut vary in some points
// Query the platform just oncevar osname = Ti.Platform.osname;
var isAndroid = (osname == android) ? true : false;
var isIPhone = (osname == iphone) ? true : false;// branch the codeif (isAndroid) { // do Android code ...} else { // do code for other platforms (iOS not guaranteed) ...};// branch the valuesvar myValue = (isAndroid) ? 100 : 150; !24
  25. 25. Multiplatform programmingBRANCHINGSlower but elegant method 
// Query the platform just oncevar osname = (Ti.Platform.osname == ipod) ? iphone : Ti.Platform.osname;os = function(/*Object*/ map) { var def = map.def||null; //default function or value if (map[osname]) { if (typeof map[osname] == function) { return map[osname](); } else { return map[osname]; } } else { if (typeof def == function) { return def(); } else { return def; } }};// better than if statement and ternary operator. easily support more platformsvar myValue = os({ android: 100, ipad: 90, iphone: 50 }); !25
  26. 26. Multiplatform programmingPLATFORM-SPECIFIC JS STYLE SHEETS (JSS)JSS separate presentation and code.
module.jsvar myLabel = Ti.UI.createLabel({ text:this is the text, id:myLabel});module.jss#myLabel { width:149; text-align:right; color:#909;}for platform specific stylesheets you can use and module.iphone.jss,but module.jss have the precedence.
  27. 27. Using CommonJSTitanium Appcelerator adopted the CommonJS modulespecification as the way in which end users of the platformstructure their JS codesample usage:// load the module “Resources/myModule.js” and return a Javascript objectvar myModule = require(myModule);// good practice: always test if objects are nullif (myModule != null){ myModule.myMethod(“twinsmatcher”);}
  28. 28. Using CommonJS: exportsthe exports variable exposes public methods and variablesexports.myProperty = 123;exports.myMethod = function (message) { (message );};
  29. 29. Using CommonJS: module.exportsthe module.exports object could be used for functionswhich act as object constructorsEmployee.jsfunction Employee(name, surname, title){ = name;this.surname = surname;this.title = title;}Employee.prototype.fullName(){ + + + + this.surname);}
module.exports = Employee;usage:var Employee = require(Employee);var myEmployee = new Employee(john,doe);myEmployee.fullName(); !29
  30. 30. Using ImagesMinimize memory footprint

Image files are decompressed in memory to be convertedin bitmap when they are displayed. 
No matter the .png or .JPG original file size WIDTH HEIGHT COLORS FOOTPRINT (bit) (KB)
 320 480 24 450 640 960 24 1800 1024 768 24 2304 2048 1536 24 9216 !30
  31. 31. Image Optimization- use JPG for displaying photos
- use PNG for displaying icons, line-art, text- use remove() when the image is not visible on screen- set image views to null once no longer need those objs- resize and crops images to the dimensions you need- resize images to minimize file storage and network usage
- cache remote images ( !31
  32. 32. DatabaseRelease the resultsets as soon as you canexports.getScore = function (level) { var rows = null; var score= 0; try { rows = db.execute( "select max(score) as maxscore from score where level=?",level ); if( rows.isValidRow( )) { "SCORE: (score,level) " + rows.field( 0 ) + + level ); score= rows.field( 0 ) } else { "SCORE: error retrieving score [1]" ); } } catch (e) { "SCORE: error retrieving score [2]" ); } finally { rows.close( ); } return score;} !32
  33. 33. Database best practicesClose the database connection after insert and update

var db =;try{ db.execute(BEGIN); // begin the transaction for(var i=0, var j=playlist.length; i < j; i++) { var item = playlist[i]; db.execute(INSERT INTO albums (disc, artist, rating) VALUES (?, ?, ?), item.disc, item.artist, item.comment); } db.execute(COMMIT);}catch (e){ "SCORE: error retrieving score [2]" ); }finally { db.close(); } !33
  34. 34. Database best practicesMinimize your database size- Big Databases increases your app package file size
- The database is duplicated on your device because iscopied to the ApplicationDataDirectory- On some Android releases the installer cannotuncompress assets over 1MB (if you have a 2MB databaseyou need some workarounds)Keep your db small and populate it on the 1st run !
  35. 35. Style and conventionsLearn and follow language rules, styles and paradigms
 javascript isnt c# or java or php
 titanium appcelerator is not just javascript
 Follow coding style best practices
 Naming Conventions
 Comments Style
 Follow language related communities and forums
 dont reinvent the wheel
 learn community best practices

  36. 36. Language RulesAlways declare the variablesWhen you fail to specify var, the variable gets placed in theglobal context, potentially clobbering existing values. Also,if theres no declaration, its hard to tell in what scope avariable lives. So always declare with var.
  37. 37. Language RulesAlways use semicolons to terminate statementsyou can cause hard to debug problems in your code.... var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // ;// conditional execution a la bash-1 == resultOfOperation() || die();
  38. 38. Language Best Practices: === operatorUse the Exactly Equal operator (===)comparing two operands of the same type is, most of thetime, what we need 
  39. 39. Language Best Practices : === operatorUse === instead of == , use !== instead of !=var testme = 1;if(testme == 1) // 1 is converted to 1{ // this will be executed }

var testme = 1;if(testme === 1) { // this will not be executed} 
  40. 40. Language Best Practices : optimizing loopsMake your loops more efficientvar names = [Jeff,Nolan,Marshall,Don];for(var i=0;i<names.length;i++){ process(names[i]);}

// I can check the array length only oncevar names = [Jeff,Nolan,Marshall,Don];for(var i=0,j=names.length;i<j;i++){ process(names[i]);} 
  41. 41. Language Best Practices : parenthesisIs better wrap self functions with parenthesis var myValue = function() { //do stuff return someValue;}();

// the same code, but its clear that myValue is not a functionvar myValue = (function() { //do stuff return someValue;})(); 
  42. 42. Language Best Practices : a better ifHow to avoid assignment bugs in your if statements var test = 1;// classic boolean expression style (left side is a variable)if (test == 1){ test++; = + test); // test = 2 }// classic boolean expression bug (is not a test, is an assignment)if (test=1){ = + test); // test = 1}// safe boolean expression style (left side is a constant)if (1 == test){ = + test); // test = 1}// compiler or interpreter will raise an exception: good !if (1 = test) // error: Left side of assignment is not a reference{ = + test); // test = 1} 
  43. 43. Coding StyleVariable names start with a category noun (lowercase)Examples:personName
  44. 44. Coding StyleFunction names start with a category verb (lowercase) and(if possible) are followed by an associated variable nameExamples:getPersonName
  45. 45. Coding StyleMajor Objects and constructors follow a capitalized wordspatternExamples:Person

Same rule is applied for namespaces

  46. 46. Coding Style: IndentationK&R Style Exampleif (x < 10) { if (y > 10) { // do this }} else { // do this} 
  47. 47. Coding Style: IndentationAllman Style Exampleif (x < 10){ if (y > 10) { // do this }}else{ // do this} 
  48. 48. Coding Style: Comments// Single line comments are required
// for code documentation
var personAge = calculatePersonAge(person); //-10; avoid this! 
/* // this line of code is disabled using block comment
 var personAge = calculatePersonAge(person)-10;*/
 * @param {String} customerName Customers full Name **/
function getCustomer(customerName) {}comments could be a great code/debug/documentation tool 
  49. 49. ReferencesTitanium Appcelerator online documentation Complete 2nd Edition – Steven C. McConnell - Microsoft Press Optimization FAQ Crockford Javascript Style Guide