Jacob Waller: Webifying Titanium Development

  • 1,726 views
Uploaded on

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 …

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.

More in: Technology , Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,726
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
29
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Kranium  Webifying  Titanium  Development   Jacob  Waller  
  • 2. +! +! +! →!
  • 3. +
  • 4. http://flic.kr/p/9wLZkJ! Kranium•  Webifying Titanium Development!
  • 5. "  Cross platform apps using javascript!"  Shared business logic!"  Native UI!"  Device API:s!
  • 6. Why cross-platform?"  One codebase! "  Faster development → cheaper development! "  Less code → less bugs! "  Focus on one language and one tool!
  • 7. 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!
  • 8. Cross Platform is Hard "  iOS! "  Android! "  Objective-C! "  Java! "  XCode! "  Eclipse!
  • 9. Titanium takes the hit http://flic.kr/p/91Zydu!
  • 10. Cross Platform Medicine http://flic.kr/p/8dZbk4!"  Must use lowest common denominator!"  Go with a low-level API!"  Must focus on getting the “atoms” behave the same across platforms!
  • 11. Low-level http://flic.kr/p/75b2DJ!Means powerful!
  • 12. Low-level http://flic.kr/p/5JDvZM!Also means annoying to build large stuff!
  • 13. Low-level http://flic.kr/p/nyxCW!Is it therefore wrong?!
  • 14. NO
  • 15. High-level"  Low level building blocks let us build high- level abstractions!"  Upon which we can build awesome stuff!
  • 16. High-level http://flic.kr/p/8ovJYH!
  • 17. 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!
  • 18. But how? http://flic.kr/p/9wfuUh!
  • 19. Parallel"  Web development has low-level API:s! "  document.createElement! "  element.style.backgroundColor!
  • 20. Web developmentif (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!
  • 21. Web development $(el).bind("mouseover mouseout", myFunction); Is now pleasant, quick and sexy!
  • 22. Ecosystem
  • 23. Titanium developmentvar tabGroup = Ti.UI.createTabGroup(), shadowColor: #fff, shadowOffset: { win1 = Ti.UI.createWindow({ y: -1, backgroundColor: #ccc, x: 0 barColor: #00a, }, title: My window font: { }), fontSize: 20, fontWeight: bold tab1 = Ti.UI.createTab({ } icon: path/to/my/icon, }); title: My tab, window: win1 win1.add(label1); }), label1.addEventListener(click, function(e){ alert(You clicked me!); label1 = Ti.UI.createLabel({ }); text: Hello world!, textAlign: center, tabGroup.addTab(tab1); color: #333, tabGroup.open(); Used to be somewhat painful, slow and ugly!
  • 24. Welcome Kranium http://flic.kr/p/9wLZkJ!
  • 25. Titanium development K({ type: tabgroup, tabs: [{ cls: myTab, window: { cls: myWindow, children: [{ text: Hello world!, cls: mylabel, click: function(){ alert(You clicked me!); } }] } }] }).open(); Is now more pleasant, quick and sexy!
  • 26. Titanium development .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; } Is now more pleasant, quick and sexy!
  • 27. Titanium development StylusK( .myTab type: "tabgroup" icon path/to/my/icon tabs: [ className: "myTab" window window: background-color #ccc className: "myWindow" bar-color #00a children: [ text: "Hello world!" .myLabel className: "mylabel" text-align center ] color #333 ] shadow-color #fff ).open() shadow-offset-y -1 font-size 20 font-weight bold With lots of possibilities!
  • 28. Kranium"  Lovechild of the following stunning web frameworks:! "  jQuery / Zepto! "  Backbone! "  Jade! "  Livetanium / Livereload! "  Sizzle / mini.js! "  Jasmine! http://bit.ly/3vVcI! "  JSS / Stylus / Sass / LESS! "  JSConsole / Weinre!
  • 29. Comparison
  • 30. jQuery / Zepto"  Easy access selector engine! $(.content > .label, .hello).text(hello!); $(el).find(.content); $(.content, el);
  • 31. jQuery / Zepto"  Chainable collections with helper functions! $(el) .text(hey) .css({ color: #f00 }) .parent(.row) .bind(click, onClick) .append(stuff);
  • 32. jQuery / Zepto"  Simplified API:s! $.ajax({ type: GET, url: http://some/url, success: function(data, status, xhr){ alert(data); } });
  • 33. Titanium"  Let’s see how these look in the low-level Titanium API!
  • 34. Titanium"  Easy access selector engine?! N/A
  • 35. 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); });
  • 36. 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();
  • 37. Kranium"  Lets look at the same functionality using Kranium!
  • 38. Kranium"  Easy access selector engine! $(.content > .label, .hello).text(hello!); $(el).find(.content); $(.content, el);
  • 39. Kranium"  Chainable collections with helper functions! $(el) .text(hey) .css({ color: #f00 }) .parent(.row) .bind(click, onClick) .append(stuff);
  • 40. Kranium"  Simplified API:s! $.ajax({ type: GET, url: http://some/url, success: function(data, status, xhr){ alert(data); } });
  • 41. Kranium http://bit.ly/bW1zP5!"  Tries to invent as few wheels as possible!"  Instead piggyback on the ideas and momentum of existing great web frameworks!
  • 42. What to piggyback? "  jQuery / Zepto! "  Backbone! "  Jade! "  Livetanium / Livereload! "  Sizzle / mini.js! "  Jasmine! "  JSS / Stylus / Sass / LESS! http://flic.kr/p/7dpmyF! "  JSConsole / Weinre!
  • 43. What IS Kranium?"  A utility library to include in your app!"  A command line program!
  • 44. 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!
  • 45. Command line program "  Built on NodeJS and NPM! "  Initiates Kranium resources in project! "  Pipes live updates! "  Two-way console! "  Jasmine reporter!
  • 46. Template engineA great template engine is a hugehelp in keeping your code:!"  DRY!"  separated!"  consise!
  • 47. Jade"  Lightweight!"  Supports custom compilers!"  Compiles templates to functions!"  Beautiful syntax!"  Consise!"  In active development!
  • 48. Jade example
  • 49. // test.jade view.board label.boardTitle Board view.boardMessages - each msg, user in users label.boardMessage= user + says + msg
  • 50. K.jade(test.jade, { users: { jacob: yeah, david: what, conny: hi, aida: hello, calle: yup } });
  • 51. .board { top: 10; left: 10; } .boardMessages { top: 30; layout: vertical; } .boardMessage { height: 20; top: 10; } .boardTitle { top: 0; height: auto; font-weight: bold; }
  • 52. JSS"  Great feature in theory - gives Separation of Concerns!"  Hasn’t always been working well !"  Not powerful and extendable enough!
  • 53. 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!
  • 54. KSSlabel { color: #000; font-size: 16dp; } label:android { font-size: 17dp; text-align: left; } tableview:ios { style: Ti.UI.iPhone.TableViewStyle.GROUPED; }
  • 55. KUI http://flic.kr/p/6a3wzw!"  Extendable UI Modules!"  Simple Inheritance!"  Automatic KSS loading!
  • 56. Examplekui/loginstatus.js! 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"); } });
  • 57. Examplekui/loginstatus.kss! .loginstatus { color: #f00; }
  • 58. Exampleapp.js! K({ type: window, children: [{ type: loggedinstatus }] }).open(); var i = 0; setInterval(function(){ Ti.App.fireEvent(authchange, { loggedIn: !!(++i % 2) }); }, 1000);
  • 59. Exampleapp.js! 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);
  • 60. Backbone supplies structure to JavaScript-heavyapplications by providing models with key-valuebinding and custom events, collections with a richAPI of enumerable functions and views withdeclarative event handling...
  • 61. Code walkthrough
  • 62. // Define model RowModel = Backbone.Model.extend({ type: tableviewrow }); // Define collection RowCollection = Backbone.Collection.extend({ model: RowModel, comparator: function(model) { return model.get("title"); } }); // Create todos collection todos = new RowCollection(); todos.add([ { title: "An example todo" }, { title: "Another example todo" }, ]); // Create todolist var todolist = K.create({ type: todolist, collection: todos });
  • 63. // kui/todolist.js exports.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); } } });
  • 64. 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; } });
  • 65. Polyfill missing UI"  Android lacks many simple UI modules! "  Navbar! "  TabbedBar! "  ButtonBar! "  Toolbar! "  Extendable TabBar""  Kranium implements these!
  • 66. Polyfill missing UI
  • 67. Polyfill missing UI
  • 68. 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 }); } });
  • 69. Livetanium"  Kranium integrates Livetanium!"  Gives you live updates of KSS style changes as well as module updates!
  • 70. Jasminedescribe(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"); }); }); });
  • 71. Console
  • 72. 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!
  • 73. Available now"  Currently in open beta! "  Source under MIT License! "  Hosted on GitHub! "  Pull requests and co-maintainers welcome""  http://github.com/krawaller/kranium!
  • 74. Available now"  Beware! "  There will be bugs! "  API far from frozen!
  • 75. 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 !
  • 76. http://kraniumjs.com
  • 77. Installation"  1. Install NodeJS and NPM!"  2. Run `npm install kranium`!"  3. There is no step 3!
  • 78. Questions? http://flic.kr/p/7vB7fR!
  • 79. Thank you + @litenjacob! jacob@krawaller.se!jacob.waller@logica.com!
  • 80. Go contribute please! http://flic.kr/p/9C7DZZ!