SlideShare a Scribd company logo
1 of 100
Download to read offline
TICONFEU,AMSTERDAM,29/06/2014
{native: “FTW”}
!
Integrating native views in Titanium apps
Olivier Morandi
TICONFEU,AMSTERDAM,29/06/2014
Olivier Morandi
Software engineer
!
http://titaniumninja.com!
olivier.morandi@gmail.com
@olivier_morandi
https://github.com/omorandi
2
TICONFEU,AMSTERDAM,29/06/2014 3
TICONFEU,AMSTERDAM,29/06/2014
• Ti app development
• Native module development (iOS/Android)
• Optimisations
• R&D
4
TICONFEU,AMSTERDAM,29/06/2014
This Talk
• How to create view-based native modules
• How to integrate third party libraries
5
TICONFEU,AMSTERDAM,29/06/2014
Not in This Talk
• Basics of native module development
★ module creation
★ proxies, methods, properties, events,
callbacks
• Check out http://www.slideshare.net/
omorandi/ticonf
6
TICONFEU,AMSTERDAM,29/06/2014
Why Native Views
• UX/Performance
★ Stock Ti UI components not suitable for
the specific UX requirements
• Integration of native UI components and
libraries
★ Leverage existing solutions from the
Android and iOS OSS communities
★ Integrate third party SDKs
7
TICONFEU,AMSTERDAM,29/06/2014
Ti.Next/Hyperloop
• Q: Are Ti.Current native modules still
relevant?
• A: YES!
★ Ti.Next/Hyperloop is WIP
★ Active need in current Titanium projects
★ Maintaining legacy modules
8
TICONFEU,AMSTERDAM,29/06/2014
Learning Resources
TICONFEU,AMSTERDAM,29/06/2014
Official Appcelerator Guides
• http://docs.appcelerator.com/titanium/latest/#!/guide/
Extending_Titanium_Mobile
• http://docs.appcelerator.com/titanium/latest/#!/guide/
iOS_Module_Development_Guide
• http://docs.appcelerator.com/titanium/latest/#!/guide/
Android_Module_Development_Guide
10
TICONFEU,AMSTERDAM,29/06/2014 11
TICONFEU,AMSTERDAM,29/06/2014
Source code
• Titanium Mobile SDK
★ https://github.com/appcelerator/
titanium_mobile
• Open source modules from Appcelerator
★ https://github.com/appcelerator/
titanium_modules
12
TICONFEU,AMSTERDAM,29/06/2014
Follow these people (and more)
• Aaron K. Saunders: https://github.com/aaronksaunders
• Adam Paxton: https://github.com/adampax/
• Ben Bahrenburg: https://github.com/benbahrenburg
• David Bankier: https://github.com/dbankier
• Jordi Domenec: https://github.com/iamyellow
• Mads Møller: https://github.com/viezel
• Marcel Pociot: https://github.com/mpociot
• Matt Apperson: https://github.com/mattapperson
• Paul Mietz Egli: https://github.com/pegli
• Ruben Fonseca: https://github.com/rubenfonseca
• Many more… find them on http://gitt.io/
13
TICONFEU,AMSTERDAM,29/06/2014
Architecture Recap
TICONFEU,AMSTERDAM,29/06/2014 15
Titanium cli (node.js)
TICONFEU,AMSTERDAM,29/06/2014
Runtime (iOS)
16
Titanium
Modules
(API)
JS APP
Parser
Interpreter
IOS SDK
Bytecode
gen
JavaScriptCore
objective-c
C++
KROLLBRIDGE
TICONFEU,AMSTERDAM,29/06/2014
Runtime (iOS)
16
Titanium
Modules
(API)
JS APP
Parser
Interpreter
IOS SDK
Bytecode
gen
JavaScriptCore
NO JIT
objective-c
C++
KROLLBRIDGE
TICONFEU,AMSTERDAM,29/06/2014
Titanium
Modules
(API)
JS APP
Parser
Native Code
Android SDK
Native Code
gen
KROLLBRIDGE
Runtime (Android)
17
Java
C++
V8
OPT
TICONFEU,AMSTERDAM,29/06/2014
Titanium
Modules
(API)
JS APP
Parser
Native Code
Android SDK
Native Code
gen
KROLLBRIDGE
Runtime (Android)
17
Java
C++
V8
OPT
TICONFEU,AMSTERDAM,29/06/2014
Titanium
Modules
(API)
JS APP
Parser
Native Code
Android SDK
Native Code
gen
KROLLBRIDGE
Runtime (Android)
17
Java
C++
V8
OPT
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
module
object
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
factory
method
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
creation
properties
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
proxy
object
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
view proxy
object
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
proxy
property
TICONFEU,AMSTERDAM,29/06/2014
Terminology
18
var win1 = Titanium.UI.createWindow({
title:'Hello World',
backgroundColor:'white'
});
!
var label1 = Titanium.UI.createLabel({
color:'black',
textAlign:'center',
width: 100
});
!
label1.text = 'howdy?';
win1.add(label1);
!
win1.open();
proxy
method
TICONFEU,AMSTERDAM,29/06/2014
Proxies & Modules
Proxy
ViewProxy ViewModule
extends
has a
creates
19
manages
NativeView Type	

