Cross-Platform Mobile Apps 05. Juni 2013
Martin Wittemann Master of Science (2009) Arbeitet bei 1&1 Internet AG Head of Frameworks & Tooling Tech Lead von qooxdoo
Plattformen Java ME 12 % Rest 7 % Android 26 % ios 55 % Mobile-Phone + Tablet, Stand: 21.05.2013, Quelle: http://netmarketshare.com/operating-system-market-share.aspx?qprid=8&qpcustomd=1&qpct=3
Plattformen Java ME 12 % Rest 7 % ios & Andoid 81 % Mobile-Phone + Tablet, Stand: 21.05.2013, Quelle: http://netmarketshare.com/operating-system-market-share.aspx?qprid=8&qpcustomd=1&qpct=3
Plattformen
Plattformen Objective-C Java
Plattformen Webtechnologien
Plattformen Webtechnologien
Webtechnologien HTML JAVASCRIPT CSS
Mobile Apps Device API / App Stores Cross-Platform
Mobile Apps Device API / App Stores Native Apps Cross-Platform
Mobile Apps Device API / App Stores Native Apps Mobile Website Cross-Platform
Mobile Apps Device API / App Stores Native Apps Hybrid Apps Mobile Website Cross-Platform
Mobile Apps Device API / App Stores Native Apps Hybrid Apps Mobile Website Cross-Platform
Native Entwicklung SDK Code Test Build SDK Code Test Build
Webtechnologien Build SDK Code Test Build
Webtechnologien SDK Code Test Build Build Build Build Build...
Herausforderungen Programmierung der Oberfläche
Programmierung der Oberfläche Normal: Pressed:
Programmierung der Oberfläche <!DOCTYPE html> <html> <head> <style type="text/css" media="screen">.button { -webkit-border-radius: 8px; -moz-border-radius: 8px; border-radius: 8px; border: 1px solid #B4B4B4; background-color: white; color: #666; cursor: pointer; font-weight: 700; text-align: center; padding: 2px 20px; margin-top: 4px; height: 30px; width: auto; line-height: 30px; font-size: 15px; font-family: Helvetica; } Normal: Pressed:.button:active { background-image:-webkit-gradient(linear,center top,center bottom,from( #4583fd),to(#194ae4)); background-image:-webkit-linear-gradient(top, #4583fd, #194ae4); background-image:-moz-linear-gradient(top, #4583fd, #194ae4); background-image:linear-gradient(to bottom, #4583fd, #194ae4); color:#fff } </style> </head> <body> <div class="button">button</div> </body> </html>
Herausforderungen Programmierung der Oberfläche Cross-Browser Unterschiede
Cross-Browser Unterschiede
Cross-Browser Unterschiede! Unterschiedliche Versionen können zu unterschiedlichen Bugs / Feature-Sets führen [1] Quelle: http://caniuse.com/#feat=transforms3d
Cross-Browser Unterschiede! Unterschiedliche Versionen können zu unterschiedlichen Bugs / Feature-Sets führen Beispiel 3D Transforms Unterstützt von ios und ab Android 3.0 [1] Feature Checks zur Laufzeit --> zukunftssicher [1] Quelle: http://caniuse.com/#feat=transforms3d
Cross-Browser Unterschiede! Unterschiedliche Versionen können zu unterschiedlichen Bugs / Feature-Sets führen Beispiel 3D Transforms Unterstützt von ios und ab Android 3.0 [1] Feature Checks zur Laufzeit --> zukunftssicher [1] Quelle: http://caniuse.com/#feat=transforms3d
Herausforderungen Programmierung der Oberfläche Cross-Browser Unterschiede Probleme mit dem Scrolling
Scrolling-Probleme fix beweglich fix
Scrolling-Probleme fix beweglich fix
Scrolling-Probleme fix beweglich fix position: fixed bzw. overflow: scroll
Scrolling-Probleme fix beweglich fix position: fixed bzw. overflow: scroll! Natives scrolling ab ios 5.0 und Android 3.0 [1] [1] Quelle: http://caniuse.com/#feat=css-fixed
Herausforderungen Programmierung der Oberfläche Cross-Browser Unterschiede Probleme mit dem Scrolling Beschränkter Zugriff auf die Hardware Keine Distribution über die AppStores
PhoneGap
PhoneGap Verpacken
PhoneGap Verpacken Installieren
Herausforderungen Programmierung der Oberfläche Cross-Browser Unterschiede Probleme mit dem Scrolling Beschränkter Zugriff auf die Hardware Keine Distribution über die AppStores
Frameworks qooxdoo
Frameworks qooxdoo Cross-Browser Kompatibilität Umfangreiche Widget-Sets Vorgefertigte Themes Scrolling via iscroll Eigene Scrolling-Lösung - Natives Scrolling LGPL / EPL - GPL / Commercial MIT
qooxdoo Mobile Beispiel JavaScript var page = new qx.ui.mobile.page.navigationpage(); page.settitle("hello World"); page.addlistener("initialize", function() { var button = new qx.ui.mobile.form.button("button"); button.addlistener("tap", function() { alert("hello World"); }); page.getcontent().add(button); });
Sencha-Touch Beispiel JavaScript Ext.define('Button.view.Main', { extend: 'Ext.Container', xtype: 'main', requires: ['Ext.TitleBar' ], config: { items: [{ title: 'Welcome', items: [{ docked: 'top', xtype: 'titlebar', title: 'Hello World' }, { title : 'Button', items : { xtype : 'button', text : 'Button', margin: 10, handler: function () { alert("hello World"); } } }] } ] } });
jquery-mobile Beispiel HTML <div data-role="header" data-position="fixed"> <h1>hello World</h1> </div> <a id="button" href="#" data-role="button" style="margin: 10px;"> Button </a> JavaScript $("#button").on("tap", function() { alert("hello World"); });
Widgets
Vordefinierte Themes ios Android Custom
Entwicklung Objekt-Orientierung Data-Binding Entwicklungsumgebung Tooling
Objekt-Orientierung qooxdoo qx.class.define("bicycle", { extend : Vehicle, members : { speed : 0, speedup : function(increment) { this.speed += increment; } } }); class Bicycle extends Vehicle { } int speed = 0; void speedup(int increment) { speed += increment; }
Objekt-Orientierung
Data-Binding Model View
Data-Binding Model binding View
Data-Binding Model binding View
Data-Binding Webservice Store Model binding
Data-Binding Webservice load Store Model binding
Data-Binding Webservice load Store create Model binding
Data-Binding JSON-P Service Mobile-List clb([{!! 'date': '2013-04-21',!! 'time': '11:00:00',!! 'hometeam': 'Ladenburg',!! 'awayteam': 'Bretten',!! 'homescore': '26',!! 'awayscore': '19'! },{!! 'date': '2013-04-28',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Villingendorf',!! 'homescore': '19',!! 'awayscore': '8'! },{!! 'date': '2013-05-05',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Freiburg',!! 'homescore': '24', Data-Binding
Data-Binding JSON-P Service clb([{!! 'date': '2013-04-21',!! 'time': '11:00:00',!! 'hometeam': 'Ladenburg',!! 'awayteam': 'Bretten',!! 'homescore': '26',!! 'awayscore': '19'! },{!! 'date': '2013-04-28',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Villingendorf',!! 'homescore': '19',!! 'awayscore': '8'! },{!! 'date': '2013-05-05',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Freiburg',!! 'homescore': '24', Data-Binding var store = new qx.data.store.jsonp(url); // View var page = new qx.ui.mobile.page.navigationpage(); page.addlistener("initialize", function() { var list = new qx.ui.mobile.list.list({ configureitem : function(item, data, row) { } }); Mobile-List item.settitle( data.gethometeam() + " vs. " + data.getawayteam() ); store.bind("model", list, "model"); page.getcontent().add(list); });
Data-Binding JSON-P Service clb([{!! 'date': '2013-04-21',!! 'time': '11:00:00',!! 'hometeam': 'Ladenburg',!! 'awayteam': 'Bretten',!! 'homescore': '26',!! 'awayscore': '19'! },{!! 'date': '2013-04-28',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Villingendorf',!! 'homescore': '19',!! 'awayscore': '8'! },{!! 'date': '2013-05-05',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Freiburg',!! 'homescore': '24', Data-Binding var store = new qx.data.store.jsonp(url); // View var page = new qx.ui.mobile.page.navigationpage(); page.addlistener("initialize", function() { var list = new qx.ui.mobile.list.list({ configureitem : function(item, data, row) { } }); Mobile-List item.settitle( data.gethometeam() + " vs. " + data.getawayteam() ); store.bind("model", list, "model"); page.getcontent().add(list); });
Data-Binding JSON-P Service clb([{!! 'date': '2013-04-21',!! 'time': '11:00:00',!! 'hometeam': 'Ladenburg',!! 'awayteam': 'Bretten',!! 'homescore': '26',!! 'awayscore': '19'! },{!! 'date': '2013-04-28',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Villingendorf',!! 'homescore': '19',!! 'awayscore': '8'! },{!! 'date': '2013-05-05',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Freiburg',!! 'homescore': '24', Data-Binding var store = new qx.data.store.jsonp(url); // View var page = new qx.ui.mobile.page.navigationpage(); page.addlistener("initialize", function() { var list = new qx.ui.mobile.list.list({ configureitem : function(item, data, row) { } }); Mobile-List item.settitle( data.gethometeam() + " vs. " + data.getawayteam() ); store.bind("model", list, "model"); page.getcontent().add(list); });
Data-Binding JSON-P Service clb([{!! 'date': '2013-04-21',!! 'time': '11:00:00',!! 'hometeam': 'Ladenburg',!! 'awayteam': 'Bretten',!! 'homescore': '26',!! 'awayscore': '19'! },{!! 'date': '2013-04-28',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Villingendorf',!! 'homescore': '19',!! 'awayscore': '8'! },{!! 'date': '2013-05-05',!! 'time': '15:00:00',!! 'hometeam': 'Bretten',!! 'awayteam': 'Freiburg',!! 'homescore': '24', Data-Binding var store = new qx.data.store.jsonp(url); // View var page = new qx.ui.mobile.page.navigationpage(); page.addlistener("initialize", function() { var list = new qx.ui.mobile.list.list({ configureitem : function(item, data, row) { } }); Mobile-List item.settitle( data.gethometeam() + " vs. " + data.getawayteam() ); store.bind("model", list, "model"); page.getcontent().add(list); });
Development JS
Development JS run
Development JS run error
Development JS run debugger
Dev Tools Settings
Tooling
Tooling create JS
Tooling create JS var x = 123; function a() { return true;
Tooling LOG Warning: x is g Warning: unused Warning:... lint create JS var x = 123; function a() { return true;
Tooling LOG Warning: x is g Warning: unused Warning:... lint create JS var x = 123; function a() { return true; test Test
Tooling LOG Warning: x is g Warning: unused Warning:... lint api API create JS var x = 123; function a() { return true; test Test
Tooling LOG Warning: x is g Warning: unused Warning:... lint api API create JS var x = 123; function a() { return true; test Test build JS var x=123;func tion a(){retur n true;}
Tooling LOG Warning: x is g Warning: unused Warning:... lint api API create JS var x = 123; function a() { return true; test Test build JS var x=123;func tion a(){retur n true;} PhoneGap App
Fazit Webtechnologien und Frameworks... sind geeignet um mobile Apps zu schreiben ermöglichen Multi-Platform-Lösungen reduzieren Entwicklungsaufwände machen Spaß!
Danke @wittemann martin.wittemann@1und1.de http://qooxdoo.org