miércoles, 8 de junio de 2016

Crear aplicaciones para iOS (iPhod, iPad, iPhone) con Apache-Cordova (primera parte)

Requisitos para crear aplicaciones para iOS con Apache-Cordova


Para poder desarrollar aplicaciones para iOS necesitas:

1. Una Mac con OS X versión 10.9 (Mavericks) o mayor.
2. Xcode versión 6 o mayor
3. iOS 8 SDK (Software Development Kit) Viene con el Xcode.
4. Un dispositivo (iPad, iPod, iPhone) con iOS 6.x o mayor.
5. Tener una cuenta de desarrollador de Apple, que cuesta $99 dlls al año.

Si únicamente utilizas el simulador, no es necesario pagarle a Apple.
Para subir aplicaciones a la tienda de Apple se requiere las últimas versiones de las herramientas (y pagar).

Adecuar el Xcode para la línea de comandos


Una vez que tienes tu Xcode necesitas instalar la herramienta de líneas de comandos. Entra a Xcode y selecciona:

Xcode> preferencias> componentes> instalar> Herramientas de línea de comandos .

En Xcode 7 y mayores sólo hay que bajar los simuladores.

Instalar herramientas


Desde la terminal, instalar las siguientes herramientas:

$ npm install -g ios-sim
$ npm install -g ios-deploy
Si tienes OS x, El capitán, debes añadir --unsafe-perm=true

Crear un proyecto nuevo


Creamos un proyecto con los mismos pasos que para otras plataformas:

    $ cordova create hello com.example.hello "HelloWorld"
    $ cd hello
    $ cordova platform add ios
    $ cordova build ios

Se genera un archivo HelloWord.xcodeproj en hello/platforms/ios/ (aun no se genera un ipa).

Aquí puedes ejecutarlo en el emulador o en Xcode.

Ejecutar la aplicación en el emulador


Necesitas tener un equipo iOS conectado a tu computadora por medio de una USB. Debes contar con el perfil provisional. Teclea en la terminal:

    $ cordova run ios --device
Si solo desea ejecutar la aplicación en el emulador, teclee en la terminal:

    $ cordova emulate ios

Si desea ver todos los destinos disponibles teclee:

    $ cordova run ios --list

Abrir la aplicación en Xcode


Dentro de la carpeta xxx/platforms/ios/ se encuentra el archivo HelloWord.xcodeproj. Pulse sobre él dos veces y abrirá la aplicación en Xcode. Puede ejecutar desde aquí el emulador.

Hasta aqui llevamos la mitad del camino pues podemos utilizar los emuladores, pero aún no se genera el archivo IPA, el ejecutable para iOS.

Crear un archivo ipa para instalarlo en un dispositivo ios

7. Añadir los certificados en Xcode
8. Conecte su dispositivo por la USB
9. Seleccione su proyecto
10. Seleccione el dispositivo
11. Presiona el botón Run y se construirá, implementará y ejecutará la aplicación en el dispositivo.

Estos pasos no implican que tu aplicación esté lista para ser subida y aprobada por Apple.


Añadir los certificados a Xcode


En la carpeta platform/ios/cordova existen tres archivos que genera Xcode:

build-debug.xcconfig
build-release.xcconfig
build.xcconfig

Abre el archivo build-release.xcconfig con un editor que no genere caracteres especiales.

Hasta el final hay dos líneas:

CODE_SIGN_IDENTITY = iPhone Distribution
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Distribution

Debes de escribir el nombre que viene en tu certificados CSR. Tiene que ser exacto, por ejemplo:

CODE_SIGN_IDENTITY = iPhone Distribution: Francisco Javier Arce Anguiano
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Distribution: Francisco Javier Arce Anguiano

Ahora debes escribir la siguiente instrucción en la terminal:



    $ cordova build --release

Si tienes un dispositivo con iOS conectado a tu computadora, puedes solicitar que se ejecute en él con:



    $ cordova build --release --device

El la carpeta platform/ios/build/device/ deberás tener tu archivo .ipa.

Pulsa dos veces sobre el archivo ipa y se cargará a iTunes. Desde ahí lo puedes arrastrar a las opciones del dispositivo, por si no se ha cargado adecuadamente.

