Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Desarrollo de apps móvil multiplataforma

Desarrollo de apps móvil multiplataforma

Desarrollo de apps móvil multiplataforma

jmortegac

April 26, 2015
Tweet

More Decks by jmortegac

Other Decks in Programming

Transcript

  1. Web-app Hibrída Nativa Se ejecuta en navegador. HTML,CSS,Javascript Se ejecuta

    en el componente webview de cada plataforma HTML,CSS,Javascript ObjetiveC for IOS Java for Android Acceso por url Se distribuyen en el market como apps nativas Se distribuyen en el market como apps nativas Limitado acceso a HW Acceso completo a HW y API nativa mediante javascript Acceso completo a HW y API nativa Jquery Mobile  PhoneGap+JavaScript framework  Titanium iOS SDK Android SDK Rápido Rapidez depende del framework Muy Rápido Introducción
  2. PhoneGap • Phonegap es un wrapper alrededor del navegador del

    dispositivo que permite acceder a los recursos del mismo • Pertenece a Adobe • Liberado como projecto open source por la fundación apache bajo el nombre de cordova • Acualmente van por la versión 3.0 • Hay 2 formas para crear el fichero binario de la app  Entornos desarrollo para cada plataforma  PhoneGap Build • No tiene UI. Será necesario emplear alguno de los frameworks javacript (jQuery Mobile, Sencha, Backbone) http://phonegap.com/ http://www.phonegapspain.com/
  3. Configuración Android package com.phonegap.exampleapp; import android.os.Bundle; import com.phonegap.*; public class

    exampleapp extends DroidGap { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setIntegerProperty("splashscreen", R.drawable.splash); super.loadUrl(file:///android_asset/www/index.html,4000);}} Permisos AndroidManifest.xml <<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  4. Javascript Inicializar-Capturar el evento deviceready Búsqueda de contactos Geolocalización (HTML5

    || Cordova Native Geolocation) https://github.com/apache/cordova-plugin-geolocation <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <script type="text/javascript" charset="utf-8"> // Espera a cargar las librerías del API document.addEventListener("deviceready", onDeviceReady, false); </script> function onDeviceReady(){ var options = new ContactFindOptions(); options.filter = «filter»; options.multiple = true; navigator.contacts.find(["displayName","emails"], foundContacts, errorContacts, options); }); function onDeviceReady() { navigator.geolocation.getCurrentPosition(onSuccess, onError); } var geoLocation = cordova.require('cordova/plugin/geolocation'); geoLocation.getCurrentPosition(onSuccess, onError);
  5. Acceso a la cámara y galería de imágenes function takeNewImage()

    { navigator.camera.getPicture(onSuccess, onFail,{ quality: 100, targetWidth: 250, targetHeight: 250 });} function selectImageFromLibrary () { navigator.camera.getPicture(onSuccess, onFail,{ quality: 100, destinationType: Camera.DestinationType.FILE_URI, sourceType: Camera.PictureSourceType.PHOTOLIBRARY, targetWidth: 250, targetHeight: 250 });} function onSuccess(imageURI) { $('#image').attr('src', imageURI); }
  6. Check connection / Eventos function checkConnection() { var networkState =

    navigator connection.type; var states = {}; states[Connection.UNKNOWN] = 'Unknown connection'; states[Connection.ETHERNET] = 'Ethernet connection'; states[Connection.WIFI] = 'WiFi connection'; states[Connection.CELL_2G] = 'Cell 2G connection'; states[Connection.CELL_3G] = 'Cell 3G connection'; states[Connection.CELL_4G] = 'Cell 4G connection'; states[Connection.NONE] = 'No network connection'; return states[networkState]; } function onDeviceReady() { document.addEventListener("online", isOnline, false); document.addEventListener("offline", isOffline, false); }
  7. PhoneGap Build http://build.phonegap.com/ • Servicio en la nube que permite

    crear los ficheros binarios para cada plataforma a partir de un proyecto que contenga las librerías de phonegap • GitHub compatible
  8. Arquitectura data-role • data-role=”page” • data-role=”header” • data-role=”footer” • data-role=”navbar”

    • data-role=”button” • data-role=”listview” • data-role=”controlgroup” • data-role=”fieldcontain” <body> <div data-role="page" id=“pag" data-add-back-btn=”true”> <header data-role="header" data-position="fixed"> Pag. secundaria </header> <div data-role="content“> Esto es la página secundaria </div> <footer data-role="footer" data-position="fixed"> Pie </footer> </div> </body>
  9. Librerías <!– jQuery Mobile CSS --> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile- 1.3.2.min.css"

    /> <!– jQuery --> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <!– jQuery Mobile JavaScript --> <script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile- 1.3.2.min.js"></script>
  10. Transiciones y diálogos <a href="index.html" data-transition=“fade“></a> <a href="index.html" data-rel=“dialog“ data-transition="pop"></a>

    $.mobile.changePage("index.html", "fade"); $.mobile.pageLoading $('.ui-loader h1').text(„Loading');
  11. Eventos • pageinit • pagebeforeshow • pagebeforehide • pageshow •

    pagehide //Se ejecuta una vez para el documento entero $(document).ready(function() { //personalizar el mensaje que sale cuando se esperan datos AJAX $.mobile.loadingMessage = "Cargando datos" //personalizar el texto del botón para ir a la página anterior $.mobile.page.prototype.options.backBtnText = "Atrás" }) //Se ejecuta una vez para cada página $('#pagBusqueda').bind('pageinit', function() { $('#botonBuscar').click(buscar) }) // Se ejecuta antes de mostrar una página $('#pagDetalles').bind('pagebeforeshow', function() { ... })
  12. Ventajas & Desventajas Ventajas • Desarrollo rápido de interfaces. •

    Elementos de interfaz adaptado a móviles • Sintaxis sencilla. • Efectos prediseñados • Manejo de eventos. • Baja curva de aprendizaje. • Personalización del estilo visual (temas) Desventajas • Agrega peso extra a la aplicación. • Manejo complejo de CSS. • Los efectos como transiciones no funcionan fluidamente en equipos de baja gama. • Las aplicaciones más grandes pueden hacer lenta la carga por trabajar en un solo archivo. • Menos control general del código.
  13. Sencha Touch • Sencha Touch es un framework para el

    desarrollo de aplicaciones móviles centrado en WebKit • Basado en EXTJS • La apariencia es similar al de las aplicaciones nativas en Android, iOS y BlackBerry • Implementa el patrón de diseño MVC en el lado del cliente • Permite leer datos directamente a través de AJAX, JSON o la capacidad local storage de HTML5 Instalación • Descargar el SDK desde su página web • http://www.sencha.com/products/touch/download Navegadores compatibles • Basados en WebKit: Safari, Chrome, Opera,Epiphany
  14. Librerías index.html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html" charset="utf-8">

    <script src="lib/touch/sencha-touch-all.js" type="text/javascript" /> <link href="lib/touch/resources/css/sencha-touch.css" rel="stylesheet" type="text/css" /> <script src="app.js" type="text/javascript" /> </head> <body></body> </html>
  15. Arquitectura Model: Los modelos representan objetos lógicos con lo que

    trabaja nuestra aplicación, donde definiremos qué campos tiene y qué métodos actuarán sobre ellos. View: Permiten visualizar los datos en los componentes que ofrece la arquitectura. Controller: Permite interactuar con las acciones del usuario.Responde a los eventos que se producen en las vistas y manejan el traspaso de datos entre Model y Store. Store: Son colecciones de modelos, y serán utilizados por varios componentes. Profile: Permite customizar los elementos UI.
  16. MVC var App=new Ext.Application({ name: „MyApp„ //variable global }); Modelo

    Ext.regModel(„MyApp.models.MyModel', { fields: [ ] }); Vista MyApp.views.viewport = new Ext.Panel( { layout:‟fit‟ //disposición elementos }); Store MyApp.stores.MyStore= new Ext.data.Store({ model: „myModel', proxy: {} }); MyApp.views.* MyApp.controllers.* MyApp.models.* MyApp.stores.* Controlador Ext.define('MyApp.controllers.MyContoller', { extend: 'Ext.app.Controller', config: { models: [„ MyApp.models.MyModel '], stores: [' MyApp.stores.MyStore '], views: [ „MyApp.views.viewport ‟], }
  17. Proyecto –Look && Feel <!--The default Sencha Touch style--> <link

    rel="stylesheet" href="resources/css/sencha-touch.css" /> <!--The default iOS style--> <link rel="stylesheet" href="resources/css/apple.css" /> <!--The default Android style--> <link rel="stylesheet" href="resources/css/android.css" /> <!--The default BlackBerry 6 style--> <link rel="stylesheet" href="resources/css/bb6.css" />  sencha-touch.js  sencha-touch.css
  18. Ext.dataview.Model / Ext.data.Store Ext.application({ launch: function(){ Ext.define('Programming',{ extend:'Ext.data.Model', config:{ fields:['lenguaje',

    'descripcion'] } }); var datos = { dataProgramming:[ {lenguaje: 'Java', descripcion: 'Creado por Sun Microsystems'},{lenguaje: 'JavaScript', descripcion: 'Creado por Netscape '},{lenguaje: 'C++', descripcion: 'Creado por Bjarne Stroustrup'},{lenguaje: 'PHP', descripcion: 'Creado por Rasmus Lerdorf'}, ] }; var store = Ext.create('Ext.data.Store',{ model: 'Programming', autoLoad: true, getGroupString : function(record) { return record.get('lenguaje')[0]; }, sorters: ['lenguaje', 'descripcion'], data: datos, proxy:{ type: 'memory', reader:{ type: 'json', rootProperty: „dataProgramming' } } } );
  19. Ext.dataview.List Ext.Viewport.add(Ext.create('Ext.Panel', { layout:'fit', items:[{ xtype:'toolbar', docked: 'top', title: 'Lenguajes

    de programación‟}, { xtype: 'list', grouped : true, onItemDisclosure: true, onItemTap: true, store: store, itemTpl: '<strong>{lenguaje} <br/>{descripcion}</strong>' }] }));
  20. Listeners listeners:{ itemtap: function(record,index){ //index es el índice de la

    fila seleccionada //record representa el objeto //carga el registro en un formulario MyApp.views.myForm.load(record); } itemdoubletap: function(record,index){ } discloure: function(index,record){ } }
  21. Ext.Map var mapdemo = Ext.create('Ext.Map', { mapOptions : { center

    : new google.maps.LatLng(40.3908, -3.6300), zoom : 16, mapTypeId : google.maps.MapTypeId.ROADMAP, navigationControl: true, navigationControlOptions: { style: google.maps.NavigationControlStyle.DEFAULT }}, listeners: { maprender: function(comp, map) { var marker = new google.maps.Marker({ position: new google.maps.LatLng(40.3908, -3.6300), title : 'Campus UPM', map: map }); google.maps.event.addListener(marker, 'click', function() { new google.maps.InfoWindow({ content: 'Campus UPM„ }).open(map, marker); }); setTimeout(function() { map.panTo(position); }, 500);}}});
  22. Browser support / S.O/ Connection <script type="text/javascript"> if (!Ext.browser.is.WebKit) {

    alert("The current browser is unsupported.\n\nSupported browsers:\n" + "Google Chrome\n" + "Apple Safari\n" + "Mobile Safari (iOS)\n" + "Android Browser\n" + "BlackBerry Browser" ); } </script> if (Ext.os.is.Android){ Ext.Msg.alert("INFO", "Android user"); } else if (Ext.os.is.Blackberry){ Ext.Msg.alert("INFO", "Blackberry user"); } else if (Ext.os.is.iPad){ Ext.Msg.alert("INFO", "iPad user"); } else if (Ext.os.is.Windows) { Ext.Msg.alert("INFO"," Win user "); } <script type="text/javascript"> Ext.device.Connection.isOnline(); Ext.device.Connection.getType(); </script>
  23. Sencha Touch vs Jquery Mobile Sencha Touch: • API más

    potente. Todo es personalizable. • Mayor número de controles IU,transiciones y animaciones • Rendimiento en iOS es superior con respecto al resto de librerías • Patrón MVC • Mayor potencia de configuración • Mayor curva de aprendizaje. Más tiempo de desarrollo. • Se necesitan unos conocimientos más avanzados de Javascript • En iOS hay limitaciones como el acceso a la cámara y contactos Jquery Mobile: • Muy sencillo de aprender si ya se conoce jquery • Compatible con mayor número de dispositivos • No emplea ningún patrón. Es necesario utilizar otro framework como Backbone • Rendimiento suele ser inferior • No dispone de muchos controles para el diseño de la interfaz
  24. • http://backbonejs.org/ • Permite implementar la lógica a nivel de

    navegación siguiendo un patrón similar a MVC / MVVM. La vista actúa también de controlador. • Perfecto para usarlo con Jquery Mobile • Pesa muy poco(6 Kb la versión minimizada) • Dependencias:Underscore.js && (Zepto.js || JQuery.js) • Se integra con la mayoría de frameworks javascript para el manejo del DOM • LinedkIn, Soundcloud, Basecamp, Codiqa Backbone Vista HTML + CSS+ Template Controlador Backbone.View Modelo Backbone.Model Manipulación del DOM con Jquery y templates DOM View Events El modelo se actualiza con la interacción del usuario Model Events
  25. Backbone $(document).ready(function () { app = new AppRouter(); Backbone.history.start(); });

    var AppRouter = Backbone.Router.extend({ routes:{ "":"home“ }, home:function () { this.changePage(new HomeView()); }, changePage:function (page) { $(page.el).attr('data-role', 'page'); page.render(); $('body').append($(page.el)); $.mobile.changePage($(page.el), {changeHash:false}); } }); window.HomeView = Backbone.View.extend({ template:_.template($('#home').html()), render:function (eventName) { $(this.el).html(this.template()); return this; }}); <!-- The Template --> <script type="text/template" id="home"> <div data-role="header"> </div> <div data-role="content“> </div> <div data-role=“header”> </div> </script>
  26. Backbone • Deshabilitar navegación con Jquery Mobile <script src="js/jqm-config.js"></script> $(document).bind("mobileinit",

    function () { $.mobile.ajaxEnabled = false; $.mobile.linkBindingEnabled = false; $.mobile.hashListeningEnabled = false; $.mobile.pushStateEnabled = false; // Elimina del DOM aquellos elementos que contengan // data-role=page $('div[data-role="page"]').live('pagehide', function (event, ui) { $(event.currentTarget).remove(); }); });
  27. Appcelerator titanium • FrameWork para crear aplicaciones nativas únicamente con

    JavaScript • Soporta Android, iOS ,BlackBerry,Tizen • Open source(Apache License 2.0).Soporte de pago • http://appcelerator.com • https://github.com/appcelerator • http://www.appsdev-es.com/ • http://docs.appcelerator.com/titanium/3.0/ Características • Interactuar con audio y video mediante streaming • Interactuar con la cámara • Geolocalización y mapas • Interacción con Redes sociales • Acceso al sistema de ficheros y base de datos
  28. Arquitectura La clave reside en la capa titanium bridge que

    será la encargada de traducir el javascript en código nativo(Java para el caso de android y objetive-c para el caso de iphone/ios).El resultado es una app completamente nativa. UI API Componentes de UI nativos Navbar, Tabbar, Toolbar,Menus Phone API Componentes para las capacidades nativas del teléfono geolocalización, acelerómetro, mapas, sonido ,DB, sistema de ficheros, red
  29. Event-driven && component-oriented Events • click • change • focus

    • blur • touchstart • ….. var button = Titanium.UI.createButton({ title: Title', top: 10, width: 100, height: 50 }); button.addEventListener('click',function(e) { Titanium.API.info("You clicked the button"); }); Components var picker = Ti.UI.createPicker({ type:Ti.UI.PICKER_TYPE_DATE, minDate:new Date(2012,0,1), maxDate:new Date(2013,11,31), value:new Date(2012,3,12), top:50 }); picker.addEventListener('change',function(e){ Ti.API.info("User selected date: " + e.value.toLocaleString()); }); var tableData = [ {title: 'Alert'}, {title: Options Dialog'}, {title: Window Unfocused'}]; var table = Ti.UI.createTableView({ data: tableData });
  30. Geolocalización var mapa = Titanium.Map.createView({ mapType: Titanium.Map.STANDARD_TYPE, animate: true, regionFit:

    true, userLocation: true }); Titanium.Geolocation.getCurrentPosition (function(event) { var longitud = event.coords.longitude; var latitud = event.coords.latitude; var altitud = event.coords.altitude; mapa.region = {latitude: latitud,longitude: longitud, latitudeDelta:0.5, longitudeDelta:0.5};});
  31. Tabs // create tab group var tabGroup = Titanium.UI.createTabGroup(); //

    create base UI tab and root window var win1 = Titanium.UI.createWindow({ title:'Tab 1', backgroundColor:'#fff' }); var tab1 = Titanium.UI.createTab({ icon:'KS_nav_views.png', title:'Tab 1', window:win1 }); // add tabs tabGroup.addTab(tab1); tabGroup.addTab(tab2); // open tab group tabGroup.open();
  32. Tianium vs PhoneGap Titanium: • Ejecuta la aplicación de forma

    nativa • API más potente. Todo es personalizable. • Mayor número de controles IU, transición y animaciones • Patrón MVC mediante Alloy • Native GUI.Look and Feel de forma nativa • Mayor curva de aprendizaje • Aplicaciones más pesadas(>=5MB) • No soporta HTML5,CSS3,librerías Javascript. • No acceso al DOM. PhoneGap: • Más fácil de aprender con conocimientos básicos de JavaScript • Soporte HTML5,CSS3,librerías Javascript • Debug es más sencillo al poder utilizar herramientas de desarrollo web • Rendimiento suele ser inferior • Ejecuta la aplicación dentro de componente WebView
  33. Recomendaciones interfaz usuario Responsive web design- CSS media queries /*

    on mobile */ //para resoluciones menores o iguales a 480px de ancho <link type="text/css" rel="stylesheet" media="only screen and (max-device-width:480px)" href="mobile.css" /> /*on tablet */ //para resoluciones mayores a 480px de ancho <link media="screen and (min-device-width: 481px)" href=“tablet.css" type="text/css" rel="stylesheet" /> Viewport optimizado para móviles <head> <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;" /> </head>
  34. Modernizr Permite detectar la presencia de prácticamente cualquier funcionalidad de

    HTML5 y CSS3 en nuestro navegador Modernizr.load([ { load: '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js', complete: function () { if ( !window.jQuery ) { //si jquery no se ha cargado correctamente Modernizr.load('js/libs/jquery-1.7.1.min.js'); } } }, { // This will wait for the fallback to load and execute if it needs to. load: 'needs-jQuery.js' } ]); http://modernizr.com/download/
  35. Bibliografia Sencha touch Sencha.Touch 2 Up and Running Oreilly 2013

    Creating Mobile Apps with Sencha Touch 2 Packt Publishing 2013 Sencha MVC Architecture Packt Publishing 2012 Sencha Touch Mobile JavaScript Framework Packt Publishing 2012
  36. Bibliografia Phonegap PhoneGap Beginner's Guide Packt Publishing 2011 Beginning PhoneGap

    Wrox 2011 Beginning PhoneGap, Mobile Web Framework for JavaScript and HTML5 Apress 2012 PhoneGap Mobile Application Development Cookbook Packt Publishing 2012
  37. Bibliografia Jquery mobile jQuery Mobile Up and Running Oreilly 2012

    jQuery Mobile O'Reilly 2011 jQuery Mobile First Look Packt 2011 Teach Yourself jQuery Mobile In 24 Hours SAMS