Taking your Web App for a walk

4,629 views

Published on

What strategies can you take to bring a web application to a mobile device? Six steps from pure HTML/CSS all the way to almost native applications.

Published in: Technology, Design
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,629
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
12
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Taking your Web App for a walk

    1. 1. Taking your web app for a walk Jens-Christian Fischer soft-shake.ch 3.10.2011
    2. 2. So who‘s this guy?
    3. 3. So who‘s this guy?• I have a job: Developer & CEO
    4. 4. So who‘s this guy?• I have a job: Developer & CEO• I have a company: http://invisible.ch
    5. 5. So who‘s this guy?• I have a job: Developer & CEO• I have a company: http://invisible.ch• I have an email address: jens-christian@invisible.ch
    6. 6. So who‘s this guy?• I have a job: Developer & CEO• I have a company: http://invisible.ch• I have an email address: jens-christian@invisible.ch• I‘m on Twitter: @jcfischer
    7. 7. So who‘s this guy?• I have a job: Developer & CEO• I have a company: http://invisible.ch• I have an email address: jens-christian@invisible.ch• I‘m on Twitter: @jcfischer• I‘m on Google+: 109789939743085010576
    8. 8. http://www.flickr.com/photos/hgesell/1257717725/
    9. 9. Webhttp://www.flickr.com/photos/hgesell/1257717725/
    10. 10. iO S -C oid i ve A n dr c t b je Da OWin Ph lvi one7 Bl k ac C# kb O S er W eb ry IP ?) (R
    11. 11. What are we going to do?
    12. 12. What are we going to do?
    13. 13. 6 Steps towards mobile apps
    14. 14. 6 Steps towards mobile apps 1. HTML 5 / CSS 3
    15. 15. 6 Steps towards mobile apps 1. HTML 5 / CSS 3 2. Responsive Design
    16. 16. 6 Steps towards mobile apps 1. HTML 5 / CSS 3 2. Responsive Design 3. Offline / Local Storage
    17. 17. 6 Steps towards mobile apps 1. HTML 5 / CSS 3 2. Responsive Design 3. Offline / Local Storage 4. UI Frameworks (jQuery Mobile / Sencha)
    18. 18. 6 Steps towards mobile apps 1. HTML 5 / CSS 3 2. Responsive Design 3. Offline / Local Storage 4. UI Frameworks (jQuery Mobile / Sencha) 5. Using the device (PhoneGap)
    19. 19. 6 Steps towards mobile apps 1. HTML 5 / CSS 3 2. Responsive Design 3. Offline / Local Storage 4. UI Frameworks (jQuery Mobile / Sencha) 5. Using the device (PhoneGap) 6. Being Native (Titanium)
    20. 20. 6 Steps towards mobile apps 1. HTML 5 / CSS 3 2. Responsive Design 3. Offline / Local Storage 4. UI Frameworks (jQuery Mobile / Se 5. Using the device (PhoneGap) 6. Being Native (Titanium)
    21. 21. 1
    22. 22. CSS
    23. 23. WebKit
    24. 24. 2
    25. 25. Responsive Design
    26. 26. Responsive Design
    27. 27. CSS Media Queries@media handheld, only screen and (max-width: 1280px) { .wrapper { padding: 0; } #header { position: absolute; } #header .center { position: relative; width: 100%; } #logo { margin: 0; left: 32px; top: 8px; } #content { width: 100%; margin: 0 auto; padding: 154px 0 240px 0; } #footer { position: absolute; bottom: 0; left: 0; } }@media handheld, only screen and (max-width: 768px) { .wrapper { padding: 0; } .entry { margin-left: 0; } h1 { font-size: 1.3em; } #logo { left: 8px; top: 8px; } #useless { display: none; } #panel { display: none; } #content { padding: 154px 0 240px 0; width: 100%; height: 100%; } #footer { position: absolute; max-width: 768px; bottom: 0; left: 0; } .text { margin: 0; } }@media handheld, only screen and (max-width: 480px) { .left { float: none; margin: 0 0 0 86px; } }@media handheld, only screen and (max-width: 320px) { .left { margin: 0 0 0 8px; } }
    28. 28. http://www.alistapart.com/articles/responsive-web-design/
    29. 29. 3
    30. 30. Going Offline• Caching Files offline• Local Storage
    31. 31. Cache Manifest<!DOCTYPE HTML> CACHE MANIFEST<html manifest="/cache.manifest"> FALLBACK:<body> / /offline.html... NETWORK:</body> /tracking.cgi</html> CACHE: /clock.css /clock.js /clock-face.jpghttp://diveintohtml5.org/offline.html
    32. 32. Cache Manifest CACHE MANIFEST FALLBACK: / /offline.html NETWORK: /tracking.cgi CACHE: /clock.css /clock.js /clock-face.jpghttp://diveintohtml5.org/offline.html
    33. 33. Cache Manifest CACHE MANIFEST FALLBACK: / /offline.html If not cached, show this NETWORK: /tracking.cgi CACHE: /clock.css /clock.js /clock-face.jpghttp://diveintohtml5.org/offline.html
    34. 34. Cache Manifest CACHE MANIFEST FALLBACK: / /offline.html If not cached, show this NETWORK: /tracking.cgi Dont‘t cache CACHE: /clock.css /clock.js /clock-face.jpghttp://diveintohtml5.org/offline.html
    35. 35. Cache Manifest CACHE MANIFEST FALLBACK: / /offline.html If not cached, show this NETWORK: /tracking.cgi Dont‘t cache CACHE: /clock.css /clock.js Cache these files /clock-face.jpghttp://diveintohtml5.org/offline.html
    36. 36. Local Storage Simple Key - Value storeif (Modernizr.localstorage) { var foo = localStorage.getItem("key"); // ... localStorage.setItem("key", foo);} else { alert(No storage capabilities);} http://diveintohtml5.org/storage.html
    37. 37. More than Key-Value?
    38. 38. More than Key-Value? Web SQL Indexed DB
    39. 39. More than Key-Value? Web SQL Indexed DB
    40. 40. More than Key-Value? Web SQL Indexed DB hic sunt dracones
    41. 41. http://flickr.com/photos/glennharper/49536169/
    42. 42. how far have we come? http://flickr.com/photos/glennharper/49536169/
    43. 43. 4
    44. 44. jQuery Mobile • Shares the name with jQuery (and uses it) • HTML Code with annotations • JavaScript for functionality http://jquerymobile.com
    45. 45. Sencha Touch• Grown out of the Ext JS Framework• JavaScript Code for design• HTML is just a container http://www.sencha.com/products/touch/
    46. 46. jQuery Mobile
    47. 47. jQuery Mobile<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no"> <title>To Do List</title> <script src="../../_libs/jqm/jquery-1.6.2.min.js"></script> <script src="../../_libs/jqm/jquery.mobile-1.0b3.min.js"></script> <script src="../../_libs/persistencejs/lib/persistence.js"></script> <link href="../../_libs/jqm/jquery.mobile-1.0b3.min.css" rel="stylesheet"> <link href="../../_libs/jqm/jquery.mobile.datebox-1.0b1.min.css" rel="stylesheet"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body> <!-- Index page--> <div data-role="page" id="indexPage"> <div data-role="header" data-theme="b" data-position="fixed"> <h1>To Do List</h1> <a href="#formPage" onclick="newTask()" data-icon="plus" class="ui-btn-right">New</a> </div> <div data-role="content"> <ul class="taskList" data-role="listview" data-theme="c" id="taskList"> </ul> </div> </div> // ... lot‘s of stuff omitted </body></html>
    48. 48. jQuery Mobile<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no"> <title>To Do List</title> <script src="../../_libs/jqm/jquery-1.6.2.min.js"></script> <script src="../../_libs/jqm/jquery.mobile-1.0b3.min.js"></script> <script src="../../_libs/persistencejs/lib/persistence.js"></script> <link href="../../_libs/jqm/jquery.mobile-1.0b3.min.css" rel="stylesheet"> <link href="../../_libs/jqm/jquery.mobile.datebox-1.0b1.min.css" rel="stylesheet"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body> <!-- Index page--> <div data-role="page" id="indexPage"> <div data-role="header" data-theme="b" data-position="fixed"> Define a Page <h1>To Do List</h1> <a href="#formPage" onclick="newTask()" data-icon="plus" class="ui-btn-right">New</a> </div> <div data-role="content"> <ul class="taskList" data-role="listview" data-theme="c" id="taskList"> </ul> </div> </div> // ... lot‘s of stuff omitted </body></html>
    49. 49. jQuery Mobile<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no"> <title>To Do List</title> <script src="../../_libs/jqm/jquery-1.6.2.min.js"></script> <script src="../../_libs/jqm/jquery.mobile-1.0b3.min.js"></script> <script src="../../_libs/persistencejs/lib/persistence.js"></script> <link href="../../_libs/jqm/jquery.mobile-1.0b3.min.css" rel="stylesheet"> <link href="../../_libs/jqm/jquery.mobile.datebox-1.0b1.min.css" rel="stylesheet"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body> <!-- Index page--> <div data-role="page" id="indexPage"> <div data-role="header" data-theme="b" data-position="fixed"> <h1>To Do List</h1> Define Header <a href="#formPage" onclick="newTask()" data-icon="plus" class="ui-btn-right">New</a> </div> <div data-role="content"> <ul class="taskList" data-role="listview" data-theme="c" id="taskList"> </ul> </div> </div> // ... lot‘s of stuff omitted </body></html>
    50. 50. jQuery Mobile<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no"> <title>To Do List</title> <script src="../../_libs/jqm/jquery-1.6.2.min.js"></script> <script src="../../_libs/jqm/jquery.mobile-1.0b3.min.js"></script> <script src="../../_libs/persistencejs/lib/persistence.js"></script> <link href="../../_libs/jqm/jquery.mobile-1.0b3.min.css" rel="stylesheet"> <link href="../../_libs/jqm/jquery.mobile.datebox-1.0b1.min.css" rel="stylesheet"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body> <!-- Index page--> <div data-role="page" id="indexPage"> <div data-role="header" data-theme="b" data-position="fixed"> <h1>To Do List</h1> <a href="#formPage" onclick="newTask()" data-icon="plus" class="ui-btn-right">New</a> </div> <div data-role="content"> Define Content <ul class="taskList" data-role="listview" data-theme="c" id="taskList"> </ul> </div> </div> // ... lot‘s of stuff omitted </body></html>
    51. 51. jQuery Mobile<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no"> <title>To Do List</title> <script src="../../_libs/jqm/jquery-1.6.2.min.js"></script> <script src="../../_libs/jqm/jquery.mobile-1.0b3.min.js"></script> <script src="../../_libs/persistencejs/lib/persistence.js"></script> <link href="../../_libs/jqm/jquery.mobile-1.0b3.min.css" rel="stylesheet"> <link href="../../_libs/jqm/jquery.mobile.datebox-1.0b1.min.css" rel="stylesheet"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body> <!-- Index page--> <div data-role="page" id="indexPage"> <div data-role="header" data-theme="b" data-position="fixed"> <h1>To Do List</h1> <a href="#formPage" onclick="newTask()" data-icon="plus" class="ui-btn-right">New</a> </div> <div data-role="content"> <ul class="taskList" data-role="listview" data-theme="c" id="taskList"> </ul> </div> </div> // ... lot‘s of stuff omitted </body></html>
    52. 52. function save() { var id = $(#formPage).jqmData("id"); if (id === null) { var task = { name: $("#taskName").val(), description: $("#taskDescription").val(), completed: ($("#taskCompleted").val() === "yes"), duedate: $("#taskDuedate").data("datebox").theDate }; taskManager.addTask(task); } else { var currentTask = $("#formPage").jqmData("task"); currentTask.name($("#taskName").val()); currentTask.description($("#taskDescription").val()); currentTask.completed(($("#taskCompleted").val() === "yes")); currentTask.duedate($("#taskDuedate").data("datebox").theDate); taskManager.save(); $(#formPage).jqmData("id", null); }}
    53. 53. Sencha Touch
    54. 54. <!DOCTYPE html><html manifest="todolist.manifest"> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <title>To Do List</title> <script src="../../_libs/sencha/sencha-touch.js"></script> <link href="../../_libs/sencha/resources/css/sencha-touch.css" rel="stylesheet"> <link rel="stylesheet" href="style.css"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body></body></html>
    55. 55. <!DOCTYPE html><html manifest="todolist.manifest"> <head> <meta charset="utf-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <title>To Do List</title> <script src="../../_libs/sencha/sencha-touch.js"></script> <link href="../../_libs/sencha/resources/css/sencha-touch.css" rel="stylesheet"> <link rel="stylesheet" href="style.css"> <script src="app.js"></script> <link rel="apple-touch-icon" href="icon.png"/> <link rel="apple-touch-startup-image" href="res/img/Default.png" /> </head> <body></body></html> Define Content (?)
    56. 56. var saveButton = { id: taskFormSaveButton, text: Save, ui: confirm, handler: function () { var record = TaskList.TaskForm.getRecord(); TaskList.TaskForm.updateRecord(record); if (null === TaskList.taskStore.findRecord(id, record.id)) { TaskList.taskStore.add(record); } TaskList.taskStore.sync(); TaskList.taskStore.sort([{property: duedate, direction: ASC}]); TaskList.listPanel.refresh(); TaskList.Viewport.setActiveItem("mainlist", {type: "slide", direction: "right"}); }, scope: this };
    57. 57. var titlebar = { id: taskFormTitlebar, xtype: toolbar, title: Task Detail, items: [ cancelButton, {xtype: spacer}, saveButton] };TaskList.Viewport = new Ext.Panel({ fullscreen: true, layout: "card", style: "background-color: white", layoutOnOrientationChange: true, items: [ { id: "mainlist", xtype: "panel", layout: "card", items: TaskList.listPanel, dockedItems: toolbar }, TaskList.TaskForm] });
    58. 58. The HTML orthe JavaScript way?
    59. 59. Choose wisely
    60. 60. But is it native?
    61. 61. 5
    62. 62. Native?
    63. 63. Native?
    64. 64. Native?• Accelerometer
    65. 65. Native?• Accelerometer• Camera
    66. 66. Native?• Accelerometer• Camera• Address Book
    67. 67. Native?• Accelerometer• Camera• Address Book• ... A lot is missing!
    68. 68. PhoneGap• iOS, Android, Blackberry, Symbian, WebOS• JavaScript APIs that give access to Phones features• Native Libraries, that interface with the JavaScript API http://phonegap.com
    69. 69. • Coordinates (Position Data / Acceleration)• Accelerometer• Camera• Contacts• Files / Directories / FileTransfer• Geolocation / Compass• Media• Notification (Dialogs / Alerts)• Orientation• SMS / Telephony• Connection
    70. 70. Accessing the cameranavigator.camera.getPicture(onSuccess, onFail, { quality: 50 });function onSuccess(imageData) { var image = document.getElementById(myImage); image.src = "data:image/jpeg;base64," + imageData;}function onFail(message) { alert(Failed because: + message);}
    71. 71. Write HTML / JSrun „native“ on deviceaccess device functions
    72. 72. But we‘re still not „really“ native
    73. 73. 6
    74. 74. Titanium Appcelerator http://www.appcelerator.com/
    75. 75. Objective-C / Dalvik JavaScript BridgeiOS / Android / (BlackBerry)
    76. 76. Build applications with native componentsControl them from JavaScript var
win
=
Ti.UI.createWindow(); var
view
=
Ti.UI.createImageView({ 

image:"myimage.png", 

width:24, 

height:24 }); var
button
=
Ti.UI.createButton({ 

title:"Animate", 

width:80, 

height:40, 

bottom:10 }); button.addEventListener("click",function(){ 

view.animate({top:0,duration:500}); }); win.add(view); win.add(button); win.open();
    77. 77. Conclusion
    78. 78. use normal Web App• Leverage your HTML5 / CSS3 / JavaScript• Webkit is the new IE (which „is a good thing“)• No restrictions on content from a certain fruit company• Can go offline
    79. 79. use jQuery Mobile• most mobile web browsers• simple to use, relatively low learning curve• much HTML, some JavaScript• still in beta (actually, RC1 just came out)
    80. 80. use Sencha Touch• most mobile browsers• many different components / widgets• high learning curve• commercial and open source licenses (but free)
    81. 81. use PhoneGap• most mobile browsers• supports „any“ web app (jQuery Mobile / Sencha)• Access to some device functions• Deliver „native“ app (via AppStore)
    82. 82. use Appcelerator• iOS / Android „native“ native app (AppStore)• use all native components of device• high learning curve• Commercial developer licenses, basic functionality free
    83. 83. Want to learn more?
    84. 84. http://mobile-training.ch

    ×