Generar el archivo ipa desde Xcode


Conecta tu dispositivo y selecciónalo en las opciones en la parte superior de Xcode, a lado del botón "run". Pulsa posteriormente el botón "run" y después de unos instantes, ya tendrás el archivo ipa, en la misma carpeta que el punto anterior, y deberás ver la aplicación en tu dispositivo.

Referencias


https://cordova.apache.org/docs/es/latest/guide/platforms/ios/
https://cordova.apache.org/docs/es/latest/guide/platforms/ios/
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/Introduction/Introduction.html

martes, 7 de junio de 2016

Empaquetar tu aplicación para Android desde Apache-Cordova

Crear las llaves en Apache-Cordova

Para poder empaquetar nuestra aplicación realizada con Apache-Cordova necesitamos crear dos llaves desde la línea de comandos: la "keystore" y la "key" que son propias de todas las aplicaciones de Android.

El "keystore" es un contenedor seguro donde se pueden almacenar las llaves encriptadas y protege a las llaves de un uso mal intencionado.

Para generar el "keystore" utilizamos el siguiente comando en la consola:

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000


El nombre del archivo de la llave será "my-release-key.keystore" el cual deberá llevar relación con el nombre de la aplicación.

El alias será un nombre corto para el "keystore". En le ejemplo es: alias_name

Cordova te hará una serie de preguntas, así como una clave de acceso, la cual no deberás olvidar. No introducir acentos ni eñes ni ningún caracteres "raro".

Se genera un archivo my-release-key.keystore en la carpeta de la aplicación, al mismo nivel de la carpeta www y del archivo config.xml.

Posteriormente deberás ejecutar el siguiente comando en la consola (el cual te enviará un error):

cordova build --release

Aquí es donde aparece un problema, porque cordova por si sola no encuentra las llaves.

Ubicar las llaves para que las encuentre cordova


Entra a la carpeta de android, dentro de platforms y crea un archivo de texto plano con el nombre ant.properties.

El archivo debe de contener las siguientes líneas:

key.store=../../mykeystore.keystore
key.alias=mykeystore

Obviamente hay que actualizar "mykeystore" por el nombre que se haya seleccionado en los puntos anteriores.

Si cambió la estructuras de las carpetas, debe actualizar la ruta de ../../

Si ha copiado el archivo "mykeystore.keystore" en la misma carpeta que el archivo ant.properties, puede omitir la ruta del archivo.

Desde la línea de comandos teclee nuevamente:

cordova build --release

Si todo es correcto, cordova le solicitará la clave de acceso creada en el paso de la creación de la "keystore".

El archivo lo encontrarás en la carpeta "build" con el nombre android-release-unsigned.apk.

Renombra el archivo. Ya estás listo para subirlo a la tienda de Google Play.

Subir la aplicación a Google-Play

Entra a:

http://developer.android.com/distribute/googleplay/index.html

Prepare su tarjeta de crédito. Le cobrarán $25 US dlls (sólo una vez en la vida). El proceso es muy transparente y le pedirán varios recursos como: pantallas de la aplicación, iconos, descripción del producto, etc.

Listo, tendrá su aplicación en el mercado de Google... prepárese para convertirse en millonario :)

Referencias:


https://developer.android.com/training/articles/keystore.html
http://phonegap.com/getstarted/
https://cordova.apache.org/docs/es/latest/guide/next/index.html

Crear un plugin en apache-cordova

Un plugin es un pequeño programa que nos permitirá tener acceso a alguna de las características o funcionalidades del dispositivo, por medio de Apache-Cordova. Puedes encontrar gran número de plugins en:

http://cordova.apache.org/plugins/

Cada plugin constará de:


  1. Un archivo JavaScript que funciona como interfaz, 
  2. Un archivo plugin.xml (conocido como manifiesto) que sirve para configuración del API y 
  3. Un archivo con el código del lenguaje nativo de cada plataforma.


Puedes almacenar tu plugin en tu cuenta git y acceder al mismo por medio de la URL:

  $ cordova plugin add https://git-micuenta.com/cordova-plugin-miplugin.git