iOS UIView	

AndroidView
extends
TICONFEU,AMSTERDAM,29/06/2014
Proxies & Modules
Proxy
ViewProxy ViewModule
extends
has a
creates
19
manages
NativeView Type	

iOS UIView	

AndroidView
State:
properties
Actions:
methods
Events:
addEventListener(), fireEvent()
Interface
extends
TICONFEU,AMSTERDAM,29/06/2014
Proxies & Modules
Proxy
ViewProxy ViewModule
extends
has a
creates
19
manages
NativeView Type	

iOS UIView	

AndroidView
State:
properties
Actions:
methods
Events:
addEventListener(), fireEvent()
Interface
Methods for the integration within the
application lifecycle
•startup() (iOS)
•shutdown() (iOS)
•onAppCreate() (Android)
extends
TICONFEU,AMSTERDAM,29/06/2014
Proxies & Modules
Proxy
ViewProxy ViewModule
extends
has a
creates
19
manages
NativeView Type	

iOS UIView	

AndroidView
State:
properties
Actions:
methods
Events:
addEventListener(), fireEvent()
Interface
Additional members for the integration
within the UI layout system:
•add()
•remove()
•height
•width
•backgroundColor
•...
Methods for the integration within the
application lifecycle
•startup() (iOS)
•shutdown() (iOS)
•onAppCreate() (Android)
extends
TICONFEU,AMSTERDAM,29/06/2014
ViewProxy
20
ViewProxy
View
NativeViews
Hierarchy
Methods
Properties
(get/set)
Events
Holds the state
of a view
Manages the
native view
hierarchy
TICONFEU,AMSTERDAM,29/06/2014
ViewProxy
20
ViewProxy
View
NativeViews
Hierarchy
Methods
Properties
(get/set)
Events
Holds the state
of a view
Manages the
native view
hierarchy
JS THREAD
TICONFEU,AMSTERDAM,29/06/2014
ViewProxy
20
ViewProxy
View
NativeViews
Hierarchy
Methods
Properties
(get/set)
Events
Holds the state
of a view
Manages the
native view
hierarchy
JS THREAD UI THREAD
TICONFEU,AMSTERDAM,29/06/2014
ViewProxy
20
ViewProxy
View
NativeViews
Hierarchy
Methods
Properties
(get/set)
Events
Holds the state
of a view
Manages the
native view
hierarchy
JS THREAD UI THREAD
ASYNC
TICONFEU,AMSTERDAM,29/06/2014
A Basic Native View
TICONFEU,AMSTERDAM,29/06/2014 22
TICONFEU,AMSTERDAM,29/06/2014
Usage Scenario
23
var win = Ti.UI.createWindow({
backgroundColor: 'white'
});
!
var ticonf = require('ti.conf');
!
var basicView = ticonf.createBasicView({
width: 100,
height: 100
});
!
win.add(basicView);
!
win.open();
app.js
TICONFEU,AMSTERDAM,29/06/2014
ViewProxy Class
24
#import "TiViewProxy.h"
!
@interface TiConfBasicViewProxy : TiViewProxy
@end
TiConfBasicViewProxy.h
TiConfBasicViewProxy.m
#import "TiConfBasicViewProxy.h"
!
@implementation TiConfBasicViewProxy
!
!
@end
TICONFEU,AMSTERDAM,29/06/2014
View Class
25
#import "TiUIView.h"
!
@interface TiConfBasicView : TiUIView
{
UIView *theView;
}
@end
TiConfBasicView.h
TiConfBasicView.m
#import "TiConfBasicView.h"
!
@implementation TiConfBasicView
!
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
theView.backgroundColor = [UIColor redColor];
[self addSubview:theView];
}
!
@end
TICONFEU,AMSTERDAM,29/06/2014 26
TICONFEU,AMSTERDAM,29/06/2014 26
WTF: where’s my view?
TICONFEU,AMSTERDAM,29/06/2014 26
WTF: where’s my view?
TiConfBasicView
TICONFEU,AMSTERDAM,29/06/2014 26
WTF: where’s my view?
TiConfBasicView
theView
TICONFEU,AMSTERDAM,29/06/2014
Managing the subview frame
27
TiConfBasicView.m
#import "TiConfBasicView.h"
!
@implementation TiConfBasicView
!
!
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
theView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
theView.backgroundColor = [UIColor redColor];
[self addSubview:theView];
}
!
@end
TICONFEU,AMSTERDAM,29/06/2014
Managing the subview frame
27
TiConfBasicView.m
#import "TiConfBasicView.h"
!
@implementation TiConfBasicView
!
!
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
theView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
theView.backgroundColor = [UIColor redColor];
[self addSubview:theView];
}
!
@end
The Ti View frame is managed by the Ti
layout system.
Bounds are not valid until the view takes
part to an on-screen Ti view hierarchy
TICONFEU,AMSTERDAM,29/06/2014
Managing the subview frame
27
TiConfBasicView.m
#import "TiConfBasicView.h"
!
@implementation TiConfBasicView
!
!
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
theView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
theView.backgroundColor = [UIColor redColor];
[self addSubview:theView];
}
!
@end
The Ti View frame is managed by the Ti
layout system.
Bounds are not valid until the view takes
part to an on-screen Ti view hierarchy
TICONFEU,AMSTERDAM,29/06/2014
An alternative
28
TiConfBasicView.m
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
theView.backgroundColor = [UIColor redColor];
[self addSubview:theView];
}
!
!
!
-(void)frameSizeChanged:(CGRect)frame bounds:(CGRect)bounds
{
theView.frame = bounds;
}
TICONFEU,AMSTERDAM,29/06/2014
An alternative
28
TiConfBasicView.m
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
theView.backgroundColor = [UIColor redColor];
[self addSubview:theView];
}
!
!
!
-(void)frameSizeChanged:(CGRect)frame bounds:(CGRect)bounds
{
theView.frame = bounds;
}
called by -[TiUIView drawRect:]
TICONFEU,AMSTERDAM,29/06/2014
ViewProxy Class
29
@Kroll.proxy(creatableInModule=AndroidModule.class)
public class BasicViewProxy extends TiViewProxy
{
// Constructor
public BasicViewProxy()
{
super();
}
!
@Override
public TiUIView createView(Activity activity)
{
TiUIView view = new BasicView(this);
return view;
}
!
}
BasicViewProxy.java
TICONFEU,AMSTERDAM,29/06/2014
View Class
30
public class BasicView extends TiUIView
{
View theView;
public BasicView(TiViewProxy proxy) {
super(proxy);
!
Activity context = proxy.getActivity();
theView = new View(context);
theView.setBackgroundColor(Color.RED);
getLayoutParams().autoFillsHeight = true;
getLayoutParams().autoFillsWidth = true;
setNativeView(theView);
}
!
}
BasicView.java
TICONFEU,AMSTERDAM,29/06/2014 31
TICONFEU,AMSTERDAM,29/06/2014
Properties
• Properties belong to the ViewProxy object
• How do we make use of property values in
View objects?
32
TICONFEU,AMSTERDAM,29/06/2014
Setting a property
33
var basicView = ticonf.createBasicView({
color: "red"
});
!
//or
!
basicView.color = "red";
TICONFEU,AMSTERDAM,29/06/2014
Property from the Proxy
34
!
UIColor *color = [[TiUtils colorValue:[self.proxy valueForKey:@"color"]] color];
TiConfBasicView.m
Retrieving the property value from the ViewProxy when needed
TICONFEU,AMSTERDAM,29/06/2014
Explicit Setter in the ViewProxy
35
-(void)setColor:(UIColor*)color
{
theView.backgroundColor = color;
}
TiConfBasicView.m
-(void)setColor:(id)args
{
//expect 1 argument
ENSURE_ARG_COUNT(args, 1);
UIColor *color = [[TiUtils colorValue:args] color];
//dispatch to the view on UI thread
//(create it if needed, don't wait for completion)
[self makeViewPerformSelector:@selector(setColor:)
withObject:color createIfNeeded:YES waitUntilDone:NO];
}
TiConfBasicViewProxy.m
TICONFEU,AMSTERDAM,29/06/2014
Explicit Setter in the ViewProxy
35
-(void)setColor:(UIColor*)color
{
theView.backgroundColor = color;
}
TiConfBasicView.m
-(void)setColor:(id)args
{
//expect 1 argument
ENSURE_ARG_COUNT(args, 1);
UIColor *color = [[TiUtils colorValue:args] color];
//dispatch to the view on UI thread
//(create it if needed, don't wait for completion)
[self makeViewPerformSelector:@selector(setColor:)
withObject:color createIfNeeded:YES waitUntilDone:NO];
}
TiConfBasicViewProxy.m
JS
THREAD
TICONFEU,AMSTERDAM,29/06/2014
Explicit Setter in the ViewProxy
35
-(void)setColor:(UIColor*)color
{
theView.backgroundColor = color;
}
TiConfBasicView.m
-(void)setColor:(id)args
{
//expect 1 argument
ENSURE_ARG_COUNT(args, 1);
UIColor *color = [[TiUtils colorValue:args] color];
//dispatch to the view on UI thread
//(create it if needed, don't wait for completion)
[self makeViewPerformSelector:@selector(setColor:)
withObject:color createIfNeeded:YES waitUntilDone:NO];
}
TiConfBasicViewProxy.m
JS
THREAD
UI
THREAD
TICONFEU,AMSTERDAM,29/06/2014
Implicit Setter in the View Class
36
-(void)setColor_:(id)arg
{
theView.backgroundColor = [[TiUtils colorValue:arg] color];
}
TiConfBasicView.m
TICONFEU,AMSTERDAM,29/06/2014
Implicit Setter in the View Class
36
-(void)setColor_:(id)arg
{
theView.backgroundColor = [[TiUtils colorValue:arg] color];
}
TiConfBasicView.m
Automatically dispatched by the
ViewProxy on the UI thread
TICONFEU,AMSTERDAM,29/06/2014
Property from the Proxy
37
!
int color = TiConvert.toColor((String) proxy.getProperty(“color"));
BasicView.java
TICONFEU,AMSTERDAM,29/06/2014
Creation Properties
38
BasicView.java
@Override
public void processProperties(KrollDict props)
{
super.processProperties(props);
if (props.containsKey("color")) {
theView.setBackgroundColor(TiConvert.toColor(props.getString("color")));
}
else if (…) {
//do something else
}
}
TICONFEU,AMSTERDAM,29/06/2014
Property Changed Listener
39
BasicView.java
@Override
public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy)
{
if (key.equals("color")) {
theView.setBackgroundColor(TiConvert.toColor((String)newValue));
} else if () {
//do something else
}
}
public abstract class TiUIView implements KrollProxyListener
titanium_mobile/android/titanium/src/java/org/appcelerator/titanium/view/TiUIView.java:73
TICONFEU,AMSTERDAM,29/06/2014
Methods
• Exposed to JS by the ViewProxy object
• Dispatched to the View object
40
TICONFEU,AMSTERDAM,29/06/2014
View Methods
41
basicView.makeRounded();
TICONFEU,AMSTERDAM,29/06/2014 42
TICONFEU,AMSTERDAM,29/06/2014
View Method
43
-(void)makeRounded
{
theView.layer.cornerRadius = 20;
}
TiConfBasicView.m
-(void)makeRounded:(id)args
{
ENSURE_UI_THREAD(makeRounded, args);
TiConfBasicView *thisView = (TiConfBasicView*)[self view];
[thisView makeRounded];
}
TiConfBasicViewProxy.m
TICONFEU,AMSTERDAM,29/06/2014
View Method
43
-(void)makeRounded
{
theView.layer.cornerRadius = 20;
}
TiConfBasicView.m
-(void)makeRounded:(id)args
{
ENSURE_UI_THREAD(makeRounded, args);
TiConfBasicView *thisView = (TiConfBasicView*)[self view];
[thisView makeRounded];
}
TiConfBasicViewProxy.m
JS
THREAD
TICONFEU,AMSTERDAM,29/06/2014
View Method
43
-(void)makeRounded
{
theView.layer.cornerRadius = 20;
}
TiConfBasicView.m
-(void)makeRounded:(id)args
{
ENSURE_UI_THREAD(makeRounded, args);
TiConfBasicView *thisView = (TiConfBasicView*)[self view];
[thisView makeRounded];
}
TiConfBasicViewProxy.m
JS
THREAD
UI
THREAD
TICONFEU,AMSTERDAM,29/06/2014
Dispatching via GCD
44
-(void)makeRounded
{
theView.layer.cornerRadius = 20;
}
TiConfBasicView.m
-(void)makeRounded:(id)args
{
dispatch_async(dispatch_get_main_queue(), ^{
TiConfBasicView *thisView = (TiConfBasicView*)[self view];
[thisView makeRounded];
});
}
TiConfBasicViewProxy.m
TICONFEU,AMSTERDAM,29/06/2014
View Method Dispatching
45
public void makeRounded() {
GradientDrawable shape = new GradientDrawable();
shape.setColor(Color.RED);
shape.setCornerRadius(50);
theView.setBackgroundDrawable(shape);
}
BasicView.java
@Kroll.method
public void makeRounded() {
TiMessenger.postOnMain(new Runnable() {
!
@Override
public void run() {
BasicView view = (BasicView)getOrCreateView();
view.makeRounded();
}
});
}
BasicViewProxy.java
TICONFEU,AMSTERDAM,29/06/2014
View Method Dispatching
45
public void makeRounded() {
GradientDrawable shape = new GradientDrawable();
shape.setColor(Color.RED);
shape.setCornerRadius(50);
theView.setBackgroundDrawable(shape);
}
BasicView.java
@Kroll.method
public void makeRounded() {
TiMessenger.postOnMain(new Runnable() {
!
@Override
public void run() {
BasicView view = (BasicView)getOrCreateView();
view.makeRounded();
}
});
}
BasicViewProxy.java
JS
THREAD
TICONFEU,AMSTERDAM,29/06/2014
View Method Dispatching
45
public void makeRounded() {
GradientDrawable shape = new GradientDrawable();
shape.setColor(Color.RED);
shape.setCornerRadius(50);
theView.setBackgroundDrawable(shape);
}
BasicView.java
@Kroll.method
public void makeRounded() {
TiMessenger.postOnMain(new Runnable() {
!
@Override
public void run() {
BasicView view = (BasicView)getOrCreateView();
view.makeRounded();
}
});
}
BasicViewProxy.java
JS
THREAD
UI
THREAD
TICONFEU,AMSTERDAM,29/06/2014
Message Dispatching
46
private static final int MSG_MAKE_ROUNDED = TiViewProxy.MSG_LAST_ID + 4001;
protected static final int MSG_LAST_ID = MSG_MAKE_ROUNDED;
!
private void handleMakeRounded() {
BasicView view = (BasicView)getOrCreateView();
view.makeRounded();
}
@Override
public boolean handleMessage(Message msg){
if (msg.what == MSG_MAKE_ROUNDED) {
handleMakeRounded();
return true;
}
return super.handleMessage(msg);
}
@Kroll.method
public void makeRounded() {
if (TiApplication.isUIThread()) {
handleMakeRounded();
} else {
TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_MAKE_ROUNDED));
}
}
BasicViewProxy.java
TICONFEU,AMSTERDAM,29/06/2014
View Events
47
basicView.addEventListener('viewTapped', function() {
alert('tapped');
});
TICONFEU,AMSTERDAM,29/06/2014
Firing Events
48
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
// other initialisation operations
!
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(basicViewTapped:)];
// Specify that the gesture must be a single tap
tapRecognizer.numberOfTapsRequired = 1;
// Add the tap gesture recognizer to the view
[theView addGestureRecognizer:tapRecognizer];
}
!
- (void)basicViewTapped:(UITapGestureRecognizer *)recognizer {
NSDictionary *event = @{@"color": @"red"};
[self.proxy fireEvent:@"viewTapped" withObject:event];
}
TiConfBasicView.m
TICONFEU,AMSTERDAM,29/06/2014
Firing Events
48
-(void)initializeState
{
theView = [[UIView alloc] initWithFrame:self.bounds];
// other initialisation operations
!
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(basicViewTapped:)];
// Specify that the gesture must be a single tap
tapRecognizer.numberOfTapsRequired = 1;
// Add the tap gesture recognizer to the view
[theView addGestureRecognizer:tapRecognizer];
}
!
- (void)basicViewTapped:(UITapGestureRecognizer *)recognizer {
NSDictionary *event = @{@"color": @"red"};
[self.proxy fireEvent:@"viewTapped" withObject:event];
}
TiConfBasicView.m
TICONFEU,AMSTERDAM,29/06/2014
Firing Events
49
public BasicView(final TiViewProxy proxy) {
super(proxy);
!
Activity context = proxy.getActivity();
theView = new View(context);
!
//other initialisation operations
View.OnTouchListener gestureListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent e) {
KrollDict event = new KrollDict();
event.put("color", "red");
proxy.fireEvent("viewTapped", event);
return true;
}
};
theView.setOnTouchListener(gestureListener);
!
setNativeView(theView);
}
BasicView.java
TICONFEU,AMSTERDAM,29/06/2014
Firing Events
49
public BasicView(final TiViewProxy proxy) {
super(proxy);
!
Activity context = proxy.getActivity();
theView = new View(context);
!
//other initialisation operations
View.OnTouchListener gestureListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent e) {
KrollDict event = new KrollDict();
event.put("color", "red");
proxy.fireEvent("viewTapped", event);
return true;
}
};
theView.setOnTouchListener(gestureListener);
!
setNativeView(theView);
}
BasicView.java
TICONFEU,AMSTERDAM,29/06/2014
Integrating Third
Party Libraries
TICONFEU,AMSTERDAM,29/06/2014
iOS Static Library
• Static library file (.a)
• Objective-c/C/C++ headers folder
51
TICONFEU,AMSTERDAM,29/06/2014
iOS Static Library
52
TICONFEU,AMSTERDAM,29/06/2014
iOS Static Library
52
includes (headers) folder
TICONFEU,AMSTERDAM,29/06/2014
iOS Static Library
52
includes (headers) folder
static lib file (.a)
TICONFEU,AMSTERDAM,29/06/2014
iOS Static Library
52
includes (headers) folder
static lib file (.a)
ensure the lib is linked
with the module
TICONFEU,AMSTERDAM,29/06/2014
iOS Frameworks
• Framework bundle
★ Header files
★ Library
★ Resources
53
TICONFEU,AMSTERDAM,29/06/2014
iOS Frameworks
54
TITANIUM_SDK_VERSION = 3.2.3.GA
!
!
TITANIUM_SDK = ~/Library/Application Support/Titanium/mobilesdk/osx/$(TITANIUM_SDK_VERSION)
TITANIUM_BASE_SDK = "$(TITANIUM_SDK)/iphone/include"
TITANIUM_BASE_SDK2 = "$(TITANIUM_SDK)/iphone/include/TiCore"
HEADER_SEARCH_PATHS= $(TITANIUM_BASE_SDK) $(TITANIUM_BASE_SDK2) /PATH/TO/YOUR/FRAMEWORK/HEADERS
titanium.xcconfig
TICONFEU,AMSTERDAM,29/06/2014
iOS Frameworks
54
TITANIUM_SDK_VERSION = 3.2.3.GA
!
!
TITANIUM_SDK = ~/Library/Application Support/Titanium/mobilesdk/osx/$(TITANIUM_SDK_VERSION)
TITANIUM_BASE_SDK = "$(TITANIUM_SDK)/iphone/include"
TITANIUM_BASE_SDK2 = "$(TITANIUM_SDK)/iphone/include/TiCore"
HEADER_SEARCH_PATHS= $(TITANIUM_BASE_SDK) $(TITANIUM_BASE_SDK2) /PATH/TO/YOUR/FRAMEWORK/HEADERS
titanium.xcconfig
TICONFEU,AMSTERDAM,29/06/2014
iOS Frameworks
54
TITANIUM_SDK_VERSION = 3.2.3.GA
!
!
TITANIUM_SDK = ~/Library/Application Support/Titanium/mobilesdk/osx/$(TITANIUM_SDK_VERSION)
TITANIUM_BASE_SDK = "$(TITANIUM_SDK)/iphone/include"
TITANIUM_BASE_SDK2 = "$(TITANIUM_SDK)/iphone/include/TiCore"
HEADER_SEARCH_PATHS= $(TITANIUM_BASE_SDK) $(TITANIUM_BASE_SDK2) /PATH/TO/YOUR/FRAMEWORK/HEADERS
titanium.xcconfig
Used ad module build time
TICONFEU,AMSTERDAM,29/06/2014
iOS Frameworks
55
!
OTHER_LDFLAGS=$(inherited) -framework <FRAMEWORK> -F <PATH/TO/FRAMEWORK>
!
For example:
!
OTHER_LDFLAGS=$(inherited) -framework ArcGIS -F $HOME/Library/SDKs/ArcGIS/iOS/
module.xcconfig
TICONFEU,AMSTERDAM,29/06/2014
iOS Frameworks
55
!
OTHER_LDFLAGS=$(inherited) -framework <FRAMEWORK> -F <PATH/TO/FRAMEWORK>
!
For example:
!
OTHER_LDFLAGS=$(inherited) -framework ArcGIS -F $HOME/Library/SDKs/ArcGIS/iOS/
module.xcconfig
Used ad application build time
TICONFEU,AMSTERDAM,29/06/2014
ARC vs. NON-ARC
• ARC = Automatic Reference Counting
★ Retain/Release handled automatically by
the Clang compiler
• Ti module template project is still NON-
ARC
• You can use ARC code inside of a Ti
module project
56
TICONFEU,AMSTERDAM,29/06/2014
Enabling ARC for a specific file
57
TICONFEU,AMSTERDAM,29/06/2014
Using external JARs
58
drag & drop the JAR in the
lib folder of the module
project
TICONFEU,AMSTERDAM,29/06/2014
Using external JARs
59
Add the external JAR
to the project build
path
TICONFEU,AMSTERDAM,29/06/2014
Integrating native libs (NDK)
60
Import the native shared
libraries (.so), separated
by target architecture in
the lib folder
TICONFEU,AMSTERDAM,29/06/2014
Fix build.xml
61
<project name="android" default="dist">	
	 <description>	
	 	 Ant build script for Titanium Android module android	
	 </description>	
