time.zip - developing an android-ios, smartphone-tablet app in one month

43
Time.zip Developing an Android-iOS, smartphone-tablet app in one month Ivano Malavolta and Alessio d'Arielli

Upload: ivano-malavolta

Post on 07-May-2015

745 views

Category:

Technology


1 download

DESCRIPTION

Slides of the talk I gave at the HTML5 Frontend Development @L'Aquila (Italy). 13th November 2013. Abstract: Last June a customer asked us to develop and publish a mobile application for both Android and iOS platforms which could run on both smartphones and tablets. Everything's fine you may say, there was only one small issue: we had only the equivalent of one month available to complete the project. We accepted the challenge and decided to exploit web technologies and PhoneGap to build a mobile application with cross-platform, cross-device and high performance in mind right from the beginning. To make the story short: we succeded! This talk will take you through the process, decisions and technical solutions we took for achieving this strong result in such a short period of time.

TRANSCRIPT

Page 1: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Time.zipDeveloping an Android-iOS, smartphone-tablet app in one

month

Ivano Malavolta and Alessio d'Arielli

Page 2: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Ivano MalavoltaResearch fellow @University of L'Aquila

Alessio d'ArielliGraphic Designer and Web developer

Page 3: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

RoadmapApp overview

Organizational best practices

Technical best practices

Page 4: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

AppOverview

Page 5: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

The Customer

Who is Frascati ScienzaWhat kind of app they asked for

Page 6: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Stuff provided

A Storyboard (with many revisions)

Page 7: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Stuff provided

Photoshop Mockups (with many revisions too)

Page 8: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Stuff provided

Anxiety (with many emails and phone calls)

Page 9: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Technical constraintsPlatforms to support: Android 4.x & iOS 6.xDevices: Smartphone & tabletOffline supportQR code scannerVideo streamingIn-app browserNews from RSS feeds

Page 10: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Timeline

2 people, ~4 hours a day

Total working hours: ~320

(~1 month, 2 people full time)

Page 11: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

The app

More than 5000 participants to the event

The treasure hunt carried on in the center of Rome

It involved 1000 people, 150 participants

Page 12: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

OrganizationalBest

Practices

Page 13: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

1. Debug contract before the code

Ask about the operational flow, the UI / UX, the intention of

the app IMMEDIATELY. Write the whole thing in the contract.

Why? If you rework parts already completed you arespending money from your own pocket

Page 14: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

2. Web-based feasibility

If they ask to support multiple platforms, evaluate if web-

based development (PhoneGap) is feasible

Search and test any component for advanced features(in our case, QR-code scanning and child browser)

Page 15: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

3. Balance efforts

Equally divide the workload, responsibilities and testing.Notify quickly to colleagues about bugs.

Page 16: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

4. Use code repositories

Use repository for remote collaboration (SVN, git, etc.)rather than email or other methods that have no chance to

undo.

Page 17: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

5. Avoid micro-multitasking

Focus on and complete a task at time, otherwise probability

of injecting bugs is terribly high.Optimize your schedules.

Page 18: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

6. Use MVC pattern

By structuring the app with the MVC pattern, you can workin parallel on JS and frontend HTML5/CSS3

Page 19: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

7. Modularity

Max simplification of navigation and extreme modularity soany changes to the content or presentation are quickly

realizable without affecting the overall structure.

Page 20: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

8. Be reactive

Maximise reactivity and cooperation with colleagues.

Don't empower customer's anxietyresponding immediately to every request

Page 21: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

9. Organize revisions with customers

Keep the customer in the loop, arrange periodical meetingsin order to update him and to collect a list of tasks or

corrections to be made.

Page 22: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

10. Get all testing tools

Book many hours for testing (and blasphemy),

get as soon as you can as much devices as possible fortesting.

Page 23: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Summary1. Debug contract before the code

2. Web-based feasibility

3. Balance efforts

4. Use code repositories

5. Avoid micro-multitasking

6. Use MVC pattern

7. Modularity