El manifiesto  o el archivo plugin.xml


Primero debemos contar con un archivo plugin.xml que es el archivo de configuración o "manifiesto" de nuestro plugin. Un ejemplo sencillo del mismo se muestra a continuación:

 <?xml version="1.0" encoding="UTF-8"?>

    <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
            id="cordova-plugin-miplugin" version="0.0.1.">
        <name>miPlugin</name>
        <auhtor>Yo Mero</autho>
        <description>Un plugin muy sencilla</description>
        <license>Apache 2.0</license>
        <keywords>cordova,apache</keywords>

        <js-module src="www/miPlugin.js" name="device">
            <clobbers target="window.miPlugin" />
        </js-module>

        <platform name="android">
            <config-file target="config.xml" parent="/*">
                <feature name="Device">
                    <param name="ios-package" value="CDVDevice"/>
                </feature>
            </config-file>
            <header-file src="src/ios/CDVDevice.h" />
            <source-file src="src/ios/CDVDevice.m" />
        </platform>

    </plugin>

La primera línea es el identificador de XML como cualquier archivo XML:

 <?xml version="1.0" encoding="UTF-8"?>

La siguiente línea determina el "name space" del xml y no debe cambiar, pero tiene como atributos el nombre del plugin y su número de versión en el formato "versión mayor.versión menor.parche" (si quieres conocer más sobre el manejo de versiones, entra a http://semver.org/). Es la etiqueta principal como cualquier archivo XML bien formado:

  <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="cordova-plugin-miplugin" version="0.0.1.">

Las siguientes líneas son para identificación del autor. Si quieres conocer más sobre las licencias de código abierto u "open source", entra a http://opensource.org/licenses

<name>miPlugin</name>
<auhtor>Yo Mero</autho>
<description>Un plugin muy sencilla</description>
<license>Apache 2.0</license>
<keywords>cordova,apache</keywords>

En el siguiente bloque de instrucciones indicamos dónde se encuentra el archivo js y con clobbers indicamos el objeto y la forma de llamarlo. También podemos añadirlo al objeto "navigator". Esta directiva copia el archivo js al proyecto de cordova y le dará acceso a tus rutinas cuando sean llamadas desde la aplicación.

<js-module src="www/miPlugin.js" name="device">
            <clobbers target="window.miPlugin" />
</js-module>

Las siguientes etiquetas nos indican los archivos fuente dependiendo de cada plataforma:

<!-- android -->
<platform name="android">
     <config-file target="res/xml/config.xml" parent="/*">
          <feature name="HelloPlugin">
               <param name="android-package" value="org.camden.plugin.HelloPlugin"/>
           </feature>

      </config-file>
      <source-file src="src/HelloPlugin.java" target-dir="src/org/camden/plugin" />

</platform>

Habría que añadir un bloque similar si el plugin es válido para más de una plataforma. La etiqueta <config-file> indica la ubicación física del archivo xml. El contenido del archivo es "incrustado" en el archivo config.xml de cordova donde se le indica en el parámetro "parent".

La etiqueta <feature> indica el nombre del plugin y sus parámetros (?)
La etiqueta <source-file> indica la ubicación y el nombre del archivo con el código fuente, el cual es escrito en el lenguaje base del dispositivo.El atributo "target-dir"  el directorio en el formato reverse-domain.

http://cordova.apache.org/docs/en/latest/plugin_ref/spec.html


El archivo JavaScript en un plugin

var helloplugin = {
    sayHello:function(name, successCallback, errorCallback) {
        cordova.exec(
            successCallback,
            errorCallback,
            'HelloPlugin',
            'sayHello',

            [{ "name": name }]
         );
    }
}

module.exports = helloplugin;

Primero creamos un objeto contenedor:

var helloplugin = {}

Dentro de este objeto creamos las acciones:

sayHello:function(name, successCallback, errorCallback) {}

La comunicación entre JavaScript y el lenguaje nativo (en este caso es Java) la realizamos por medio de la sentencia:
    cordova.exec(function(winParam) {},
                 function(error) {},
                 "service",
                 "action",
                 ["firstArgument", "secondArgument"]);

El primer parámetro dentro del método exec() es la función que ejecutaremos si todo marcha bien (successCallback). 
El segundo parámetro es el nombre de la función si las cosas no salen bien (errorCallback). 
El tercer parámetro es nombre del plugin que será utilizado (HelloPlugin).
El cuarto parámetro es la acción a pasar desde el código nativo.
El quinto parámetro es el valor que vamos a pasar al código nativo.

Fuera de la definición, regresamos el objeto que cordova lo hace disponible a la aplicación

module.exports = helloplugin;

Este plugin toma una cadena y regresa un mensaje (otra cadena).

miércoles, 1 de junio de 2016

El objeto .derrefed() en jQuery

EL objeto deferred() se utiliza cuando tenemos una llamada asíncrona en jQuery principalmente en AJAX.

Cuando haces una solicitud por medio de AJAX, la información no necesariamente llega junta, puede llegar en bloques, es decir, por partes.

Si quieres procesar la información, puedes meter toda el código dentro de la función de callback, pero jQuery tiene una forma más elegante de solucionar este problema.

Por ejemplo, el método .get() de jQuery tiene la siguiente sintaxis:

jQuery.get( url [, data ] [, success ] [, dataType ] );

La función de callback que se lanza en success recibe tres parámetros:

Function( PlainObject data, String textStatus, jqXHR jqXHR )

El primero son los datos en forma de un objeto "variable, valor". El segundo es una cadena con el estado del proceso y el tercero es un objeto con información adicional a la lectura del objeto XMLHttpRequest.

Para manejar el proceso asíncrono en AJAX, tendremos el modelo deferred/promise, donde deferred es tan solo un objeto. La promesa (promise) es la instancia del objeto que puede esperar  la llegada de datos de una petición asíncrona o el fin del procesamiento de todos los datos obtenidos en una función asíncrona.

Un objeto promise es una instancia de solo lectura de un objeto deferred.

Un objeto deferred inicia con un estado "pendiente" o "pending" y puede cambiar a "resuelto" o "rechazado". Una vez que ha cambiado de estado, ya no puede modificarse.

 A una "promesa" puedes asociarle cualquier cantidad de funciones por medio de los métodos done(), fail() y always().

También podemos utilizar una estructura del tipo:

promesa.then(callbackDone, callbackFail, progressFilter);

Una función asociada por medio del método done() de una promesa que a su vez está asociada a un método get(), recibe como parámetro los datos leídos del proceso asíncrono.

Si quieres asociar varias promesas, puedes utilizar la siguiente estructura:

$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) )
  .then( myFunc, myFailure );