!
	 <property name="ti.module.root" location="${basedir}"/>	
	 <property file="build.properties" />	
!
	 <import file="${titanium.platform}/../module/android/build.xml"/>	
	 	
	 <target name="post.jar">	
	 	 <copy todir="${libs}">	
	 <fileset dir="lib">	
		 <include name="**/*.so"/>	
	 </fileset>	
		 </copy>	
	 </target>	
</project>	
build.xml
Copy the .so files from lib to
libs before packaging
Paul Mietz Egli: http://developer.appcelerator.com/question/121573/how-do-i-use-so-library-in-module#answer-228134
TICONFEU,AMSTERDAM,29/06/2014
Fix build.xml
61
<project name="android" default="dist">	
	 <description>	
	 	 Ant build script for Titanium Android module android	
	 </description>	
!
	 <property name="ti.module.root" location="${basedir}"/>	
	 <property file="build.properties" />	
!
	 <import file="${titanium.platform}/../module/android/build.xml"/>	
	 	
	 <target name="post.jar">	
	 	 <copy todir="${libs}">	
	 <fileset dir="lib">	
		 <include name="**/*.so"/>	
	 </fileset>	
		 </copy>	
	 </target>	
</project>	
build.xml
Copy the .so files from lib to
libs before packaging
Paul Mietz Egli: http://developer.appcelerator.com/question/121573/how-do-i-use-so-library-in-module#answer-228134
TICONFEU,AMSTERDAM,29/06/2014
Questions?

