際際滷

際際滷Share a Scribd company logo
Titanium Native
Module
The missing handbook
THE FOLLOWING SESSION HAS BEEN APPROVED FOR
TITANIUM
DEVELOPERS
SO DONT PANIC IF YOU DONT KNOW OBJECTIVE-C
TL;DR @presentation
 What a module looks like
 Methods & Properties
 TiModule
 TiProxy (Non Visual)
 TiUIView & ViewProxys
Who am I?
 Titan
 Using Ti 4+ year
 Language Geek
 Enterprise Innovator
@benCoding
Bencoding.com
Ti conf
From the documentation
Maybe think of it as this
Your JavaScript
Titaniums JavaScript
Ti SDK / Kroll
Titanium SDK
Modules
Your Modules
What is
Kroll?
Kroll is.
 Bridge between Native and JavaScript
 Translates types, arguments, etc
 Exposes methods, properties, etc
 Manages references
Components of modules
TiModule
TiProxy TiUIView
TiView
Proxy
The bad news
Cross-platform native
modules means code
at least twice
Methods
@Kroll.method
public void demoMethodNoReturn()
public int demoMethodNumberInt(Object[] args)
public float demoMethodNumberFloat(Object[] args)
public String demoMethodString(Object[] args)
public HashMap demoMethodDictionary(Object args)
public Date demoMethodDate(HashMap hm)
public Object[] demoMethodArray(Object[] args)
Method Examples
-(NSNumber*) demoMethodNumberFloat:(id)args {}
-(NSString*) demoMethodString:(id)args {}
-(NSDictionary*) demoMethodDictionary:(id)args {}
-(NSDate*) demoMethodDate:(id)args {}
-(NSArray*) demoMethodArray:(id)args {}
-(NSNull*) demoMethodNull:(id)args {}
-(TiFile*) demoMethodFile:(id)args {}
-(TiBlob*) demoMethodBlob:(id)args {}
-(TiRect*) demoMethodRect:(id)args {}
-(TiPoint*) demoMethodPoint:(id)args {}
Methods things to consider
 Most native arguments are converted, ie strings
 More complex arguments are converted to NSDictionary
 BOOL return results much be converted to numbers
