First a PSA: Older versions of Apple’s Application Loader have been reported to cause problems on app submission related to icon sizes. Updating to the latest app loader resolves the issue. Related Q&A post here.
The following is the first in a series of Friday blog posts covering advanced topics and Titanium development best practices.
If you’ve followed the developer blog and read through our documentation out on the wiki, you’ve probably come across the phrase “proxy object” on a few occasions. Basically, a proxy is a special JavaScript object which is a stand-in for a corresponding object in native code (on iOS or Android – this magic layer is not needed on mobile web).
//"button" is a proxy object var button = Ti.UI.createButton({ title:'push me!', height:50, width:200 });
For a more detailed explanation of what a proxy is and how it works, check out our module development guide, which goes through the process of creating your own native modules for iOS and Android.
Any time you are interacting with a function or property in the Ti.* JavaScript namespace, or dealing with an object you got back from a function in this namespace, that object is a proxy of some type. In order to facilitate communication “over the bridge” from the JavaScript context to native code, these proxy objects have been instrumented with special behavior which allows native code (Java, C, or Objective-C) to intercept assignments and function calls to these objects. This model of interaction is what allows developers to essentially write native code in JavaScript, and makes Titanium distinct from many other other cross-platform tools.
Proxies Are Special
As a user of the platform, though, it is helpful to understand a few things about these objects. At least in the 1.x and probably for most of the 2.x timeframe, proxy objects won’t always play by the rules of JavaScript. Let’s take a look at some areas where the rules of JavaScript get bent or broken.
Nested Objects
In a normal JavaScript object, you can set nested properties on objects (so long as those properties/objects exist), as in “meaning.of.life = 42;”. With proxies, this cannot be done. One notable place where you’ll run into this is with the “font” property of Labels. In the example below, the “l” object is a proxy, which should have a nested property font, and then fontSize associated with it. Trying to set the nested property fontSize directly does not work, but setting the entire font object to a new value does:
var w = Ti.UI.createWindow({ backgroundColor:'white' }); var l = Ti.UI.createLabel({ text:'here is a label', font: { fontFamily:'Trebuchet MS' } }); w.add(l); //doesn't work l.font.fontSize = 24; //this does work l.font = { fontFamily:'Trebuchet MS', fontSize: 24 }; w.open();
Overriding Properties
Another behavior of proxy objects is that the functions defined as the public interface of a proxy object (functions and properties Titanium expects to use) cannot be overridden as they could be with typical JavaScript objects. The following is legal JavaScript code:
var window = Ti.UI.createWindow({ backgroundColor:'red' }); window.open = function() { alert('overriding open!'); }; window.open();
But when run, you’ll notice that since “open” is a function that is part of the proxy’s public interface, the “built in” open functionality remains, even though we think we’ve overridden it:

Getters and Setters
Certain function names also have magic associated with them. Any function prefixed with “get” or “set” will be delegated to native code, so any custom getters or setters you’d like to set up on a proxy will be ignored:
var window = Ti.UI.createWindow({ backgroundColor:'red' }); window.getSomething = function() { alert('getter function'); }; window.setSomething = function(something) { alert('trying to set '+something); }; window.open(); //will be ignored window.getSomething(); window.setSomething('foo');
.apply and .call
For instance, normally you can call any Function in JavaScript using .apply or .call, since functions are first class objects. With Titanium proxy objects, because of their special plumbing, you’re not able to do this out of the box. The following is code that should be rational:
var window = Ti.UI.createWindow.call(this,{ backgroundColor:'red' }); window.open();
But produces a red screen of death on iOS:

Wrapping Proxies
Occasionally this behavior becomes annoying, because we expect to be able to use all the JavaScript tricks up our sleeves on the objects which are part of or produced by the Ti.* namespace. When dealing with a proxy directly presents a problem, a common approach is to wrap a proxy object in a regular JavaScript object with no link to an object in “native land”. It can be as simple as the following example, which could be placed at the root of a Titanium project directory:
Resources/WrappedWindow.js
//Proxy wrapper function WrappedWindow(args) { this.proxy = Ti.UI.createWindow(args); } WrappedWindow.prototype.open = function(args) { this.proxy.open(args); }; WrappedWindow.prototype.setBackgroundColor = function(color) { //this works because WrappedWindow is just a plain ol' JS object! this.proxy.animate({ backgroundColor:color, duration:4000 }); }; module.exports = WrappedWindow;
Resources/app.js
var WrappedWindow = require('WrappedWindow'); var w = new WrappedWindow({ backgroundColor:'white' }); w.open(); w.setBackgroundColor('red');
Using this technique, you can avoid the special behavior of proxies when working with them directly is a pain in your neck.
Summary
A proxy object is the bridge that empowers you to write a native app in JavaScript. However, they do have some special rules applied to them. The big ones to watch out for are:
- Can’t set properties of nested objects
- Unable to override properties in the proxy’s public API
- Functions prefixed with “get” and “set” are intercepted
- .call and .apply don’t work on proxy objects
When this behavior presents a problem, it becomes useful to wrap a proxy object in a plain JavaScript object, which will “play by the rules” of JavaScript. Next week, we’ll be looking at a more complex way to use this object wrapper technique to build custom components with CommonJS modules. See you next time!



