Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Titanium appcelerator best practices

17,196 views

Published on

an introduction to the programming best practices for javascript and Titanium mobile
(cross platform programming seminar at university of pisa, july 2012)

Published in: Technology

Titanium appcelerator best practices

  1. 1. BEST PRACTICES in apps development usingTITANIUM APPCELERATOR Alessio Ricco @alessioricco 1
  2. 2. Software Quality characteristic (user point of view)• Adaptability: is the app able to run in different environments ?• Accuracy: how well does your app do the job ?• Correctness: is your app able to do the job ?• Efficiency: minimizing system resources• Integrity: is your app secure ?• Reliability: does it crash ?• Robustness: does your app handle invalid inputs ?• Usability: is it easy to learn how to use it ? USERS notice STABILITY and PERFORMANCE 2
  3. 3. Software Quality characteristic (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 does and how it does it ? DEVELOPERS needs RAPIDITY and READABILITY 3
  4. 4. Software Quality characteristicUser side:STABLE (applications must have a predictive behaviour)PERFORMANT (speed must approach the speed of cpu)Developer side:RAPID (development must be fast)READABLE (code must be easy to understand) 4
  5. 5. Best Practices 5
  6. 6. Avoid the global scope• NO GARBAGE COLLECTION In the global scope not null objects cannot be collected• SCOPE IS NOT ACCESSIBLE FROM MODULES 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 6
  7. 7. Nulling out object references// create ui objectsvar window = Ti.UI.createWindow();var myView = myLibrary.createMyView();win.add(myView);win.open();// remove objects and release memorywin.remove(myView);myView = null;// the view could be removed by the GC 7
  8. 8. Keep local your temp var// 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 ! 8
  9. 9. Use self calling functions// self calling function(function(){ var priv = Im local!;})();//undefined in the global scopealert(priv); 9
  10. 10. Use namespacesEnclose your applications API functions and properties into asingle variable (namespace). This prevent the global scopepollution- this protect your code from colliding with othercode or libraries// declare it in the global scopevar mynamespace = {};mynamespace.myvar = “hello”;mynamespace.myfunc = function(param) {} 10
  11. 11. 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 } myapp.info = function(msg) { // added to the apps namespace, so a public function helper(msg); Ti.API.info(msg) };})();// you could then call your function withmyapp.info(Hello World); DONT EXTEND TITANIUM NAMESPACES !!!!! 11
  12. 12. Understanding the closuresA closure is a function together with a referencing environment for thenon local variables of that function// Return a function that approximates thederivative of f// using an interval of dx, which should beappropriately 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 mustcontinue to exist as long as any existing closures have references to them 12
  13. 13. 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(e.data); }); view.add(table); return view;};Consider to use callback functions instead of custom global eventsPlace global event handlers in app.jsRule : global events handle global objects 13
  14. 14. Lazy script loading Load scripts only when they are needed JavaScript evaluation is slow, so avoid loading scripts if they are not necessary// load immediatelyvar _window1 = require(lib/window1).getWindow;var win1 = new _window1();win1.open()win1.addEventListener(click, function(){! // load when needed! var _window2 = require(lib/window2).getWindow;! var win2 = new _window2();! win2.open()})BE AWARE: Some bugs could not be discovered until you load the script... 14
  15. 15. Cross PlatformBRANCHINGuseful when your code is mostly the same across platforms but 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; 15
  16. 16. Cross Platform: branch// 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) { returnmap[osname](); } else { return map[osname]; } } else { if (typeof def == function) { return def(); } else { return def; } }};// better than if statement and ternary operator.var myValue = os({ android: 100, ipad: 90, iphone: 50 }); 16
  17. 17. Cross Platform: JSSPLATFORM-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 module.android.jss andmodule.iphone.jss, but module.jss have the precedence. 17
  18. 18. ImagesMinimize memory footprintImage files are decompressed in memory to be converted inbitmap when they are displayed.No matter the .png or .JPG original file size Width Height Colors Footprint 320 480 24bit 450KB 640 960 24bit 1800KB 1024 768 24bit 2304KB 2304KB 2048 1536 24bit 9216 18
  19. 19. 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 (https://gist.github.com/1901680) 19
  20. 20. Database Release the resultset 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( )) {! ! Ti.API.info( "SCORE: (score,level) " + rows.field( 0 ) + + level );! ! score= rows.field( 0 )! ! } else {! ! Ti.API.info( "SCORE: error retrieving score [1]" );! ! }! }! catch (e) {! ! Ti.API.info( "SCORE: error retrieving score [2]" );! }! finally {! ! rows.close( );! }! return score;} 20
  21. 21. Database Close the database connection after insert and updatevar db = Ti.Database.open(myDatabase);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){! Ti.API.info( "SCORE: error retrieving score [2]" );}finally {! db.close();} 21
  22. 22. Database Minimize your database size• Big Databases increases your app package file size• The database is duplicated on your device because is copied to the ApplicationDataDirectory• On some Android releases the installer cannot uncompress assets over 1MB (if you have a 2MB database you need some workarounds) Keep your db small and populate it on the 1st run ! read sql-lite FAQ: http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html 22
  23. 23. Style and conventionLearn and follow language rules, styles and paradigms javascriptisnt c# or java or php titanium appcelerator is not just javascript Follow coding style best practices Naming Conventions Indentation Comments Style Follow language related communities and forums dont reinvent the wheel learn community best practices 23
  24. 24. Language RulesLearn and follow language rules, styles and paradigms javascriptisnt c# or java or php titanium appcelerator is not just javascript Follow coding style best practices Naming Conventions Indentation Comments Style Follow language related communities and forums dont reinvent the wheel learn community best practices 24
  25. 25. Language RulesAlways declare the variablesWhen you fail to specify var, the variable gets placed in theglobal context, potentially clobbering existing values. Also, iftheres no declaration, its hard to tell in what scope a variablelives.So always declare with var. 25
  26. 26. Language Best PracticesUse the Exactly Equal operator (===)comparing two operands of the same type is, most of thetime, what we need 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 } 26
  27. 27. Language Best Practices Is better wrap self functions with parenthesisvar myValue = function() { //do stuff return someValue;}();// the same code, but its clear thatmyValue is not a functionvar myValue = (function() { //do stuff return someValue;})(); 27
  28. 28. ReferencesTitanium Appcelerator online documentationhttp://docs.appcelerator.com/Code Complete 2nd Edition – Steven C. McConnell - Microsoft Presshttp://www.cc2e.com/Default.aspxSQLite Optimization FAQhttp://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.htmlDouglas Crockfordhttp://javascript.crockford.com/Google Javascript Style Guidehttp://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xmlTwinsMatcherhttp://itunes.apple.com/app/twinsmatcher/id429890747?mt=8@alessioriccohttp://www.linkedin.com/in/alessioricco 28

×