More Related Content

Similar to Native FTW: Integrating native views in Titanium apps

12_CI4_FITMAN_Javier Martín
12_CI4_FITMAN_Javier Martín12_CI4_FITMAN_Javier Martín
12_CI4_FITMAN_Javier Martín
Redit
 
LivingLabs & Open Innovation
LivingLabs & Open InnovationLivingLabs & Open Innovation
LivingLabs & Open Innovation
urbanlabs
 
Digital Fabrication Studio 0.3 Introduction
Digital Fabrication Studio 0.3 IntroductionDigital Fabrication Studio 0.3 Introduction
Digital Fabrication Studio 0.3 Introduction
Massimo Menichinelli
 

Similar to Native FTW: Integrating native views in Titanium apps (20)

Business Models for Open Source Hardware
Business Models for Open Source HardwareBusiness Models for Open Source Hardware
Business Models for Open Source Hardware
 
Mobile Development Options
Mobile Development OptionsMobile Development Options
Mobile Development Options
 
From open source labs to ceo methods and advice by sysfera
From open source labs to ceo methods and advice by sysferaFrom open source labs to ceo methods and advice by sysfera
From open source labs to ceo methods and advice by sysfera
 
Open Hardware Summit 2014
Open Hardware Summit 2014Open Hardware Summit 2014
Open Hardware Summit 2014
 
