Many people that come to Titanium and Alloy come to it from a background in web development. Having that as a background is great but often times it is lacking in some basic disciplines that are important for success. Success not only in the initial development but also the long term maintenance and upkeep of the app you are building.
When working with frameworks like Titanium or Node.js, it?s easy to have a fire and forget mentality. These frameworks make it so simple to get to ?hello world? that sometimes we forget how important best practices are.
In this session I will take you through some of the beginning best practices that have helped me maintain thousands of apps and tens of thousands of lines of code. I have made a lot of mistakes and will try to help you avoid as many of those pitfalls as possible.
This session will be specifically geared for the person that is relatively new to Titanium and/or Alloy and will address things like application structure for Classic and Alloy based applications. The plan is to answer questions like, why is my app leaking, how to I manage memory, how and when do I use a window vs. a view? What does it mean to open a window with a different context? How do I use commonJS modules effectively? What is a global event listener and why do people tell me not to use them? How do I get help, and why won?t anyone answer my questions in the support forums?
If you want to love working with Titanium for a long time to come, check out some of the best practices that will help you get there.
4. Beginning Best Practices&
Best Practices > General Javascript Topics
We all know Javascript has
it’s quirks, but it is a
powerful, expressive
language that allows us to
do amazing things.
5. A couple of great
books to read.
Beginning Best Practices&
Best Practices > General Javascript Topics
8. My preferred style guide
Beginning Best Practices&
Best Practices > General Javascript Topics
https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
9. Ti. vs. Titanium. namespace
Beginning Best Practices&
Best Practices > General Titanium Topics
Remember: When typing out the namespace, if you
snicker you have gone too far, remove the “t”…
var win = Ti.UI.createWindow({});
// vs.
var win = Titanium.UI.createWindow({});
10. Opening a Window
Beginning Best Practices&
Best Practices > General Titanium Topics
Avoid using the “url” property when creating a window.
// No, no, no…
var win = Ti.UI.createWindow({
url: “windows/window.js”
});
// Yes
var win = Titanium.UI.createWindow({});
11. A Classic Folder Structure
Beginning Best Practices&
Best Practices > General Titanium Topics
Your folder structure needs to make as much sense as your
code. Remember that you are doing this for future you or
someone else.
-‐ Resources
-‐ android
-‐ app.js
-‐ application
-‐ application.js
-‐ ui
-‐ helpers
-‐ lib
-‐ iphone
!
!
Create an
“application”
folder for all
of your
Titanium
code.
12. Windows vs. Views
Beginning Best Practices&
Best Practices > General Titanium Topics
It’s up to you! Kind of.
15. Some things to know about
CommonJS
Beginning Best Practices&
Best Practices > CommonJS
16. What does a CommonJS module
look like?
Beginning Best Practices&
Best Practices > CommonJS
// Private
var count = 0;
// Public
exports.incrementCount = function() {
count = count + 1;
return count;
};
17. What does a CommonJS module look like?
Beginning Best Practices&
Best Practices > CommonJS
// require
var libA = require("lib/liba");
// exports
exports.createInstance = function() {
};
18. exports. vs. module.exports
Beginning Best Practices&
Best Practices > CommonJS
// module.exports
var instanceFactory = {};
instanceFactory.createInstance = function() {
};
module.exports = instanceFactory;
exports.createInstance = function() {
};
19. Simple CommonJS App Example
Beginning Best Practices&
Best Practices > CommonJS
var APP = require("application/application");
APP.init();
var APP = {};
!
APP.init = function() {
var win = Ti.UI.createWindow({
backgroundColor: "#fff"
});
!
var label = Ti.UI.createLabel({
color: "#333",
text: "Hello TiConf",
font: {
fontSize:20,
fontFamily: "Helvetica Neue"
},
textAlign: "center",
width: "auto"
});
win.add(label);
!
win.open();
};
!
module.exports = APP;
app.js
application/application.js
21. CommonJS can be used to share
data in the application.
Beginning Best Practices&
Best Practices > CommonJS
22. Using Native Modules
Beginning Best Practices&
Best Practices > CommonJS
var social = require("dk.napp.social");
app.js
<modules>
<module platform="iphone">dk.napp.social</module>
</modules>
tiapp.xml
$ gittio install dk.napp.social
[sudo] npm install -‐g gittio
Check out http://gitt.io
23. Formatting style preference
Beginning Best Practices&
Best Practices > CommonJS
var social = require("dk.napp.social");
!
var uiHelper = require("application/helpers/ui");
!
var APP = {};
application/application.js
Note: This is a style preference… Not law.
Installed Modules
(Referenced in tiapp.xml)
Local CommonJS Modules
Declared Variables
25. Memory Management
Beginning Best Practices&
Best Practices > Memory Management
Titanium Native
Kroll Bridge
Windows, Buttons, Views, etc.
26. Memory Management
Beginning Best Practices&
Best Practices > Memory Management
exports.windowFactory = function(_params, _listeners) {
var win = Ti.UI.createWindow(_.extend(_params, {}));
!
var onWindowClose = function() {
Ti.API.info("Window Closed");
if (_listeners.onClose) {
_listeners.onClose();
}
win = null;
onWindowClose = null;
};
!
win.addEventListener("close", onWindowClose);
return win;
};
Remember: If in doubt,
null it out…
var win = uiHelper.windowFactory({
backgroundColor: "#fff"
}, {
onClose: function() {
win = null;
label = null;
}
});
application/application.js application/helpers/ui.js
27. Beginning Best Practices&
Best Practices > Memory Management
for (var i = 0; i < 5; i++) {
var star = Ti.UI.createImageView({
height:'44dp',
width:'44dp',
top: "50dp",
left:'10dp',
backgroundColor: "#333"
});
(function() {
var index = i;
star.addEventListener('click', function() {
setRating(index+1);
});
})();
myView.add(star);
}
Possible memory leaks
http://www.tidev.io/2014/03/27/memory-management/
28. Beginning Best Practices&
Best Practices > Memory Management var starWrapper = Ti.UI.createView({
layout: "horizontal",
top: "10dp",
width: "145dp",
height: "24dp"
});
!
win.add(starWrapper);
!
for (var i = 0; i < 6; i++) {
starWrapper.add(Ti.UI.createImageView({
id: "star" + i,
height: "24dp",
width: "24dp",
left: "5dp",
image: "/images/star.png",
opacity: 0.5
}));
}
!
var onStarTap = function(e) {
_.each(starWrapper.getChildren(), function(child) {
child.setOpacity(0.5);
});
e.source.setOpacity(1);
setRating(e.source.id);
Ti.API.info(currentRating);
};
!
starWrapper.addEventListener("click", onStarTap);
A better way…
No reference to createImage has
been stored.
We are not adding an eventListener
to each imageView
29. Beginning Best Practices&
Best Practices > Memory Management
// Global system Events
Ti.Network.addEventListener("change", APP.networkObserver);
Ti.Gesture.addEventListener("orientationchange", APP.orientationObserver);
Ti.App.addEventListener("pause", APP.exitObserver);
Ti.App.addEventListener("close", APP.exitObserver);
Ti.App.addEventListener("resumed", APP.resumeObserver);
!
if(OS_ANDROID) {
APP.MainWindow.addEventListener("androidback", APP.backButtonObserver);
}
Global Event Listeners
30. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
$ titanium build -‐-‐platform ios -‐-‐target simulator -‐-‐sim-‐type iphone -‐-‐tall -‐-‐retina
Build your project for the simulator
1
Go to your project folder > build >
iPhone > Click on the Xcode project
file.
2
31. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Open Xcode:
Select: Product > Destination > iPhone Retina (4-inch)
Then select an OS version, like 7.1
3
32. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Then select: Product > Profile4
33. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Wait…5
34. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Select: Allocations6
35. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Add “TiUI” here7
As you use your app in the
simulator you will see TiUI items
start showing up in your
Allocation summary.
8
36. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Add “TiUI” here
37. Checking your memory management
Beginning Best Practices&
Best Practices > Memory Management
Add “TiUI” here
38. Memory Management
Beginning Best Practices&
Best Practices > Memory Management
http://www.tidev.io/2014/03/27/memory-management/
43. Beginning Best Practices&
Best Practices > Alloy
Alloy specific best
practices.
Use Alloy.Global sparingly…
Use it, it’s incredibly powerful, but use it carefully.
44. Beginning Best Practices&
Best Practices > Alloy
Alloy specific best
practices.
Don’t forget to call $.destroy(); when you
are done with a controller.
$.win.addEventListener("close", function(){
$.destroy();
}
45. Being a good community
member
Beginning Best Practices&
Best Practices > Community
http://bit.ly/appc-qa - Using
Questions and Answers
Read This
Then this
Finally, read this before you
post something…