SlideShare a Scribd company logo
Extending Titanium Mobile through Native Modules Olivier Morandi
# whoami Olivier Morandi Freelance mobile developer & software engineer [email_address] @olivier_morandi https://github.com/omorandi
Titanium Mobile A set of tools for developing cross-platform mobile applications in JavaScript iOS (iPhone/iPod/iPad)  Android  Blackberry (through a commercial subscription) http://www.appcelerator.com https://github.com/appcelerator/titanium_mobile
Anatomy of a project Project directory build/ android/ iphone/ Resources/ app.js manifest tiapp.xml Project files Resource files: JS code, images, sounds, Sqlite DBs, etc. Build folders, per platform
manifest #appname: whymca #publisher: olivier #url: http://www.whymca.org #image: appicon.png #appid: com.whymca.test #desc: undefined #type: mobile #guid: 746e9cb4-49f6-4afe-af0b-5de9f0116f65
tiapp.xml <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?> <ti:app xmlns:ti=&quot;http://ti.appcelerator.org&quot;> <deployment-targets> <target device=&quot;iphone&quot;>true</target> <target device=&quot;ipad&quot;>false</target> <target device=&quot;android&quot;>true</target> </deployment-targets> <id>com.whymca.test</id> <name>whymca</name> <version>1.0</version> <publisher>olivier</publisher> <url>http://www.whymca.org</url> <description>not specified</description> <copyright>2011 by olivier</copyright> <icon>appicon.png</icon> <persistent-wifi>false</persistent-wifi> <prerendered-icon>false</prerendered-icon> <statusbar-style>default</statusbar-style> <statusbar-hidden>false</statusbar-hidden> <fullscreen>false</fullscreen> <navbar-hidden>false</navbar-hidden> <analytics>false</analytics> <guid>746e9cb4-49f6-4afe-af0b-5de9f0116f65</guid> <iphone> <orientations device=&quot;iphone&quot;> <orientation>Ti.UI.PORTRAIT</orientation> </orientations> <orientations device=&quot;ipad&quot;> <orientation>Ti.UI.PORTRAIT</orientation> <orientation>Ti.UI.UPSIDE_PORTRAIT</orientation> <orientation>Ti.UI.LANDSCAPE_LEFT</orientation> <orientation>Ti.UI.LANDSCAPE_RIGHT</orientation> </orientations> </iphone> <android xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;> </android> <modules> </modules> </ti:app>
app.js (1) var win = Titanium.UI.createWindow({  title: 'Hello' , backgroundColor: '#fff' }); var label1 = Titanium.UI.createLabel({ color: '#333' , text: ’Hello World!' , textAlign:  'center' , font: {fontSize: 30, fontWeight:  'bold' } }); win. add (label1);
app.js (2) var bt = Titanium.UI.createButton({ title:  'Click me' ,  width: 100, height: 40, bottom: 40 }) bt.addEventListener( 'click' ,  function (e) { label1.text =  'WHYMCA ROCKS!' ; }); win. add (bt); win. open ();
UI widgets created in JS are mapped on the native components of the target platform
App distribution The product ready for distribution is actually a native app JS Code Partially compiled and optimized Packed in binary format into the bundle Resources Copied into the bundle
Development toolchain Ti Developer (toolchain GUI) Ti Studio (IDE) Ti SDK toolchain (Python scripts) Mac OSX Mac OSX Windows Linux Xcode/iOS SDK Android SDK
Application Stack JavaScript Application Code Titanium JavaScript API Android  Modules iOS  Modules Android SDK iOS SDK Titanium Framework JS Interpreter Runtime JS Interpreter Runtime
Ti JavaScript API http://developer.appcelerator.com/apidoc/mobile
Extending the API: why? Accessing specific OS features Leveraging existing native libraries Optimizing critical portions of the app Extending/ameliorating portions of the Titanium Mobile framework
Extending the API: how? Creating a fork of Titanium Mobile’s source code on github Unflexible approach You put your hands in the heart of the framework Maintaining a separate branch can be tedious and costly There are situations where this is the cheaper approach E.g. when needing to extend the functionality of core modules of the framework (networking, maps, ecc.)
Extending the API: how? Creating one or more native modules throught the Titanium Module SDK Great flexibility Easy to distribute as Open Source Binary packages Appcelerator Ti+Plus Marketplace (?)
Moduli nativi – some examples Android barcode scanner (Zxing wrapper) https://github.com/mwaylabs/titanium-barcode iOS ZipFile (create/decompress zip files) https://github.com/TermiT/ZipFile iOS TiStoreKit (in app purchase) https://github.com/masuidrive/TiStoreKit iOS TiSMSDialog (in app sms sending) https://github.com/omorandi/TiSMSDialog Appcelerator Titanium modules (sample modules) https://github.com/appcelerator/titanium_modules
Titanium JS Interface var bt = Titanium.UI.createButton({ title:  'Click me' ,  width: 100, height: 40, bottom: 40 }); bt.addEventListener( 'click' ,  function (e) { label1.text =  'WHYMCA ROCKS!' ; });
Titanium JS Interface Module Titanium.UI Object Titanium.UI.Button Object Factory Titanium.UI.createButton() Property getters/setters - methods Button.title Button.width Button.animate() Ecc. Event handling Button.addEventListener()
Module Architecture Titanium.UI Titanium.UI.Button Titanium.UI.Button.width Module Proxy Internal State setters/getters Methods Events Module Class Namespace Object Object property/method Proxy Class  Implementation Titanium  abstraction JavaScript Factory Internal State setters/getters Methods Events
The path to module development Define the functionality you need to be exposed and how they’ll be invoked from JavaScript code    define the API of the module Create a project with the tools of the Module SDK Implement the API Build-Test-Debug
Case Study – iOS SMS module The Titanium API provides email sending functionality through the Ti.UI.EmailDialog component, but nothing for sending SMS messages On iOS this feature is available since version 4.0 of the OS through the  MFMessageComposeViewController  class
MFMessageComposeViewController
Case Study – iOS SMS module Implement a native module capable of exposing the features of the  MFMessageComposeViewController  class through a JavaScript API: Check the availability of the component (not present in iOS versions < 4.0) Programmatically set recipients and message body Set UI properties (e.g. navbar color) Notify the caller about the result of the send operation
Resources Module SDK Docs Android http://wiki.appcelerator.org/display/guides/Module+Developer+Guide+for+Android iOS http://wiki.appcelerator.org/display/guides/Module+Developer+Guide+for+iOS Titanium Mobile source code https://github.com/appcelerator/titanium_mobile Code of other modules released as open source
1. Defining the API Object SMSDialog Properties recipients messageBody barColor Methods isSupported() open()
Example code var  smsDialog = module.createSMSDialog(); if  (smsDialog.isSupported())  { smsDialog.recipients = [ ’+14151234567' ]; smsDialog.messageBody =  'Test message from me' ; smsDialog.barColor =  ’red' ; smsDialog.addEventListener( 'complete' ,  function (e){ Ti.API.info( 'Result: '  + e.resultMessage); }); smsDialog.open({animated: true}); }
Result
2. Creating the project # titanium create  --platform= iphone  --type= module  --dir= ~/ --name= SMSDialog  --id= com.whymca.smsdialog
titanium (alias) Mac OS X alias titanium=&quot;/Library/Application Support/Titanium/mobilesdk/osx/1.7.0/titanium.py&quot; Linux alias titanium=&quot;$HOME/Library/Application Support/Titanium/mobilesdk/osx/1.7.0/titanium.py&quot; Windows XP PATH=C:\Documents and Settings\All Users\Application Data\Titanium\mobilesdk\win32\1.7.0 Windows Vista/7 PATH=C:\ProgramData\Titanium\mobilesdk\win32\1.7.0
Xcode project generated assets/  Classes/ ComWhymcaSmsdialogModule.h ComWhymcaSmsdialogModule.m ComWhymcaSmsdialogModuleAssets.h ComWhymcaSmsdialogModuleAssets.m example/ app.js   build.py   ComWhymcaSmsdialog_Prefix.pch  manifest  module.xcconfig  smsdialog.xcodeproj  titanium.xcconfig Asset files to be distributed with the module Implementation files Sample program for testing module invocations Script for building and packaging the module Metadata for managing the module in Titanium Include/linking directives used at integration-time Include/linking directives used at build-time To be filled with our code
3. Implementation The generated project already contains the class that implements the module: ComWhymcaSmsdialogModule The class name is a CamelCase transposition of the module id chosen when creating the project In JS it will be instantiated as var module = require(‘com.whymca.smsdialog’);
Implementing the proxy The SMSDialog object we defined, must be implemented as a proxy The name of the class must follow a convention similar to that used for the module name, in the form: < moduleID >< proxyName >Proxy i.e. ComWhymcaSmsdialog SMSDialog Proxy
SMSDialogProxy class Must be a subclass of the  TiProxy  class It should expose properties and methods that we want to make available to JavaScript code
Object creation and initialization var  smsDialog = module.createSMSDialog(); smsDialog.recipients = [ ’+391234567' ]; smsDialog.messageBody =  'Test message' ; //or var  smsDialog = module.createSMSDialog({ recipients: [ ’+391234567’ ], messageBody:  'Test message’ });
Creation Object creation is completely managed by the framework The JS construct module.create< ProxyName >() is mapped on code that instantiate an object of the correct class thanks to the naming convention used
Initialization The object can be initialized either passing a dictionary of property values to the factory method, either setting single property values in a second moment through dot notation In either case, if the proxy doesn’t explicitly provide getter/setter methods for those properties, they are automatically inserted in the  dynprops  dictionary of the proxy object
Initialization It’s always possible to retrieve property values present in the  dynprops  dictionary with the message  [self valueForUndefinedKey: @&quot;messageBody&quot; ]
Conversion utilities The framework provides the TiUtils class, which contains methods for simplifying the conversion of values coming form JS code: NSString * messageBody = [TiUtils stringValue:[self  valueForUndefinedKey: @&quot;messageBody&quot; ]]; UIColor * barColor = [[TiUtils colorValue:[self  valueForUndefinedKey: @&quot;barColor&quot; ]] _color]; BOOL animated = [TiUtils boolValue: @&quot;animated&quot;  properties:args def:YES];
Methods They are exposed to JavaScript by simply declaring them in the  @interface  section of the proxy class They must be declared in one of the following forms: -(id)methodName:(id)args -(void)methodName:(id)args
Example @interface ComWhymcaSmsdialogSMSDialogProxy: TiProxy <MFMessageComposeViewControllerDelegate>  - (id)isSupported:(id)args; - (void)open:(id)args; @end
Method arguments The list of arguments passed in JavaScript to a method is passed as a  NSArray  object in the  args  parameter The framework provides some C macros for the cases where a single argument is expected: ENSURE_SINGLE_ITEM(args,type) ENSURE_SINGLE_ARG_OR_NIL(args, type)
Passing JavaScript dictionary Objects JS: smsDialog.open({animated: true}); OBJ-C: - (void)open:(id)args { ENSURE_SINGLE_ARG_OR_NIL(args, NSDictionary); //args ora è un NSDictionary BOOL animated = [TiUtils boolValue: @&quot;animated&quot;  properties:args def:YES]; //[…]
Return values The types  NSString  NSDictionary  NSArray  NSNumber  NSDate  NSNull don’t need to be converted Numeric types must be wrapped in a  NSNumber  object It’s possible to return proxy objects (though they must be autoreleased if allocated by our method) return [[[TiColor alloc] initWithColor:color  name: @&quot;#fff&quot; ] autorelease];
Executing a method in the UI thread There are cases where a method should be executed in the UI thread (e.g. when interacting with user interface objects) In such cases we can use the macro ENSURE_UI_THREAD(method,args) for forcing the execution of the method on the UI thread
Events The simplest way a proxy has to interact with JS code is through events In JS we register an event-listener function on a specific event managed by the proxy Example JS: smsDialog.addEventListener( 'complete' ,  function (e){ Ti.API.info( 'Result: '  + e.resultMessage); });
Events OBJ-C: -(void)_listenerAdded:(NSString*)type count:(int)count  { //type = @&quot;complete&quot;   } -(void)_listenerRemoved:(NSString*)type count:(int)count { //type = @&quot;complete&quot;  }
Events OBJ-C: NSDictionary *event = [NSDictionary  dictionaryWithObjectsAndKeys:resultMessage,  @&quot;resultMessage&quot; ,  nil]; [self fireEvent: @&quot;complete&quot;  withObject:event];
4. Build We can build the project directly from Xcode Useful for checking out warning & syntax error messages
⌘ B
4. Build Using the script # build.py   from the module project root directory It performs a complete build and it packages the module library + assets + metadata in a zip file
Package Name in the form com.whymca.smsdialog-iphone-0.1.zip For being used it must be decompressed in the directory /Library/Application\ Support/Titanium/
Simple testing By executing the script # titanium run in the project directory This will create a temporary project based on the  app.js  file from the  example  directory Not the best way for testing the module
Using the module in a Ti Mobile Project <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?> <ti:app xmlns:ti=&quot;http://ti.appcelerator.org&quot;> <!–- SNIP… --> <modules> <module version=“0.1” platform=“iphone”> com.whymca.smsdialog </module> </modules> </ti:app> tiapp.xml
Testing/Debugging Create a new Ti Mobile project with test code and a reference to the module Launch the app at least one time from Ti Studio/Developer Open the Xcode project from the  build/iphone  directory found in the app project directory Issue  Build&Debug  from there Set breakpoints in the module code, test, etc.
 
Thank you! Any questions? You can find all the code used for this presentation on  https://github.com/omorandi/whymca-conf-2011

More Related Content

What's hot (20)

PPTX
Intel XDK - Philly JS
Ian Maffett
 
KEY
Live Content: Finding new ways to publish
ckimrie
 
PPSX
CR Bridge Solutions Pvt Ltd. Java slides
CRBTech
 
PPT
Java for Recruiters
ph7 -
 
PDF
Bn1005 demo ppt core java
conline training
 
PPT
Jetspeed-2 Overview
bettlebrox
 
PPTX
15 android libraries for app development
Concetto Labs
 
PDF
Introduction to android
krishnastudent88
 
PDF
Marakana Android Internals
Marko Gargenta
 
PDF
iOS Development - Offline Class for Jasakomer
Andri Yadi
 
PDF
Moved to https://slidr.io/azzazzel/leveraging-osgi-to-create-extensible-plugi...
Milen Dyankov
 
PDF
LinuxCon Europe 2012 - Tizen Mini Summit
Cheng Luo
 
PDF
Qt - for stack overflow developer conference
Nokia
 
PDF
Android on Windows 11 - A Developer's Perspective (Windows Subsystem For Andr...
Embarcadero Technologies
 
PDF
Droid con berlin_the_bb10_android_runtime
Droidcon Berlin
 
PDF
Os Rego
oscon2007
 
PPT
Android For Java Developers
Mike Wolfson
 
PPTX
Cross-Platform Development using Angulr JS in Visual Studio
Mizanur Sarker
 
PPTX
Cross platform-mobile-applications
mailalamin
 
PDF
Spring Roo Flex Add-on
Bill Ott
 
Intel XDK - Philly JS
Ian Maffett
 
Live Content: Finding new ways to publish
ckimrie
 
CR Bridge Solutions Pvt Ltd. Java slides
CRBTech
 
Java for Recruiters
ph7 -
 
Bn1005 demo ppt core java
conline training
 
Jetspeed-2 Overview
bettlebrox
 
15 android libraries for app development
Concetto Labs
 
Introduction to android
krishnastudent88
 
Marakana Android Internals
Marko Gargenta
 
iOS Development - Offline Class for Jasakomer
Andri Yadi
 
Moved to https://slidr.io/azzazzel/leveraging-osgi-to-create-extensible-plugi...
Milen Dyankov
 
LinuxCon Europe 2012 - Tizen Mini Summit
Cheng Luo
 
Qt - for stack overflow developer conference
Nokia
 
Android on Windows 11 - A Developer's Perspective (Windows Subsystem For Andr...
Embarcadero Technologies
 
Droid con berlin_the_bb10_android_runtime
Droidcon Berlin
 
Os Rego
oscon2007
 
Android For Java Developers
Mike Wolfson
 
Cross-Platform Development using Angulr JS in Visual Studio
Mizanur Sarker
 
Cross platform-mobile-applications
mailalamin
 
Spring Roo Flex Add-on
Bill Ott
 

Viewers also liked (7)

PDF
from old Java to modern Java
心 谷本
 
PDF
Going to War Over UX
Evgenia (Jenny) Grinblo
 
PDF
Native FTW: Integrating native views in Titanium apps
omorandi
 
KEY
Using Titanium Mobile
johndbritton
 
PPTX
Let Spark Fly: Advantages and Use Cases for Spark on Hadoop
MapR Technologies
 
PDF
Titanium Alloy Tutorial
Fokke Zandbergen
 
PDF
Livre blanc 612 rencontres sur les reseaux sociaux - partie 1 - 74 rencontres
Alban Jarry
 
from old Java to modern Java
心 谷本
 
Going to War Over UX
Evgenia (Jenny) Grinblo
 
Native FTW: Integrating native views in Titanium apps
omorandi
 
Using Titanium Mobile
johndbritton
 
Let Spark Fly: Advantages and Use Cases for Spark on Hadoop
MapR Technologies
 
Titanium Alloy Tutorial
Fokke Zandbergen
 
Livre blanc 612 rencontres sur les reseaux sociaux - partie 1 - 74 rencontres
Alban Jarry
 
Ad

Similar to Extending Appcelerator Titanium Mobile through Native Modules (20)

PPTX
Appcelerator Titanium Intro
Nicholas Jansma
 
PPT
Titanium Meetup Deck
sschwarzhoff
 
KEY
Titanium Mobile Intro
Marshall Culpepper
 
PPT
Titanium Overview (Mobile March 2011)
Kevin Whinnery
 
PPT
OSCON Titanium Tutorial
Kevin Whinnery
 
PPT
Native Mobile Application Using Open Source
Axway Appcelerator
 
PPTX
Modeveast Appcelerator Presentation
Aaron Saunders
 
PPTX
Appcelerator Titanium - An Introduction to the Titanium Ecosystem
Boydlee Pollentine
 
PDF
The Big Easy: Native Mobile App Development with Appcelerator Titanium and Ja...
Adam Paxton
 
KEY
Appcelerator Titanium at Mobile 2.0
Jeff Haynie
 
ZIP
Mobile for the rest of us
Axway Appcelerator
 
KEY
Mobile 2.0 Event: Mobile for the rest of us using Appcelerator Titanium
Jeff Haynie
 
PPTX
Intro to appcelerator
Mohab El-Shishtawy
 
PDF
Appcelerator Titanium Intro (2014)
Nicholas Jansma
 
KEY
Mountain View July JavaScript Meetup at Google
Jeff Haynie
 
PDF
Intro to Appcelerator Titanium - Code for Fort Lauderdale 2015
Adam Paxton
 
ZIP
iPhone/iPad Development with Titanium
Axway Appcelerator
 
KEY
Appcelerator iPhone/iPad Dev Con 2010 San Diego, CA
Jeff Haynie
 
ZIP
Titanium @ Minnebar
Kevin Whinnery
 
PPTX
Presentation
Rajdeep Kaur
 
Appcelerator Titanium Intro
Nicholas Jansma
 
Titanium Meetup Deck
sschwarzhoff
 
Titanium Mobile Intro
Marshall Culpepper
 
Titanium Overview (Mobile March 2011)
Kevin Whinnery
 
OSCON Titanium Tutorial
Kevin Whinnery
 
Native Mobile Application Using Open Source
Axway Appcelerator
 
Modeveast Appcelerator Presentation
Aaron Saunders
 
Appcelerator Titanium - An Introduction to the Titanium Ecosystem
Boydlee Pollentine
 
The Big Easy: Native Mobile App Development with Appcelerator Titanium and Ja...
Adam Paxton
 
Appcelerator Titanium at Mobile 2.0
Jeff Haynie
 
Mobile for the rest of us
Axway Appcelerator
 
Mobile 2.0 Event: Mobile for the rest of us using Appcelerator Titanium
Jeff Haynie
 
Intro to appcelerator
Mohab El-Shishtawy
 
Appcelerator Titanium Intro (2014)
Nicholas Jansma
 
Mountain View July JavaScript Meetup at Google
Jeff Haynie
 
Intro to Appcelerator Titanium - Code for Fort Lauderdale 2015
Adam Paxton
 
iPhone/iPad Development with Titanium
Axway Appcelerator
 
Appcelerator iPhone/iPad Dev Con 2010 San Diego, CA
Jeff Haynie
 
Titanium @ Minnebar
Kevin Whinnery
 
Presentation
Rajdeep Kaur
 
Ad

Recently uploaded (20)

PDF
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 

Extending Appcelerator Titanium Mobile through Native Modules

  • 1. Extending Titanium Mobile through Native Modules Olivier Morandi
  • 2. # whoami Olivier Morandi Freelance mobile developer & software engineer [email_address] @olivier_morandi https://github.com/omorandi
  • 3. Titanium Mobile A set of tools for developing cross-platform mobile applications in JavaScript iOS (iPhone/iPod/iPad) Android Blackberry (through a commercial subscription) http://www.appcelerator.com https://github.com/appcelerator/titanium_mobile
  • 4. Anatomy of a project Project directory build/ android/ iphone/ Resources/ app.js manifest tiapp.xml Project files Resource files: JS code, images, sounds, Sqlite DBs, etc. Build folders, per platform
  • 5. manifest #appname: whymca #publisher: olivier #url: http://www.whymca.org #image: appicon.png #appid: com.whymca.test #desc: undefined #type: mobile #guid: 746e9cb4-49f6-4afe-af0b-5de9f0116f65
  • 6. tiapp.xml <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?> <ti:app xmlns:ti=&quot;http://ti.appcelerator.org&quot;> <deployment-targets> <target device=&quot;iphone&quot;>true</target> <target device=&quot;ipad&quot;>false</target> <target device=&quot;android&quot;>true</target> </deployment-targets> <id>com.whymca.test</id> <name>whymca</name> <version>1.0</version> <publisher>olivier</publisher> <url>http://www.whymca.org</url> <description>not specified</description> <copyright>2011 by olivier</copyright> <icon>appicon.png</icon> <persistent-wifi>false</persistent-wifi> <prerendered-icon>false</prerendered-icon> <statusbar-style>default</statusbar-style> <statusbar-hidden>false</statusbar-hidden> <fullscreen>false</fullscreen> <navbar-hidden>false</navbar-hidden> <analytics>false</analytics> <guid>746e9cb4-49f6-4afe-af0b-5de9f0116f65</guid> <iphone> <orientations device=&quot;iphone&quot;> <orientation>Ti.UI.PORTRAIT</orientation> </orientations> <orientations device=&quot;ipad&quot;> <orientation>Ti.UI.PORTRAIT</orientation> <orientation>Ti.UI.UPSIDE_PORTRAIT</orientation> <orientation>Ti.UI.LANDSCAPE_LEFT</orientation> <orientation>Ti.UI.LANDSCAPE_RIGHT</orientation> </orientations> </iphone> <android xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;> </android> <modules> </modules> </ti:app>
  • 7. app.js (1) var win = Titanium.UI.createWindow({ title: 'Hello' , backgroundColor: '#fff' }); var label1 = Titanium.UI.createLabel({ color: '#333' , text: ’Hello World!' , textAlign: 'center' , font: {fontSize: 30, fontWeight: 'bold' } }); win. add (label1);
  • 8. app.js (2) var bt = Titanium.UI.createButton({ title: 'Click me' , width: 100, height: 40, bottom: 40 }) bt.addEventListener( 'click' , function (e) { label1.text = 'WHYMCA ROCKS!' ; }); win. add (bt); win. open ();
  • 9. UI widgets created in JS are mapped on the native components of the target platform
  • 10. App distribution The product ready for distribution is actually a native app JS Code Partially compiled and optimized Packed in binary format into the bundle Resources Copied into the bundle
  • 11. Development toolchain Ti Developer (toolchain GUI) Ti Studio (IDE) Ti SDK toolchain (Python scripts) Mac OSX Mac OSX Windows Linux Xcode/iOS SDK Android SDK
  • 12. Application Stack JavaScript Application Code Titanium JavaScript API Android Modules iOS Modules Android SDK iOS SDK Titanium Framework JS Interpreter Runtime JS Interpreter Runtime
  • 13. Ti JavaScript API http://developer.appcelerator.com/apidoc/mobile
  • 14. Extending the API: why? Accessing specific OS features Leveraging existing native libraries Optimizing critical portions of the app Extending/ameliorating portions of the Titanium Mobile framework
  • 15. Extending the API: how? Creating a fork of Titanium Mobile’s source code on github Unflexible approach You put your hands in the heart of the framework Maintaining a separate branch can be tedious and costly There are situations where this is the cheaper approach E.g. when needing to extend the functionality of core modules of the framework (networking, maps, ecc.)
  • 16. Extending the API: how? Creating one or more native modules throught the Titanium Module SDK Great flexibility Easy to distribute as Open Source Binary packages Appcelerator Ti+Plus Marketplace (?)
  • 17. Moduli nativi – some examples Android barcode scanner (Zxing wrapper) https://github.com/mwaylabs/titanium-barcode iOS ZipFile (create/decompress zip files) https://github.com/TermiT/ZipFile iOS TiStoreKit (in app purchase) https://github.com/masuidrive/TiStoreKit iOS TiSMSDialog (in app sms sending) https://github.com/omorandi/TiSMSDialog Appcelerator Titanium modules (sample modules) https://github.com/appcelerator/titanium_modules
  • 18. Titanium JS Interface var bt = Titanium.UI.createButton({ title: 'Click me' , width: 100, height: 40, bottom: 40 }); bt.addEventListener( 'click' , function (e) { label1.text = 'WHYMCA ROCKS!' ; });
  • 19. Titanium JS Interface Module Titanium.UI Object Titanium.UI.Button Object Factory Titanium.UI.createButton() Property getters/setters - methods Button.title Button.width Button.animate() Ecc. Event handling Button.addEventListener()
  • 20. Module Architecture Titanium.UI Titanium.UI.Button Titanium.UI.Button.width Module Proxy Internal State setters/getters Methods Events Module Class Namespace Object Object property/method Proxy Class Implementation Titanium abstraction JavaScript Factory Internal State setters/getters Methods Events
  • 21. The path to module development Define the functionality you need to be exposed and how they’ll be invoked from JavaScript code  define the API of the module Create a project with the tools of the Module SDK Implement the API Build-Test-Debug
  • 22. Case Study – iOS SMS module The Titanium API provides email sending functionality through the Ti.UI.EmailDialog component, but nothing for sending SMS messages On iOS this feature is available since version 4.0 of the OS through the MFMessageComposeViewController class
  • 24. Case Study – iOS SMS module Implement a native module capable of exposing the features of the MFMessageComposeViewController class through a JavaScript API: Check the availability of the component (not present in iOS versions < 4.0) Programmatically set recipients and message body Set UI properties (e.g. navbar color) Notify the caller about the result of the send operation
  • 25. Resources Module SDK Docs Android http://wiki.appcelerator.org/display/guides/Module+Developer+Guide+for+Android iOS http://wiki.appcelerator.org/display/guides/Module+Developer+Guide+for+iOS Titanium Mobile source code https://github.com/appcelerator/titanium_mobile Code of other modules released as open source
  • 26. 1. Defining the API Object SMSDialog Properties recipients messageBody barColor Methods isSupported() open()
  • 27. Example code var smsDialog = module.createSMSDialog(); if (smsDialog.isSupported()) { smsDialog.recipients = [ ’+14151234567' ]; smsDialog.messageBody = 'Test message from me' ; smsDialog.barColor = ’red' ; smsDialog.addEventListener( 'complete' , function (e){ Ti.API.info( 'Result: ' + e.resultMessage); }); smsDialog.open({animated: true}); }
  • 29. 2. Creating the project # titanium create --platform= iphone --type= module --dir= ~/ --name= SMSDialog --id= com.whymca.smsdialog
  • 30. titanium (alias) Mac OS X alias titanium=&quot;/Library/Application Support/Titanium/mobilesdk/osx/1.7.0/titanium.py&quot; Linux alias titanium=&quot;$HOME/Library/Application Support/Titanium/mobilesdk/osx/1.7.0/titanium.py&quot; Windows XP PATH=C:\Documents and Settings\All Users\Application Data\Titanium\mobilesdk\win32\1.7.0 Windows Vista/7 PATH=C:\ProgramData\Titanium\mobilesdk\win32\1.7.0
  • 31. Xcode project generated assets/ Classes/ ComWhymcaSmsdialogModule.h ComWhymcaSmsdialogModule.m ComWhymcaSmsdialogModuleAssets.h ComWhymcaSmsdialogModuleAssets.m example/ app.js build.py ComWhymcaSmsdialog_Prefix.pch manifest module.xcconfig smsdialog.xcodeproj titanium.xcconfig Asset files to be distributed with the module Implementation files Sample program for testing module invocations Script for building and packaging the module Metadata for managing the module in Titanium Include/linking directives used at integration-time Include/linking directives used at build-time To be filled with our code
  • 32. 3. Implementation The generated project already contains the class that implements the module: ComWhymcaSmsdialogModule The class name is a CamelCase transposition of the module id chosen when creating the project In JS it will be instantiated as var module = require(‘com.whymca.smsdialog’);
  • 33. Implementing the proxy The SMSDialog object we defined, must be implemented as a proxy The name of the class must follow a convention similar to that used for the module name, in the form: < moduleID >< proxyName >Proxy i.e. ComWhymcaSmsdialog SMSDialog Proxy
  • 34. SMSDialogProxy class Must be a subclass of the TiProxy class It should expose properties and methods that we want to make available to JavaScript code
  • 35. Object creation and initialization var smsDialog = module.createSMSDialog(); smsDialog.recipients = [ ’+391234567' ]; smsDialog.messageBody = 'Test message' ; //or var smsDialog = module.createSMSDialog({ recipients: [ ’+391234567’ ], messageBody: 'Test message’ });
  • 36. Creation Object creation is completely managed by the framework The JS construct module.create< ProxyName >() is mapped on code that instantiate an object of the correct class thanks to the naming convention used
  • 37. Initialization The object can be initialized either passing a dictionary of property values to the factory method, either setting single property values in a second moment through dot notation In either case, if the proxy doesn’t explicitly provide getter/setter methods for those properties, they are automatically inserted in the dynprops dictionary of the proxy object
  • 38. Initialization It’s always possible to retrieve property values present in the dynprops dictionary with the message [self valueForUndefinedKey: @&quot;messageBody&quot; ]
  • 39. Conversion utilities The framework provides the TiUtils class, which contains methods for simplifying the conversion of values coming form JS code: NSString * messageBody = [TiUtils stringValue:[self valueForUndefinedKey: @&quot;messageBody&quot; ]]; UIColor * barColor = [[TiUtils colorValue:[self valueForUndefinedKey: @&quot;barColor&quot; ]] _color]; BOOL animated = [TiUtils boolValue: @&quot;animated&quot; properties:args def:YES];
  • 40. Methods They are exposed to JavaScript by simply declaring them in the @interface section of the proxy class They must be declared in one of the following forms: -(id)methodName:(id)args -(void)methodName:(id)args
  • 41. Example @interface ComWhymcaSmsdialogSMSDialogProxy: TiProxy <MFMessageComposeViewControllerDelegate> - (id)isSupported:(id)args; - (void)open:(id)args; @end
  • 42. Method arguments The list of arguments passed in JavaScript to a method is passed as a NSArray object in the args parameter The framework provides some C macros for the cases where a single argument is expected: ENSURE_SINGLE_ITEM(args,type) ENSURE_SINGLE_ARG_OR_NIL(args, type)
  • 43. Passing JavaScript dictionary Objects JS: smsDialog.open({animated: true}); OBJ-C: - (void)open:(id)args { ENSURE_SINGLE_ARG_OR_NIL(args, NSDictionary); //args ora è un NSDictionary BOOL animated = [TiUtils boolValue: @&quot;animated&quot; properties:args def:YES]; //[…]
  • 44. Return values The types NSString NSDictionary NSArray NSNumber NSDate NSNull don’t need to be converted Numeric types must be wrapped in a NSNumber object It’s possible to return proxy objects (though they must be autoreleased if allocated by our method) return [[[TiColor alloc] initWithColor:color name: @&quot;#fff&quot; ] autorelease];
  • 45. Executing a method in the UI thread There are cases where a method should be executed in the UI thread (e.g. when interacting with user interface objects) In such cases we can use the macro ENSURE_UI_THREAD(method,args) for forcing the execution of the method on the UI thread
  • 46. Events The simplest way a proxy has to interact with JS code is through events In JS we register an event-listener function on a specific event managed by the proxy Example JS: smsDialog.addEventListener( 'complete' , function (e){ Ti.API.info( 'Result: ' + e.resultMessage); });
  • 47. Events OBJ-C: -(void)_listenerAdded:(NSString*)type count:(int)count { //type = @&quot;complete&quot; } -(void)_listenerRemoved:(NSString*)type count:(int)count { //type = @&quot;complete&quot; }
  • 48. Events OBJ-C: NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:resultMessage, @&quot;resultMessage&quot; , nil]; [self fireEvent: @&quot;complete&quot; withObject:event];
  • 49. 4. Build We can build the project directly from Xcode Useful for checking out warning & syntax error messages
  • 50. ⌘ B
  • 51. 4. Build Using the script # build.py from the module project root directory It performs a complete build and it packages the module library + assets + metadata in a zip file
  • 52. Package Name in the form com.whymca.smsdialog-iphone-0.1.zip For being used it must be decompressed in the directory /Library/Application\ Support/Titanium/
  • 53. Simple testing By executing the script # titanium run in the project directory This will create a temporary project based on the app.js file from the example directory Not the best way for testing the module
  • 54. Using the module in a Ti Mobile Project <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?> <ti:app xmlns:ti=&quot;http://ti.appcelerator.org&quot;> <!–- SNIP… --> <modules> <module version=“0.1” platform=“iphone”> com.whymca.smsdialog </module> </modules> </ti:app> tiapp.xml
  • 55. Testing/Debugging Create a new Ti Mobile project with test code and a reference to the module Launch the app at least one time from Ti Studio/Developer Open the Xcode project from the build/iphone directory found in the app project directory Issue Build&Debug from there Set breakpoints in the module code, test, etc.
  • 56.  
  • 57. Thank you! Any questions? You can find all the code used for this presentation on https://github.com/omorandi/whymca-conf-2011