NUMBOOL(NO)
Properties
Properties
private boolean DEBUG = false;
@Kroll.getProperty
public boolean getDebug()
{
return DEBUG;
}
@Kroll.setProperty
public void setDebug(boolean value) {
DEBUG = value;
}
Properties
-(id)debug
{
return NUMBOOL(NO);
}
-(void)setDebug:(id)value
{
NSLog(@Setting debug);
}
TiModule
TiModule the important parts
@Kroll.module(name="TiLight", id="ti.light")
public class TiLightModule extends KrollModule
{
..
public TiLightModule()
{
super();
}
}
Decorate module so Kroll
knows what to do
Extend
KrollModule
TiModule Example
@Kroll.module(name="Tilight", id="ti.light")
public class TilightModule extends KrollModule
{
public TilightModule()
{
super();
}
@Kroll.method
public void toggle()
{
if (isLighOn) {
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLighOn = false;
} else {
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
isLighOn = true;
}
}
}
TiModule the important parts
#import "TiModule.h"
@interface TiLightModule : TiModule {
}
@end
Import TiModule.h
Implement the
TiModule interface
TiModule Example
#import <AVFoundation/AVFoundation.h>
#import "TiLightModule.h
@implementation TiLightModule
- (void) toggle: (id) unused
{
AVCaptureDevice *device =
[AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
if (device.torchMode == AVCaptureTorchModeOff)
{
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
}
else
{
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
}
[device unlockForConfiguration];
}
@end
Available at.
Ti.Light
https://github.com/benbahrenburg/ti.light
TiProxy
TiProxy the important parts
@Kroll.proxy(creatableInModule = BasicgeoModule.class)
public class GeocoderProxy extends KrollProxy {
{
..
public GeocoderProxy()
{
super();
}
}
Decorate so Kroll
knows what to do
Extend
KrollProxy
TiProxy Life Cycle
TiProxy Life Cycle overrideable elements
 public void handleCreationDict(KrollDict options)
 public void handleCreationArgs(KrollModule
createdInModule, Object[] args)
* Javas native constructor and other life cycle
elements also apply
TiProxy Example
@Kroll.proxy(creatableInModule = BasicgeoModule.class)
public class GeocoderProxy extends KrollProxy {
public GeocoderProxy() {
super();
}
@Kroll.method
public boolean isSupported(){
return CommonHelpers.reverseGeoSupported();
}
}
TiProxy the important parts
#import "TiProxy.h"
@interface BencodingBasicgeoGeocoderProxy:
TiProxy{
}
@end
Import TiProxy.h
Implement the
TiProxy interface
TiProxy Life Cycle
 -(id)init
 -(void)_destroy
 -(void)dealloc
 -(id)_initWithPageContext:(id<TiEvaluator>)context
 -(id)_initWithPageContext:(id<TiEvaluator>)
context_ args:(NSArray*)args
 -(void)_configure
 -(void)_initWithProperties:(NSDictionary *)properties
TiProxy Example
#import "BencodingBasicgeoGeocoderProxy.h
#import "TiUtils.h
@implementation BencodingBasicgeoGeocoderProxy
-(NSNumber*)isSupported:(id)unused
{
BOOL hasMinOSVersion=NO;
if(NSClassFromString(@"UIReferenceLibraryViewController"))
{
hasMinOSVersion=YES;
}
return NUMBOOL(hasMinOSVersion);
}
@end
Available at.
BasicGeo
https://github.com/benbahrenburg/
benCoding.BasicGeo
TiUiView &
TiViewProxy
TiUIView + TiViewProxy Relationship
TiUIView
Native object,
ie UIView
TiViewProxy
Model / Controller for the
paired TiUIView
TiViewProxy the important parts
Kroll.proxy(creatableInModule = TisqModule.class)
public class ViewProxy extends TiViewProxy {
{
..
public ViewProxy ()
{
super();
}
@Override
public TiUIView createView(Activity activity)
{
..
}
}
Decorate
Extend
TiViewProxy
Create the TiIUView
TiUIView the important parts
public class View extends TiUIView
{
..
public View(TiViewProxy proxy)
{
super(proxy);
..
setNativeView(calendar);
}
}
Extend TiUIView
TiViewProxy passed
to constructor
Set as native view
Life Cycle
TiUIView
 public void processProperties(KrollDict props)
 public void propertyChanged(String key, Object oldValue,
Object newValue, KrollProxy proxy)
TiViewProxy
 public TiUIView createView(Activity activity)
 public void handleCreationDict(KrollDict options)
TiViewProxy Example
@Kroll.proxy(creatableInModule = TisqModule.class)
public class ViewProxy extends TiViewProxy {
public ViewProxy() {
super();
}
@Kroll.getProperty()
public Date getValue(){
ti.sq.View demoView = (ti.sq.View)view;
return demoView.getValue();
}
}
TiUiView Example
public class View extends TiUIView{
..
public Date getValue(){
CalendarPickerView square = (CalendarPickerView)getNativeView();
return square.getSelectedDate();
}
public void setValue(HashMap hm){
Date newValue = convertHMtoDate(hm);
CalendarPickerView square = (CalendarPickerView)getNativeView();
square.selectDate(newValue);
}
..
}
TiViewProxy the important parts
#import " TiViewProxy.h "
@interface TiSqViewProxy : TiViewProxy {
..
}
@end
Import
TiViewProxy.h
Implement the
TiViewProxy interface
TiUIView the important parts
#import "TiUIView.h"
@interface TiSqView :
TiUIView<TSQCalendarViewDelegate>{
..
}
@end
Import TiUIView.h
Implement the
TiUIView interface
TiUIView Life Cycle
 -(id)init
 -(void)dealloc
 -(void)willMoveToSuperview:(UIView *)newSuperview
 -(void)initializeState
 -(void)configurationSet
 -(void)frameSizeChanged:(CGRect)frame
bounds:(CGRect)bounds
TiUiView Example
@implementation TiSqView
..
-(void)setBackgroundColor_:(id)value{
TiColor *newColor = [TiUtils colorValue:value];
UIColor *clr = [newColor _color];
UIView *sq = [self square];
sq.backgroundColor = clr;
}
-(void)setPagingEnabled_:(id)value{
[[self square] setPagingEnabled:[TiUtils boolValue:value]];
}
..
}
TiViewProxy Life Cycle
 -(id)init
 -(void)_destroy
 -(id)_initWithPageContext:(id<TiEvaluator>)context
 -(id)_initWithPageContext:(id<TiEvaluator>)context_ args:(NSArray*)args
 -(void)_configure
 -(void)_initWithProperties:(NSDictionary *)properties
 -(void)viewWillAttach
 -(void)viewDidAttach
 -(void)viewDidDetach
 -(void)viewWillDetach
TiViewProxy Example
#import "TiSqViewProxy.h"
#import "TiUtils.h"
#import "TiSqView.h"
@implementation TiSqViewProxy

-(NSArray *)keySequence{
return [NSArray arrayWithObjects: @"min",@"max",nil];
}
-(void)viewDidAttach{
if ([NSThread isMainThread]) {
TiSqView * ourView = (TiSqView *)[self view];
[ourView render];
}
[super viewDidAttach];
}
Available at.
Ti.SQ
https://github.com/benbahrenburg/ti.sq
Appcelerator Resources
 ModDevGuide
 https://github.com/appcelerator/titanium_modules/tree/master/moddevguide
 Guide - Extending Titanium Mobile
 http://docs.appcelerator.com/titanium/latest/#!/guide/Extending_Titanium_Mobile
 Titanium Mobile Source
 https://github.com/appcelerator/titanium_mobile
Community
 Mads M淡ller @nappdev
 Olivier Morandi @oliver_morandi
 Matt Apperson @AppersonLabs
 Fokke Zandbergen @FokkeZB
 Jordi Domenech iamyellow.net
 Russ Frank @russjf
 Paul Mietz Egli @pegli
 Aaron Saunders @aaronksaunders
Questions?
@benCoding
benbahrenburg
bencoding.com

More Related Content

Ti conf

  • 2. THE FOLLOWING SESSION HAS BEEN APPROVED FOR TITANIUM DEVELOPERS SO DONT PANIC IF YOU DONT KNOW OBJECTIVE-C
  • 3. TL;DR @presentation What a module looks like Methods & Properties TiModule TiProxy (Non Visual) TiUIView & ViewProxys
  • 4. Who am I? Titan Using Ti 4+ year Language Geek Enterprise Innovator @benCoding Bencoding.com
  • 7. Maybe think of it as this Your JavaScript Titaniums JavaScript Ti SDK / Kroll Titanium SDK Modules Your Modules
  • 9. Kroll is. Bridge between Native and JavaScript Translates types, arguments, etc Exposes methods, properties, etc Manages references
  • 10. Components of modules TiModule TiProxy TiUIView TiView Proxy
  • 11. The bad news Cross-platform native modules means code at least twice
  • 13. @Kroll.method public void demoMethodNoReturn() public int demoMethodNumberInt(Object[] args) public float demoMethodNumberFloat(Object[] args) public String demoMethodString(Object[] args) public HashMap demoMethodDictionary(Object args) public Date demoMethodDate(HashMap hm) public Object[] demoMethodArray(Object[] args)
  • 14. Method Examples -(NSNumber*) demoMethodNumberFloat:(id)args {} -(NSString*) demoMethodString:(id)args {} -(NSDictionary*) demoMethodDictionary:(id)args {} -(NSDate*) demoMethodDate:(id)args {} -(NSArray*) demoMethodArray:(id)args {} -(NSNull*) demoMethodNull:(id)args {} -(TiFile*) demoMethodFile:(id)args {} -(TiBlob*) demoMethodBlob:(id)args {} -(TiRect*) demoMethodRect:(id)args {} -(TiPoint*) demoMethodPoint:(id)args {}
  • 15. Methods things to consider Most native arguments are converted, ie strings More complex arguments are converted to NSDictionary BOOL return results much be converted to numbers NUMBOOL(NO)
  • 17. Properties private boolean DEBUG = false; @Kroll.getProperty public boolean getDebug() { return DEBUG; } @Kroll.setProperty public void setDebug(boolean value) { DEBUG = value; }
  • 20. TiModule the important parts @Kroll.module(name="TiLight", id="ti.light") public class TiLightModule extends KrollModule { .. public TiLightModule() { super(); } } Decorate module so Kroll knows what to do Extend KrollModule
  • 21. TiModule Example @Kroll.module(name="Tilight", id="ti.light") public class TilightModule extends KrollModule { public TilightModule() { super(); } @Kroll.method public void toggle() { if (isLighOn) { p.setFlashMode(Parameters.FLASH_MODE_OFF); camera.setParameters(p); camera.stopPreview(); isLighOn = false; } else { p.setFlashMode(Parameters.FLASH_MODE_TORCH); camera.setParameters(p); camera.startPreview(); isLighOn = true; } } }
  • 22. TiModule the important parts #import "TiModule.h" @interface TiLightModule : TiModule { } @end Import TiModule.h Implement the TiModule interface
  • 23. TiModule Example #import <AVFoundation/AVFoundation.h> #import "TiLightModule.h @implementation TiLightModule - (void) toggle: (id) unused { AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo]; [device lockForConfiguration:nil]; if (device.torchMode == AVCaptureTorchModeOff) { [device setTorchMode:AVCaptureTorchModeOn]; [device setFlashMode:AVCaptureFlashModeOn]; } else { [device setTorchMode:AVCaptureTorchModeOff]; [device setFlashMode:AVCaptureFlashModeOff]; } [device unlockForConfiguration]; } @end
  • 26. TiProxy the important parts @Kroll.proxy(creatableInModule = BasicgeoModule.class) public class GeocoderProxy extends KrollProxy { { .. public GeocoderProxy() { super(); } } Decorate so Kroll knows what to do Extend KrollProxy
  • 27. TiProxy Life Cycle TiProxy Life Cycle overrideable elements public void handleCreationDict(KrollDict options) public void handleCreationArgs(KrollModule createdInModule, Object[] args) * Javas native constructor and other life cycle elements also apply
  • 28. TiProxy Example @Kroll.proxy(creatableInModule = BasicgeoModule.class) public class GeocoderProxy extends KrollProxy { public GeocoderProxy() { super(); } @Kroll.method public boolean isSupported(){ return CommonHelpers.reverseGeoSupported(); } }
  • 29. TiProxy the important parts #import "TiProxy.h" @interface BencodingBasicgeoGeocoderProxy: TiProxy{ } @end Import TiProxy.h Implement the TiProxy interface
  • 30. TiProxy Life Cycle -(id)init -(void)_destroy -(void)dealloc -(id)_initWithPageContext:(id<TiEvaluator>)context -(id)_initWithPageContext:(id<TiEvaluator>) context_ args:(NSArray*)args -(void)_configure -(void)_initWithProperties:(NSDictionary *)properties
  • 31. TiProxy Example #import "BencodingBasicgeoGeocoderProxy.h #import "TiUtils.h @implementation BencodingBasicgeoGeocoderProxy -(NSNumber*)isSupported:(id)unused { BOOL hasMinOSVersion=NO; if(NSClassFromString(@"UIReferenceLibraryViewController")) { hasMinOSVersion=YES; } return NUMBOOL(hasMinOSVersion); } @end
  • 34. TiUIView + TiViewProxy Relationship TiUIView Native object, ie UIView TiViewProxy Model / Controller for the paired TiUIView
  • 35. TiViewProxy the important parts Kroll.proxy(creatableInModule = TisqModule.class) public class ViewProxy extends TiViewProxy { { .. public ViewProxy () { super(); } @Override public TiUIView createView(Activity activity) { .. } } Decorate Extend TiViewProxy Create the TiIUView
  • 36. TiUIView the important parts public class View extends TiUIView { .. public View(TiViewProxy proxy) { super(proxy); .. setNativeView(calendar); } } Extend TiUIView TiViewProxy passed to constructor Set as native view
  • 37. Life Cycle TiUIView public void processProperties(KrollDict props) public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) TiViewProxy public TiUIView createView(Activity activity) public void handleCreationDict(KrollDict options)
  • 38. TiViewProxy Example @Kroll.proxy(creatableInModule = TisqModule.class) public class ViewProxy extends TiViewProxy { public ViewProxy() { super(); } @Kroll.getProperty() public Date getValue(){ ti.sq.View demoView = (ti.sq.View)view; return demoView.getValue(); } }
  • 39. TiUiView Example public class View extends TiUIView{ .. public Date getValue(){ CalendarPickerView square = (CalendarPickerView)getNativeView(); return square.getSelectedDate(); } public void setValue(HashMap hm){ Date newValue = convertHMtoDate(hm); CalendarPickerView square = (CalendarPickerView)getNativeView(); square.selectDate(newValue); } .. }
  • 40. TiViewProxy the important parts #import " TiViewProxy.h " @interface TiSqViewProxy : TiViewProxy { .. } @end Import TiViewProxy.h Implement the TiViewProxy interface
  • 41. TiUIView the important parts #import "TiUIView.h" @interface TiSqView : TiUIView<TSQCalendarViewDelegate>{ .. } @end Import TiUIView.h Implement the TiUIView interface
  • 42. TiUIView Life Cycle -(id)init -(void)dealloc -(void)willMoveToSuperview:(UIView *)newSuperview -(void)initializeState -(void)configurationSet -(void)frameSizeChanged:(CGRect)frame bounds:(CGRect)bounds
  • 43. TiUiView Example @implementation TiSqView .. -(void)setBackgroundColor_:(id)value{ TiColor *newColor = [TiUtils colorValue:value]; UIColor *clr = [newColor _color]; UIView *sq = [self square]; sq.backgroundColor = clr; } -(void)setPagingEnabled_:(id)value{ [[self square] setPagingEnabled:[TiUtils boolValue:value]]; } .. }
  • 44. TiViewProxy Life Cycle -(id)init -(void)_destroy -(id)_initWithPageContext:(id<TiEvaluator>)context -(id)_initWithPageContext:(id<TiEvaluator>)context_ args:(NSArray*)args -(void)_configure -(void)_initWithProperties:(NSDictionary *)properties -(void)viewWillAttach -(void)viewDidAttach -(void)viewDidDetach -(void)viewWillDetach
  • 45. TiViewProxy Example #import "TiSqViewProxy.h" #import "TiUtils.h" #import "TiSqView.h" @implementation TiSqViewProxy -(NSArray *)keySequence{ return [NSArray arrayWithObjects: @"min",@"max",nil]; } -(void)viewDidAttach{ if ([NSThread isMainThread]) { TiSqView * ourView = (TiSqView *)[self view]; [ourView render]; } [super viewDidAttach]; }
  • 47. Appcelerator Resources ModDevGuide https://github.com/appcelerator/titanium_modules/tree/master/moddevguide Guide - Extending Titanium Mobile http://docs.appcelerator.com/titanium/latest/#!/guide/Extending_Titanium_Mobile Titanium Mobile Source https://github.com/appcelerator/titanium_mobile
  • 48. Community Mads M淡ller @nappdev Olivier Morandi @oliver_morandi Matt Apperson @AppersonLabs Fokke Zandbergen @FokkeZB Jordi Domenech iamyellow.net Russ Frank @russjf Paul Mietz Egli @pegli Aaron Saunders @aaronksaunders