También se puede utilizar con el método done():

var d1 = $.Deferred();
var d2 = $.Deferred();

$.when( d1, d2 ).done(function ( v1, v2 ) {
    console.log( v1 ); // "Fish"
    console.log( v2 ); // "Pizza"
});

d1.resolve( "Fish" );
d2.resolve( "Pizza" );




Fuentes:

https://api.jquery.com/jQuery.Deferred/
https://api.jquery.com/category/deferred-object/
https://api.jquery.com/jquery.when/
https://api.jquery.com/deferred.promise/



El método parse() del objeto Date() de JavaScript

El método Date.parse() de JavaScript, toma una cadena de fecha en inglés,  por ejemplo "Dec 25, 1995", como parámetro y regresa el número de milisegundos a partir de la fecha cero de Unix, 10, es decir, enero de 1970.

Acepta la sintaxis IETF (Internet Engineering Task Force, en inglés): "Mon, 20 Dec 1994 13:30:00 GMT"

Comprende las abreviaciones de la zona horaria continental de EUA.

Para su uso general, usar la diferencia de zona horaria, por ejemplo, "Mon, 25 Dec 1995 13:30:00 GMT+0430" (4 horas, 30 minutos al oeste del meridiano de Greenwich).

Si no se especifica la zona horaria se asume la zona horaria local.

Se considera equivalente las zonas horarias GMT y UTC.

parse() es un método estático, por lo que se utiliza junto con el objeto Date() y no sobre una instancia del objeto.

Ejemplo:

var fecha= new Date(Date.parse("Mon, 20 Dec 1994 13:30:00 GMT"));