iOS Internals and Best Practices
Blain Hamon & Max StepanovSenior Software Engineers
Appcelerator, Inc.@blainhamon @maxstepanov
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
• 2009: Versions 0.3-0.8
• Based on web views
• Native via JSON service
• Drew upon Ti:Desktop
Ti.API.prehistory
• 2010+: Versions 0.9+
• Built-in Interpreters
• Native via JS callbacks
• Focused on Mobile
Ti.API.today
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
• Native OS
App To The Future
Native OS
• Native OS
• OS Abstraction Layer
App To The Future
Native OS
OS Abstraction Layer
• Native OS
• OS Abstraction Layer
• Ti Binding (Kroll)
App To The Future
Native OS
OS Abstraction Layer Ti Binding (Kroll)
• Native OS
• OS Abstraction Layer
• Ti Binding (Kroll)
• Ti Foundation Layer
App To The Future
Native OS
OS Abstraction Layer Ti Binding (Kroll)
Ti Foundation Layer
• Native OS
• OS Abstraction Layer
• Ti Binding (Kroll)
• Ti Foundation Layer
• Modules
App To The Future
Native OS
OS Abstraction Layer Ti Binding (Kroll)
Ti Foundation Layer
UI App Network Other Modules…
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
UI-triggered event:
• UI asynchronously triggers event listener
• UI is ready for more action while JS processes.
Game of Threads
User taps button
EventListener
UI JS
User taps button
EventListener
JS-triggered events:
• Still asychronous
• First in, first out queue
Game of Threads UI JS
fireEvent(‘foo’);setTimeout(0,ƒ());
Timeout Function
EventListener
Expensive listeners:
• Still first in, first out
• Delayed responses
Game of Threads UI JS
User taps button
EventListener
User taps button
EventListener
User taps button
EventListener
Options:
• Block user interaction, but only as a last resort
Game of Threads UI JS
User taps button
EventListener
User taps button
EventListener
User taps button
EventListener
Button covered
Options:
• Block user interaction, but only as a last resort
• Break up expensive listeners
Game of Threads UI JS
User taps button 1
User taps button 2
EventListener 2
EventListener 1
EventListener 1.1
EventListener 1.2
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
• In global namespace
My Little Memory
held1 = {foo:5};
• In global namespace
• In a closure of a function
held1 = {foo:5};
foo = (function(){var held2=0;return function()
{return held2++;};})();
My Little Memory
• In global namespace
• In a closure of a function
• Property of a retained object
held1 = {foo:5};
foo = (function(){var held2=0;return function()
{return held2++;};})();
foo.bar = held3;foo.add(held4);
My Little Memory
• In global namespace
• In a closure of a function
• Property of a retained object
• Artificially retained via Titanium
held1 = {foo:5};
foo = (function(){var held2=0;return function()
{return held2++;};})();
foo.bar = held3;foo.add(held4);
held5.open();
My Little Memory
• Be aware of variable scope
• “nulling out”
held1 = {foo:5};
foo = (function(){var held2=0;return function()
{return held2++;};})();
foo.bar = held3;foo.add(held4);
held5.open();
My Little Memory
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
JS(JSCORE)• Proxies represent
Titanium objects
• Proxies are threadsafe
• Proxies store data as a native copy
Class of the Titans
UI(NATIVE)
JS(NATIVE)
Ti Proxy
UIView Object Ti Binding Object JS Object
JS(JSCORE)• Proxies represent
Titanium objects
• Proxies are threadsafe
• Proxies store data as a native copy
• Method objects are generated
Class of the Titans
UI(NATIVE)
JS(NATIVE)
Ti Proxy
UIView Object Ti Binding Object JS Object
(Method) JS Object
JS(JSCORE)• Native can be
expensive
• Cache when possible
• Use properties instead of setters
• Pass properties in creators
• Use applyProperties()
Class of the Titans
UI(NATIVE)
JS(NATIVE)
Ti Proxy
UIView Object Ti Binding Object JS Object
(Method) JS Object
• History
• Structure
• Responsive Apps
• Memory-Light Apps
• Fast-Performing Apps
• Fast-Drawing Apps
iOS Internals
• iOS uses OpenGL underneath
• Views cache as textures
• Opaque textures are faster
• Resizing can be expensive
• Transparency can be expensive
Epic View Time
iOS uses OpenGL underneath• Views cache as textures• Opaque textures are faster• Rendering happens often
Some behaviors are expensive• Resizing view sizes• Transparent/views with alpha• Dynamic graphics
Epic View Time
Epic View Time
var row = Ti.UI.createTableViewRow({height:Ti.UI.SIZE,layout:'horizontal’
});row.add(Ti.UI.createImageView({
image: myUrl,top: 10,height:89,bottom:11,left: 0,width:125
}));row.add(Ti.UI.createLabel({
text: myText,left:5,width:Ti.UI.SIZE,height:Ti.UI.SIZE
}));
Epic View Time
var row = Ti.UI.createTableViewRow({height:Ti.UI.SIZE,layout:'horizontal’
});row.add(Ti.UI.createImageView({
image: myUrl,top: 10,height:89,bottom:11,left: 0,width:125
}));row.add(Ti.UI.createLabel({
text: myText,left:5,width:Ti.UI.SIZE,height:Ti.UI.SIZE
}));
Epic View Time
var row = Ti.UI.createTableViewRow({height:100
});row.add(Ti.UI.createImageView({
image: myUrl,top: 10,height:89,bottom:11,left: 0,width:125,backgroundColor:'white'
}));row.add(Ti.UI.createLabel({
text: myText,top:0,left:130,right:0,bottom:0,backgroundColor:'white'
});
Being responsive:• Block UI as last resort• Break up expensive tasks
Being memory-efficient:• Mind native object references
Being fast:• Cache when possible• Reduce using native containers• Concentrate property setting
Being fast-rendering:• Aim for static, opaque views
iOS Internals
iOS Debugging
iOS Simulator Physical Devices
New in Titanium
Titanium 3.0Titanium 1.7
• Install with iTunes
• Requires network connectivity between development machine and a device
• Local WiFi or Hotspot
• iPhone Personal Hotspot via WiFi, Bluetooth or USB
• Titanium Studio will do the best to locate your device(s)!
Device Debugging
• Turn off Auto-Lock on device
• Ensure same WiFi network
• Don’t forget to launch your app
Debugging Tips
http://docs.appcelerator.com/titanium/3.0/ Debugging on iOS Devices
• UI thread for handling user interactions
• JS thread for the application logic
• Debugger thread for communications with Titanium Studio
• Other iOS platform threads
Game of Threads UI JS
User taps button 1
postlayout eventGeo location
Function
EventListener 1 var x = 1;Ti.API.log(x);openWin(x);
EventListener 2 Line 1
Line 2Line 3
DBG
Run
• Use conditional breakpoints
• A block of JavaScript code
• Hit count
• Use Console logging with Ti.API functions
Best Practices
Blain Hamon & Max Stepanov@blainhamon @maxstepanov