Como construir un Fab Lab - FEED2015 20.11.2015
Como construir un Fab Lab - FEED2015 20.11.2015Como construir un Fab Lab - FEED2015 20.11.2015
Como construir un Fab Lab - FEED2015 20.11.2015
 
London Oracle Developer Meetup - June 18 - Drones with APIs
London Oracle Developer Meetup - June 18 - Drones with APIsLondon Oracle Developer Meetup - June 18 - Drones with APIs
London Oracle Developer Meetup - June 18 - Drones with APIs
 
Digital Fabrication Studio v.0.2: Introduction
Digital Fabrication Studio v.0.2: IntroductionDigital Fabrication Studio v.0.2: Introduction
Digital Fabrication Studio v.0.2: Introduction
 
Why and How to do a Software Startup
Why and How to do a Software StartupWhy and How to do a Software Startup
Why and How to do a Software Startup
 
ITCamp 2018 - Florin Coros - ‘Cloud Ready’ Design through Application Softwar...
ITCamp 2018 - Florin Coros - ‘Cloud Ready’ Design through Application Softwar...ITCamp 2018 - Florin Coros - ‘Cloud Ready’ Design through Application Softwar...
ITCamp 2018 - Florin Coros - ‘Cloud Ready’ Design through Application Softwar...
 