8. Be reactive

9. Organize revisions with customers

10. Get all testing tools

Page 24: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

TechnicalBest

Practices

Page 25: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

1. First day: search and test alreadydeveloped components

Page 26: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

require.config({ paths: { jquery: '../lib/jquery/jquery-1.9.1.min', /* '../lib/jquery/zepto', */ underscore: '../lib/underscore/underscore-min', backbone: "../lib/backbone/backbone", text: '../lib/require/text-1.0.6', async: '../lib/require/async', handlebars: '../lib/handlebars/handlebars', templates: '../templates', leaflet: '../lib/leaflet/leaflet', datamanager: 'datamanager', spin: '../lib/spin/spin' }, shim: { 'jquery': { exports: '$' }, 'underscore': { exports: '_' }, 'backbone': { deps: ['jquery', 'underscore'], exports: 'Backbone' }, 'handlebars': { exports: 'Handlebars' }, 'leaflet': { exports: 'L' } }});

Once you are done, setup your boilerplate app

Page 27: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

2. Establish the software architecturefrom the beginning

It will guide the structure of your code

Page 28: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

var EnteView = Backbone.View.extend({ model: Ente,

initialize: function () { this.title = this.model.get("titolo");

},

var EventoView = Backbone.View.extend({ model: Evento, /**/ initialize: function () { var date = new Date(this.model.get("timestamp") * 1000); var gg, mm, aaaa, hours, mins; gg = date.getDate() + "/"; mm = date.getMonth() + 1 + "/"; aaaa = date.getFullYear(); hours = date.getHours(); mins = date.getMinutes(); this.title = gg + mm + aaaa + " - " + hours + ":" + mins; /**/ },

Define your own coding patterns**more patterns will show up during the presentation

Page 29: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

3. Clearly separate concerns

It makes the code more testable

More easy to extend and refine the app

It allowed us to follow a micro-process

Page 30: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

from JS developer's perspective...

I commit this after update I see this

Page 31: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Example (home view)

define([..., "text!templates/frascatiscienza.html"], /* dependency to template file */function ($, _, Backbone, Handlebars, Ente, template) { /* template contains a string now */ var FrascatiScienzaView = Backbone.View.extend({

model: Ente,

className: "default_wrapper",

events: { "touchstart #enti": "enti", "touchstart #_eventi": "eventi", "touchstart #partner": "partner", "touchstart #frascati": "continua" },

template: Handlebars.compile(template), /* template compilation, it is a function now */

render: function () { /* gestione nav bar */ this.updateNavbar(); $(this.el).html(this.template(this.model.toJSON())); /* template execution */ /* */ return this; } }); return FrascatiScienzaView;});

Page 32: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

4. Keep performance in mind from thebeginning

Avoid to fall into the fancy-framework trapUse pure JS as much as you canNo JS animation, just switch classes + CSS3transitions/transformsUse native touch events, not onClick (300ms delay)Minimize browser reflowsAvoid complex CSS selectorsTry to use id-only selectors...

Page 33: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

5. Views first, then datavar AppRouter = Backbone.Router.extend({ /* */changePage: function (page) { if (this.currentView) { this.currentView.trigger("removed"); this.currentView.remove(); } this.currentView = page; this.structureView.currentView = page; page.render(); this.structureView.$el.find("#content").append($(page.el)); this.structureView.trigger("updateTitle", page); this.currentView.trigger("inTheDom"); // here the new view can fetch data return true;}/* */

Valid especially when data is coming from the network

Page 34: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

6. Let the user forget he is looking at abrowser

@charset "UTF-8";/* STANDARD FOR MOBILE */

* { /* transparent link selection */ -webkit-tap-highlight-color: rgba(0,0,0,0);}

body { -webkit-touch-callout: none; /* no callouts during tap and hold */ -webkit-text-size-adjust: none; /* no fonts auto inflation */ -webkit-user-select: none; /* no copy and paste, etc. */ background-attachment: fixed; font-family: 'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif; height: 100%; margin: 0px; padding: 0px; width: 100%;}

#mainContainer { /* get the whole display */ position: absolute; height: 100%; width: 100%; margin: 0px; padding: 0px; left: 0; top: 0;

Page 35: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

7. Minimize network access// We launch the Apprequire(['underscore', 'backbone', 'spin', 'router', 'datamanager'], function (_, Backbone, Spinner, AppRouter, Data) {

String.prototype.endsWith = function (suffix) { return this.indexOf(suffix, this.length - suffix.length) !== -1; };

String.prototype.strip = function () { return this.replace(/(<([̂>]+)>)/ig, "").replace(/(<([̂>]+)>)/ig, ""); };

document.addEventListener("deviceready", run, false);

function run() { Data.initialize();

/* */ } }); Try to prefetch data as much as possible

If some data is always the same, bundle it into the app

Page 36: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

8. Take special care of imagesAvoid to resize images (both via CSS and JS)Be robust w.r.t. 404 errors

Show a spinner in place of an image while it is loading

/* in the template */<img src="{{ immagine }}" onerror="ImgError(this);">

/* in your JS */function ImgError(source){ empty1x1png = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII=" source.src = "data:image/png;base64," + empty1x1png; source.onerror = ""; return true;}

.heavyImg { background: url('../res/loader.gif') no-repeat; background-position: center; min-height: 20%; width: 100%;}

Page 37: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

9. When it's simple, leave it simpleDon't overelaborate. Complexity will come by itself.

goBack: function (self) { var that = (self instanceof StructureView) ? self : this; if (!that.currentView) { return false; } if (that.currentView instanceof IntroTappaView) { return false; } if (that.currentView instanceof DomandaCacciaView) { return false; } if (that.currentView instanceof RisultatoCacciaView) { Backbone.history.navigate("introcaccia", {trigger: true}); return false; } if (that.currentView instanceof FineCacciaView) { Backbone.history.navigate("caccia", {trigger: true}); return false; } window.history.back();}

ANTIPATTERN ABOVE

Page 38: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

10. Test, debug, test, debug

In this context, your desktop browser is the killer app!

Check consoleBreakpointsUpdate the DOM at run-timeAccess to all local DBsNetwork profilingCPU and memory profilingMonitor event listenersMonitor elements’ rendering time

Page 39: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Summary1. First day: search and test already developed components

2. Establish the software architecture from the beginning

3. Clearly separate concerns

4. Keep performance in mind from the beginning

5. Views first, then data

6. Let the user forget he is looking at a browser

7. Minimize network access

8. Take special care of images

9. When it's simple, leave it simple

10. Test, debug, test, debug

Page 40: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

ConclusionsWe extracted a set of organizational and technical bestpractices from a true story

In any case, step zero to success is to be technologicallyready

for example, many people tend to underestimate JavaScript, don't!

Page 41: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

BonusAn RSS reader in 20 lines of pure JavaScript ;)

define(["jquery", "underscore", "backbone", "models/Rss"], function ($, _, Backbone, Rss) {

var RssList = Backbone.Collection.extend({

model: Rss,

populate: function (feedUrl, view) { var xmlhttp = new XMLHttpRequest(); var self = this; xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { var feed = xmlhttp.responseXML; var news = feed.getElementsByTagName("item"); var title, description, link; for (var i = 0; i news.length; i++) { title = news[i].getElementsByTagName("title")[0].textContent.strip description = news[i].getElementsByTagName("description")[0].textContent link = news[i].getElementsByTagName("link")[0].textContent.strip if (title && description && link) { self.create({ title: title, description: description, link: link }); }

Page 42: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Ivano MalavoltaResearch fellow

[email protected]

www.ivanomalavolta.com

@IMalavolta

github.com/iivanoo

Page 43: Time.zip - Developing an Android-iOS, smartphone-tablet app in one month

Alessio d'ArielliGraphic Designer and Web developer

[email protected]

www.alessiodarielli.com