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

PDF
Titanium Mobile: flexibility vs. performance
PPTX
Introduction to Module Development with Appcelerator Titanium
PDF
Extending Titanium with native iOS and Android modules
PDF
Eclipse vs Netbean vs Railo
PDF
Developing and-benchmarking-native-linux-applications-on-android
PPTX
Advance Android Application Development
PDF
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
PDF
International Journal of Engineering Research and Development
Titanium Mobile: flexibility vs. performance
Introduction to Module Development with Appcelerator Titanium
Extending Titanium with native iOS and Android modules
Eclipse vs Netbean vs Railo
Developing and-benchmarking-native-linux-applications-on-android
Advance Android Application Development
Wakanda: NoSQL for Model-Driven Web applications - NoSQL matters 2012
International Journal of Engineering Research and Development

What's hot (20)

PPTX
Intel XDK - Philly JS
KEY
Live Content: Finding new ways to publish
PPSX
CR Bridge Solutions Pvt Ltd. Java slides
PPT
Java for Recruiters
PDF
Bn1005 demo ppt core java
PPT
Jetspeed-2 Overview
PPTX
15 android libraries for app development
PDF
Introduction to android
PDF
Marakana Android Internals
PDF
iOS Development - Offline Class for Jasakomer
PDF
Moved to https://slidr.io/azzazzel/leveraging-osgi-to-create-extensible-plugi...
PDF
LinuxCon Europe 2012 - Tizen Mini Summit
PDF
Qt - for stack overflow developer conference
PDF
Android on Windows 11 - A Developer's Perspective (Windows Subsystem For Andr...
PDF
Droid con berlin_the_bb10_android_runtime
PDF
Os Rego
PPT
Android For Java Developers
PPTX
Cross-Platform Development using Angulr JS in Visual Studio
PPTX
Cross platform-mobile-applications
PDF
Spring Roo Flex Add-on
Intel XDK - Philly JS
Live Content: Finding new ways to publish
CR Bridge Solutions Pvt Ltd. Java slides
Java for Recruiters
Bn1005 demo ppt core java
Jetspeed-2 Overview
15 android libraries for app development
Introduction to android
Marakana Android Internals
iOS Development - Offline Class for Jasakomer
Moved to https://slidr.io/azzazzel/leveraging-osgi-to-create-extensible-plugi...
LinuxCon Europe 2012 - Tizen Mini Summit
Qt - for stack overflow developer conference
Android on Windows 11 - A Developer's Perspective (Windows Subsystem For Andr...
Droid con berlin_the_bb10_android_runtime
Os Rego
Android For Java Developers
Cross-Platform Development using Angulr JS in Visual Studio
Cross platform-mobile-applications
Spring Roo Flex Add-on
Ad

Viewers also liked (7)

PDF
from old Java to modern Java
PDF
Going to War Over UX
PDF
Native FTW: Integrating native views in Titanium apps
KEY
Using Titanium Mobile
PPTX
Let Spark Fly: Advantages and Use Cases for Spark on Hadoop
PDF
Titanium Alloy Tutorial
PDF
Livre blanc 612 rencontres sur les reseaux sociaux - partie 1 - 74 rencontres
from old Java to modern Java
Going to War Over UX
Native FTW: Integrating native views in Titanium apps
Using Titanium Mobile
Let Spark Fly: Advantages and Use Cases for Spark on Hadoop
Titanium Alloy Tutorial
Livre blanc 612 rencontres sur les reseaux sociaux - partie 1 - 74 rencontres
Ad

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

PPTX
Appcelerator Titanium Intro
PPT
Titanium Meetup Deck
KEY
Titanium Mobile Intro
PPT
Titanium Overview (Mobile March 2011)
PPT
OSCON Titanium Tutorial
PPT
Native Mobile Application Using Open Source
PPTX
Modeveast Appcelerator Presentation
PPTX
Appcelerator Titanium - An Introduction to the Titanium Ecosystem
PDF
The Big Easy: Native Mobile App Development with Appcelerator Titanium and Ja...
KEY
Appcelerator Titanium at Mobile 2.0
ZIP
Mobile for the rest of us
KEY
Mobile 2.0 Event: Mobile for the rest of us using Appcelerator Titanium
PPTX
Intro to appcelerator
PDF
Appcelerator Titanium Intro (2014)
KEY
Mountain View July JavaScript Meetup at Google
PDF
Intro to Appcelerator Titanium - Code for Fort Lauderdale 2015
KEY
Appcelerator iPhone/iPad Dev Con 2010 San Diego, CA
ZIP
iPhone/iPad Development with Titanium
ZIP
Titanium @ Minnebar
PPTX
Presentation
Appcelerator Titanium Intro
Titanium Meetup Deck
Titanium Mobile Intro
Titanium Overview (Mobile March 2011)
OSCON Titanium Tutorial
Native Mobile Application Using Open Source
Modeveast Appcelerator Presentation
Appcelerator Titanium - An Introduction to the Titanium Ecosystem
The Big Easy: Native Mobile App Development with Appcelerator Titanium and Ja...
Appcelerator Titanium at Mobile 2.0
Mobile for the rest of us
Mobile 2.0 Event: Mobile for the rest of us using Appcelerator Titanium
Intro to appcelerator
Appcelerator Titanium Intro (2014)
Mountain View July JavaScript Meetup at Google
Intro to Appcelerator Titanium - Code for Fort Lauderdale 2015
Appcelerator iPhone/iPad Dev Con 2010 San Diego, CA
iPhone/iPad Development with Titanium
Titanium @ Minnebar
Presentation

Recently uploaded (20)

PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Cloud computing and distributed systems.
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
cuic standard and advanced reporting.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Machine learning based COVID-19 study performance prediction
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
MYSQL Presentation for SQL database connectivity
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Review of recent advances in non-invasive hemoglobin estimation
20250228 LYD VKU AI Blended-Learning.pptx
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Cloud computing and distributed systems.
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
MIND Revenue Release Quarter 2 2025 Press Release
Chapter 3 Spatial Domain Image Processing.pdf
cuic standard and advanced reporting.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Machine learning based COVID-19 study performance prediction
The AUB Centre for AI in Media Proposal.docx
Advanced methodologies resolving dimensionality complications for autism neur...
Encapsulation_ Review paper, used for researhc scholars
Diabetes mellitus diagnosis method based random forest with bat algorithm
Understanding_Digital_Forensics_Presentation.pptx
MYSQL Presentation for SQL database connectivity

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