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.
Citation preview
Titanium Beginning Best Practices
A little about me. Josh Jensen mashstack.com
Beginning Best Practices& Goal: To help you keep your
WTF/min to a minimum.
Beginning Best Practices& Best Practices > General
Javascript Topics We all know Javascript has its quirks, but it is
a powerful, expressive language that allows us to do amazing
things.
A couple of great books to read. Beginning Best Practices&
Best Practices > General Javascript Topics
Beginning Best Practices& Best Practices > General
Javascript Topics Reminder: ! Many of these are personal
preferences.
JSHint Beginning Best Practices& Best Practices >
General Javascript Topics http://www.jshint.com/
My preferred style guide Beginning Best Practices& Best
Practices > General Javascript Topics
https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
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({});
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({});
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.
Windows vs. Views Beginning Best Practices& Best Practices
> General Titanium Topics Its up to you! Kind of.
CommonJS Beginning Best Practices& Bringing sanity to your
project. Best Practices > CommonJS
What is CommonJS? Beginning Best Practices& A simple API
for declaring modules. Best Practices > CommonJS
Some things to know about CommonJS Beginning Best
Practices& Best Practices > CommonJS
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; };
What does a CommonJS module look like? Beginning Best
Practices& Best Practices > CommonJS // require var libA =
require("lib/liba"); // exports exports.createInstance = function()
{ };
exports. vs. module.exports Beginning Best Practices& Best
Practices > CommonJS // module.exports var instanceFactory = {};
instanceFactory.createInstance = function() { }; module.exports =
instanceFactory; exports.createInstance = function() { };
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
CommonJS can be used to share data in the application.
Beginning Best Practices& Best Practices > CommonJS
Using Native Modules Beginning Best Practices& Best
Practices > CommonJS var social = require("dk.napp.social");
app.js dk.napp.social tiapp.xml $ gittio install dk.napp.social
[sudo] npm install -g gittio Check out http://gitt.io
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
Memory management Beginning Best Practices& Best Practices
> Memory Management
Memory Management Beginning Best Practices& Best Practices
> Memory Management Titanium Native Kroll Bridge Windows,
Buttons, Views, etc.
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
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/
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
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
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 le. 2
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
Checking your memory management Beginning Best Practices&
Best Practices > Memory Management Then select: Product >
Prole4
Checking your memory management Beginning Best Practices&
Best Practices > Memory Management Wait5
Checking your memory management Beginning Best Practices&
Best Practices > Memory Management Select: Allocations6
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
Checking your memory management Beginning Best Practices&
Best Practices > Memory Management Add TiUI here
Checking your memory management Beginning Best Practices&
Best Practices > Memory Management Add TiUI here
Memory Management Beginning Best Practices& Best Practices
> Memory Management
http://www.tidev.io/2014/03/27/memory-management/
Beginning Best Practices& Best Practices > Alloy Alloy
Highly recommended!
Beginning Best Practices& Best Practices > Alloy Alloy
is a framework that follows an MVC architecture Whats that?
model-view-controller (MVC)
Beginning Best Practices& Best Practices > Alloy Alloy
specic best practices.I have 3
Beginning Best Practices& Best Practices > Alloy Alloy
specic best practices. Use it!
Beginning Best Practices& Best Practices > Alloy Alloy
specic best practices. Use Alloy.Global sparingly Use it, its
incredibly powerful, but use it carefully.
Beginning Best Practices& Best Practices > Alloy Alloy
specic best practices. Dont forget to call $.destroy(); when you
are done with a controller. $.win.addEventListener("close",
function(){ $.destroy(); }
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
Questions? Beginning Best Practices& Best Practices >
General Titanium Topics http://bit.ly/ticonfjosh @joshj
Slides/Example app: Twitter: