Jacob Waller: Webifying Titanium Development

86
Kranium Webifying Titanium Development Jacob Waller

description

What if we could bring the good parts of web development to Titanium? I'm talking about the realtimeness of web development - changing files and being able to see results on the fly, both visually and regarding application logic. Compare it to Firebug's live CSS editing abilities and Chrome's live code changes. I'm also talking about bringing the beauty of web frameworks to Titanium - Stylus, SASS and Less for styling, CoffeeScript and its cousins to enhance development, Jasmine for testing, Backbone for MVC and jQuery and friends to simplify element creation, communication and handling. What if we could use all these techniques on top of Titanium to create native apps even faster and with better structure?The solution is Kranium - the result of merging Titanium with web development techniques, creating a cyborg which is greater than just the sum of its parts. It will significantly speed up development and styling, and is useful both for prototyping and production apps. It will be release under the MIT license during the conference. The session is meant as an introduction of Kranium for all Titanium developers, but will be especially thrilling for those with a web development background.

Transcript of Jacob Waller: Webifying Titanium Development

Page 1: Jacob Waller: Webifying Titanium Development

Kranium  Webifying  Titanium  Development  

Jacob  Waller  

Page 2: Jacob Waller: Webifying Titanium Development
Page 3: Jacob Waller: Webifying Titanium Development

+! +!+! →!

Page 4: Jacob Waller: Webifying Titanium Development

+

Page 5: Jacob Waller: Webifying Titanium Development

•  Webifying Titanium Development!

Kranium http://flic.kr/p/9wLZkJ!

Page 6: Jacob Waller: Webifying Titanium Development

"   Cross platform apps using javascript!

"   Shared business logic!

"   Native UI!

"   Device API:s!

Page 7: Jacob Waller: Webifying Titanium Development

Why cross-platform?

"   One codebase!

"   Faster development → cheaper development!

"   Less code → less bugs!

"   Focus on one language and one tool!

Page 8: Jacob Waller: Webifying Titanium Development

Why not cross-platform?

"   Potential bugs in cross-platform frameworks!

"   Somewhat harder stepping outside the box!

"   Might still need platform branching!

"   Less speed and more memory usage!

Page 9: Jacob Waller: Webifying Titanium Development

Cross Platform is Hard

"   iOS!

"   Objective-C!

"   XCode!

"   Android!

"   Java!

"   Eclipse!

Page 10: Jacob Waller: Webifying Titanium Development

Titanium takes the hit

http://flic.kr/p/91Zydu!

Page 11: Jacob Waller: Webifying Titanium Development

Cross Platform Medicine

"   Must use lowest common denominator!

"   Go with a low-level API!

"   Must focus on getting the “atoms” behave the same across platforms!

http://flic.kr/p/8dZbk4!

Page 12: Jacob Waller: Webifying Titanium Development

Low-level

Means powerful!

http://flic.kr/p/75b2DJ!

Page 13: Jacob Waller: Webifying Titanium Development

Low-level

Also means annoying to build large stuff!

http://flic.kr/p/5JDvZM!

Page 14: Jacob Waller: Webifying Titanium Development

Low-level

Is it therefore wrong?!

http://flic.kr/p/nyxCW!

Page 15: Jacob Waller: Webifying Titanium Development

NO

Page 16: Jacob Waller: Webifying Titanium Development

High-level

"   Low level building blocks let us build high-level abstractions!

"   Upon which we can build awesome stuff!

Page 17: Jacob Waller: Webifying Titanium Development

High-level

http://flic.kr/p/8ovJYH!

Page 18: Jacob Waller: Webifying Titanium Development

Titanium

"   Titanium Mobile has a low-level core API:s for each platform it supports!

"   Lets cover it in platform-independent high-level awesome-sauce!

Page 19: Jacob Waller: Webifying Titanium Development

But how?

http://flic.kr/p/9wfuUh!

Page 20: Jacob Waller: Webifying Titanium Development

Parallel

"   Web development has low-level API:s!

"   document.createElement!

"   element.style.backgroundColor!

Page 21: Jacob Waller: Webifying Titanium Development

Web development

if (el.addEventListener) { el.addEventListener("mouseover", myFunction, false); el.addEventListener("mouseout", myFunction, false);} else if (el.attachEvent) { el.attachEvent("onmouseover", myFunction); el.attachEvent("onmouseout", myFunction);} else { el.onmouseover = myFunction; el.onmouseout = myFunction;}

Used to be painful, slow and ugly!

Page 22: Jacob Waller: Webifying Titanium Development

Web development

Is now pleasant, quick and sexy!

$(el).bind("mouseover mouseout", myFunction);

Page 23: Jacob Waller: Webifying Titanium Development

Ecosystem

Page 24: Jacob Waller: Webifying Titanium Development

Titanium development

Used to be somewhat painful, slow and ugly!

var tabGroup = Ti.UI.createTabGroup(), win1 = Ti.UI.createWindow({ backgroundColor: '#ccc', barColor: '#00a', title: 'My window' }), tab1 = Ti.UI.createTab({ icon: 'path/to/my/icon', title: 'My tab', window: win1 }), label1 = Ti.UI.createLabel({ text: 'Hello world!', textAlign: 'center', color: '#333',

shadowColor: '#fff', shadowOffset: { y: -1, x: 0 }, font: { fontSize: 20, fontWeight: 'bold' } });win1.add(label1);label1.addEventListener('click', function(e){ alert('You clicked me!');});tabGroup.addTab(tab1);tabGroup.open();

Page 25: Jacob Waller: Webifying Titanium Development

Welcome Kranium

http://flic.kr/p/9wLZkJ!

Page 26: Jacob Waller: Webifying Titanium Development

Titanium development

Is now more pleasant, quick and sexy!

K({ type: 'tabgroup', tabs: [{ cls: 'myTab', window: { cls: 'myWindow', children: [{ text: 'Hello world!', cls: 'mylabel', click: function(){ alert('You clicked me!'); } }] } }]}).open();

Page 27: Jacob Waller: Webifying Titanium Development

Titanium development

Is now more pleasant, quick and sexy!

.myTab { icon: path/to/my/icon; }window { background-color: #ccc; bar-color: #00a;}.myLabel { text-align: center; color: #333; shadow-color: #fff; shadow-offset-y: -1; font-size: 20; font-weight: bold;}

Page 28: Jacob Waller: Webifying Titanium Development

Titanium development

With lots of possibilities!

K( type: "tabgroup" tabs: [ className: "myTab" window: className: "myWindow" children: [ text: "Hello world!" className: "mylabel" ] ]).open()

.myTab icon path/to/my/iconwindow background-color #ccc bar-color #00a.myLabel text-align center color #333 shadow-color #fff shadow-offset-y -1 font-size 20 font-weight bold

Stylus

Page 29: Jacob Waller: Webifying Titanium Development

Kranium "   Lovechild of the following stunning web frameworks:!

"   jQuery / Zepto!

"   Backbone!

"   Jade!

"   Livetanium / Livereload!

"   Sizzle / mini.js!

"   Jasmine!

"   JSS / Stylus / Sass / LESS!

"   JSConsole / Weinre!

http://bit.ly/3vVcI!

Page 30: Jacob Waller: Webifying Titanium Development

Comparison

Page 31: Jacob Waller: Webifying Titanium Development

jQuery / Zepto

"   Easy access selector engine!

$('.content > .label, .hello').text('hello!');$(el).find('.content');$('.content', el);

Page 32: Jacob Waller: Webifying Titanium Development

jQuery / Zepto

"   Chainable collections with helper functions!

$(el) .text('hey') .css({ color: '#f00' }) .parent('.row') .bind('click', onClick) .append(stuff);

Page 33: Jacob Waller: Webifying Titanium Development

jQuery / Zepto

"   Simplified API:s!

$.ajax({ type: 'GET', url: 'http://some/url', success: function(data, status, xhr){ alert(data); }});

Page 34: Jacob Waller: Webifying Titanium Development

Titanium

"   Let’s see how these look in the low-level Titanium API!

Page 35: Jacob Waller: Webifying Titanium Development

Titanium

"   Easy access selector engine?!

N/A

Page 36: Jacob Waller: Webifying Titanium Development

Titanium

"   Chainable collections with helper functions?!

el.text = 'hey';el.color = '#f00';var parent = el.getParent().getParent().children().filter(function(el){ return /(^|\s+)row(\s+|$)/.test(el.className);});parent.addEventListener('click', onClick);stuff.forEach(function(toAdd){ el.add(toAdd);});

Page 37: Jacob Waller: Webifying Titanium Development

Titanium

"   Simplified API:s?!

var xhr = Ti.Network.createHTTPClient();xhr.open('GET', 'http://some/url');xhr.onload = function(data, status, xhr){ alert(data);});xhr.send();

Page 38: Jacob Waller: Webifying Titanium Development

Kranium

"   Lets look at the same functionality using Kranium!

Page 39: Jacob Waller: Webifying Titanium Development

Kranium

"   Easy access selector engine!

$('.content > .label, .hello').text('hello!');$(el).find('.content');$('.content', el);

Page 40: Jacob Waller: Webifying Titanium Development

Kranium

"   Chainable collections with helper functions!

$(el) .text('hey') .css({ color: '#f00' }) .parent('.row') .bind('click', onClick) .append(stuff);

Page 41: Jacob Waller: Webifying Titanium Development

Kranium

"   Simplified API:s!

$.ajax({ type: 'GET', url: 'http://some/url', success: function(data, status, xhr){ alert(data); }});

Page 42: Jacob Waller: Webifying Titanium Development

Kranium

"   Tries to invent as few wheels as possible!

"   Instead piggyback on the ideas and momentum of existing great web frameworks!

http://bit.ly/bW1zP5!

Page 43: Jacob Waller: Webifying Titanium Development

What to piggyback? "   jQuery / Zepto!

"   Backbone!

"   Jade!

"   Livetanium / Livereload!

"   Sizzle / mini.js!

"   Jasmine!

"   JSS / Stylus / Sass / LESS!

"   JSConsole / Weinre!http://flic.kr/p/7dpmyF!

Page 44: Jacob Waller: Webifying Titanium Development

What IS Kranium?

"   A utility library to include in your app!

"   A command line program!

Page 45: Jacob Waller: Webifying Titanium Development

Utility library

"   Exposes a jQuery-like object called K (or $)!

"   Exposes Backbone integration!

"   Exposes Jade template engine!

"   Implements simple selector engine!

"   Implements enhanced styling!

"   Implements extendable modules!

Page 46: Jacob Waller: Webifying Titanium Development

Command line program

"   Built on NodeJS and NPM!

"   Initiates Kranium resources in project!

"   Pipes live updates!

"   Two-way console!

"   Jasmine reporter!

Page 47: Jacob Waller: Webifying Titanium Development

Template engine

"   DRY!

"   separated!

"   consise!

A great template engine is a huge help in keeping your code:!

Page 48: Jacob Waller: Webifying Titanium Development

Jade "   Lightweight!

"   Supports custom compilers!

"   Compiles templates to functions!

"   Beautiful syntax!

"   Consise!

"   In active development!

Page 49: Jacob Waller: Webifying Titanium Development

Jade example

Page 50: Jacob Waller: Webifying Titanium Development

// test.jadeview.board label.boardTitle Board view.boardMessages - each msg, user in users label.boardMessage= user + ' says ' + msg

Page 51: Jacob Waller: Webifying Titanium Development

K.jade('test.jade', { users: { jacob: 'yeah', david: 'what', conny: 'hi', aida: 'hello', calle: 'yup' }});