‘Cloud Ready’ Design through Application Software Infrastructure
‘Cloud Ready’ Design through Application Software Infrastructure‘Cloud Ready’ Design through Application Software Infrastructure
‘Cloud Ready’ Design through Application Software Infrastructure
 
12_CI4_FITMAN_Javier Martín
12_CI4_FITMAN_Javier Martín12_CI4_FITMAN_Javier Martín
12_CI4_FITMAN_Javier Martín
 
12_CI4_FITMAN_Javier Martín
12_CI4_FITMAN_Javier Martín12_CI4_FITMAN_Javier Martín
12_CI4_FITMAN_Javier Martín
 
LivingLabs & Open Innovation
LivingLabs & Open InnovationLivingLabs & Open Innovation
LivingLabs & Open Innovation
 
inleiding tot chi
inleiding tot chiinleiding tot chi
inleiding tot chi
 
Patent Strategy for Startups, Hardware Workshop SF 2015
Patent Strategy for Startups, Hardware Workshop SF 2015 Patent Strategy for Startups, Hardware Workshop SF 2015
Patent Strategy for Startups, Hardware Workshop SF 2015
 
Appcelerator Titanium - An Introduction to the Titanium Ecosystem
Appcelerator Titanium - An Introduction to the Titanium EcosystemAppcelerator Titanium - An Introduction to the Titanium Ecosystem
Appcelerator Titanium - An Introduction to the Titanium Ecosystem
 
Prototyping
PrototypingPrototyping
Prototyping
 
Defcon Blue Team Village 2020: Purple On My Mind: Cost Effective Automated Ad...
Defcon Blue Team Village 2020: Purple On My Mind: Cost Effective Automated Ad...Defcon Blue Team Village 2020: Purple On My Mind: Cost Effective Automated Ad...
Defcon Blue Team Village 2020: Purple On My Mind: Cost Effective Automated Ad...
 
Digital Fabrication Studio 0.3 Introduction
Digital Fabrication Studio 0.3 IntroductionDigital Fabrication Studio 0.3 Introduction
Digital Fabrication Studio 0.3 Introduction
 
Maker Faire Shenzhen, April 2014. Atmel's position in the maker space
Maker Faire Shenzhen, April 2014. Atmel's position in the maker spaceMaker Faire Shenzhen, April 2014. Atmel's position in the maker space
Maker Faire Shenzhen, April 2014. Atmel's position in the maker space
 

Recently uploaded

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Cara Menggugurkan Kandungan 087776558899
 

Recently uploaded (6)

Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdf
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 

Native FTW: Integrating native views in Titanium apps