Page 52: Jacob Waller: Webifying Titanium Development

.board { top: 10; left: 10;}

.boardMessages { top: 30; layout: vertical;}

.boardMessage { height: 20; top: 10;}

.boardTitle { top: 0; height: auto; font-weight: bold;}

Page 53: Jacob Waller: Webifying Titanium Development

JSS

"   Great feature in theory - gives Separation of Concerns!

"   Hasn’t always been working well !

"   Not powerful and extendable enough!

Page 54: Jacob Waller: Webifying Titanium Development

KSS "   A styling layer implemented in the javascript

context!

"   Everything created using K function is styled appropriately!

"   Style based on Types, Classes and IDs!

"   Platform branching using psuedo selectors!

"   Variable evaluation!

Page 55: Jacob Waller: Webifying Titanium Development

KSS

label { color: #000; font-size: 16dp;}label:android { font-size: 17dp; text-align: left;}tableview:ios { style: Ti.UI.iPhone.TableViewStyle.GROUPED;}

Page 56: Jacob Waller: Webifying Titanium Development

KUI

"   Extendable UI Modules!

"   Simple Inheritance!

"   Automatic KSS loading!

http://flic.kr/p/6a3wzw!

Page 57: Jacob Waller: Webifying Titanium Development

Example

exports.Class = Label.extend({ className: "loginstatus", init: function(opts) { this.events = { app: { authchange: this.updateStatus.bind(this) } }; this._super.call(this, opts); this.updateStatus(); }, updateStatus: function(e) { this.el.text = "Logged " + (e && e.loggedIn ? "in" : "out"); }});

kui/loginstatus.js!

Page 58: Jacob Waller: Webifying Titanium Development

Example

.loginstatus { color: #f00;}

kui/loginstatus.kss!

Page 59: Jacob Waller: Webifying Titanium Development

Example

K({ type: 'window', children: [{ type: 'loggedinstatus' }]}).open();var i = 0;setInterval(function(){ Ti.App.fireEvent('authchange', { loggedIn: !!(++i % 2) });}, 1000);

app.js!

Page 60: Jacob Waller: Webifying Titanium Development

Example

K({ type: 'window', children: [{ top: 10, type: 'loggedinstatus' }, { bottom: 10, type: 'loggedinstatus' }]}).open();var i = 0;setInterval(function(){ Ti.App.fireEvent('authchange', { loggedIn: !!(++i % 2) });}, 1000);

app.js!

Page 61: Jacob Waller: Webifying Titanium Development

Backbone supplies structure to JavaScript-heavy

applications by providing models with key-value binding and custom events, collections with a rich

API of enumerable functions and views with declarative event handling...

Page 62: Jacob Waller: Webifying Titanium Development
Page 63: Jacob Waller: Webifying Titanium Development

Code walkthrough

Page 64: Jacob Waller: Webifying Titanium Development

// Define modelRowModel = Backbone.Model.extend({ type: 'tableviewrow'});// Define collectionRowCollection = Backbone.Collection.extend({ model: RowModel, comparator: function(model) { return model.get("title"); }});// Create todos collectiontodos = new RowCollection();todos.add([ { title: "An example todo" }, { title: "Another example todo" },]);// Create todolistvar todolist = K.create({ type: 'todolist', collection: todos});

Page 65: Jacob Waller: Webifying Titanium Development

// kui/todolist.jsexports.Class = BackboneView.extend({ type: 'tableview', editable: true, events: { click: function(e){ var model = todos.getByCid(e.rowData._modelCid); model.set({ hasCheck: !model.get('hasCheck') }); }, "delete": function(e){ var model = todos.getByCid(e.rowData._modelCid); todos.remove(model); } }});

Page 66: Jacob Waller: Webifying Titanium Development

exports.Class = Window.extend({ navBarHidden: true, init: function(o){

this.titleLabel = K.createLabel({ className: 'titleLabel' }); todos.bind('all', this.updateTitleLabel.bind(this)); this.updateTitleLabel();

this.children = [{ type: 'toolbar', className: 'todoToolbar', items: [{ type: 'textfield', className: 'todoInputTextField', events: { "return": function(e){ todos.add({ title: e.value }); } } }, 'spacer', this.titleLabel] }, todolist];

this._super(o); },

updateTitleLabel: function(){ var completed = todos.filter(function(m){ return m.get('hasCheck') }).length; this.titleLabel.text = completed + ' / ' + todos.length + ' todos'; }});

Page 67: Jacob Waller: Webifying Titanium Development
Page 68: Jacob Waller: Webifying Titanium Development

Polyfill missing UI "   Android lacks many simple UI modules!

"   Navbar!

"   TabbedBar!

"   ButtonBar!

"   Toolbar!

"   Extendable TabBar"

"   Kranium implements these!

Page 69: Jacob Waller: Webifying Titanium Development

Polyfill missing UI

Page 70: Jacob Waller: Webifying Titanium Development

Polyfill missing UI

Page 71: Jacob Waller: Webifying Titanium Development

Extend Base UI

K.createTableview({ pullToRefresh: true, refresh: function(){ K.ajax({ url: 'http://example.com/service.json', success: this.render }); }, render: function(data){ this.setData(data.rows.map(this.createRow)); }, createRow: function(o){ return K.createTableViewRow({ title: o.name }); }});

Page 72: Jacob Waller: Webifying Titanium Development

Livetanium

"   Kranium integrates Livetanium!

"   Gives you live updates of KSS style changes as well as module updates!

Page 73: Jacob Waller: Webifying Titanium Development
Page 74: Jacob Waller: Webifying Titanium Development

Jasmine

describe('Demo', function() { describe('Titanium Object', function(){ it('Ti == Titanium', function(){ expect(Titanium).toEqual(Ti); }); it('Ti.App', function(){ expect(Titanium).toBeDefined(); }); }); describe('TabGroup', function(){ it('Has tabgroup', function(){ expect(K('tabgroup').length).toBeGreaterThan(0); }); it('TabGroup.activeTab.title === "test"', function(){ expect(K('tabgroup').get(0).activeTab.title).toEqual("test"); }); });});

Page 75: Jacob Waller: Webifying Titanium Development
Page 76: Jacob Waller: Webifying Titanium Development

Console

Page 77: Jacob Waller: Webifying Titanium Development
Page 78: Jacob Waller: Webifying Titanium Development

Summary

"   Consists of a command line program and an includable library!

"   Ports the best web development libraries and technologies to Titanium!

"   Polyfills parts missing between platforms!

"   Helps you with your KISS:ing and keeps you DRY!

Page 79: Jacob Waller: Webifying Titanium Development

Available now

"   Currently in open beta!

"   Source under MIT License!

"   Hosted on GitHub!

"   Pull requests and co-maintainers welcome"

"   http://github.com/krawaller/kranium!

Page 80: Jacob Waller: Webifying Titanium Development

Available now

"   Beware!

"   There will be bugs!

"   API far from frozen!

Page 81: Jacob Waller: Webifying Titanium Development

Available now

"   Works best with iOS, but Android getting there!

"   CLI works best on Mac OSX!

"   Will be tested and fixed for Linux and Windows !

Page 82: Jacob Waller: Webifying Titanium Development

http://kraniumjs.com

Page 83: Jacob Waller: Webifying Titanium Development

Installation

"   1. Install NodeJS and NPM!

"   2. Run `npm install kranium`!

"   3. There is no step 3!

Page 84: Jacob Waller: Webifying Titanium Development

Questions?

http://flic.kr/p/7vB7fR!

Page 85: Jacob Waller: Webifying Titanium Development

+

Thank you

@[email protected]!

[email protected]!

Page 86: Jacob Waller: Webifying Titanium Development

Go contribute please!

http://flic.kr/p/9C7DZZ!