jueves, 17 de mayo de 2012

Desarrollo de apps con Titanium:Captura y reproducción de Audio

Muchas de las veces queremos desarrollar apps para capturar audio y después de ello guardarlas para luego reproducirlas, esto ha impulsado mucho la combinación de notas en audio más la nube que ha sido una combinación perfecta en esta temporada tecnologica.Para ello necesitamos tener un esqueleto de interfaz:


//crea ventana
var win = Titanium.UI.currentWindow;
//variables
var archivo;
var tiempo;
var sonido;
var duracion = 0;

var etiqueta = Titanium.UI.createLabel({
 text: ' ',
 top:150,
 color: '#999',
 textAlign:'center',
 width: 250,
 height:'auto'
});

win.add(etiqueta);

//label volumen
var volumen = Titanium.UI.createLabel({
 text: "Volumen: "+Ti.Media.volume,
 bottom:50,
 color:'#999',
 textAlign:'center',
 width: 250,
 height: 'auto'
});
//label de switch
var etiquetaSwitch = Titanium.UI.createLabel({
 text:'Alta fiedilidad: ',
 width: 250,
 height:'auto',
 textAlign:'center',
 color:'#999',
 bottom:115
});
//switch
var switchL = Titanium.UI.createSwitch({
 value:false,
 bottom:80
});

win.add(etiquetaSwitch);
win.add(switchL);
//boton del play
var play = Titanium.UI.createButton({
 title:'Reproduce Grabacion',
 width:200,
 height:40,
 top:80
 });
win.add(play);
//boton de grabacion
var start = Titanium.UI.createButton({
 title:'Comenzar Grabacion',
 width:200,
 height:40,
 top:20
});

win.add(start);


Y veremos una interfaz como esta:


Ahora le daremos funcionalidad haciendo lo siguiente:

//crea ventana
var win = Titanium.UI.currentWindow;
//variables
var archivo;
var tiempo;
var sonido;
var duracion = 0;

var etiqueta = Titanium.UI.createLabel({
 text: ' ',
 top:150,
 color: '#999',
 textAlign:'center',
 width: 250,
 height:'auto'
});

win.add(etiqueta);

//label volumen
var volumen = Titanium.UI.createLabel({
 text: "Volumen: "+Ti.Media.volume,
 bottom:50,
 color:'#999',
 textAlign:'center',
 width: 250,
 height: 'auto'
});
//label de switch
var etiquetaSwitch = Titanium.UI.createLabel({
 text:'Alta fiedilidad: ',
 width: 250,
 height:'auto',
 textAlign:'center',
 color:'#999',
 bottom:115
});
//switch
var switchL = Titanium.UI.createSwitch({
 value:false,
 bottom:80
});

win.add(etiquetaSwitch);
win.add(switchL);
//boton del play
var play = Titanium.UI.createButton({
 title:'Reproduce Grabacion',
 width:200,
 height:40,
 top:80
 });
win.add(play);
//boton de grabacion
var start = Titanium.UI.createButton({
 title:'Comenzar Grabacion',
 width:200,
 height:40,
 top:20
});

win.add(start);

//Creamos la instancia de un objeto del metodo AudioRecorder llamado grabando
var grabacion = Ti.Media.createAudioRecorder();

/*
Para una compresion por default usamos Ti.Media.AUDIO_FORMAT_LINEAR_PCM
Nos comprimira el archivo en un tamanio pequenio y optimo para el telefono
Para un formato por default usamos Ti.Media.AUDIO_FILEFORMAT_CAF
Nos dara una buena calidad en el audio
*/
grabacion.compression = Ti.Media.AUDIO_FORMAT_LINEAR_PCM;
grabacion.format = Ti.Media.AUDIO_FILEFORMAT_CAF;
Ti.Media.addEventListener('recordinginput',function(e){
 //en caso de grabacion se da un click en el evento de start
 if(!e.available && grabacion.recording){
  start.fireEvent('click',{});
 }
});
//si se modifico el volumen se actualizara
Ti.Media.addEventListener('volume', function(e){
 volumen.text = "Volumen: "+e.volume;
});
//muestra los niveles de sonido y duracion
function muetraNiveles() 
{
 var peak = Ti.Media.peakMicrophonePower;
    var avg = Ti.Media.averageMicrophonePower;
    duracion ++;
    etiqueta.text ='Duracion: '+duracion+' segundos\npeak power: '+peak+'\navg power: '+avg;
}
//evento al comenzar grabacion
start.addEventListener('click', function()
   {
    if(start.title == "Detener Grabacion")
    {
     //guarda lo grabado en archivo
     archivo = grabacion.stop();
     //cambia la etiqueta start
     start.title= "Comienzar Grabacion";
     //nos muestra la opcion de reproducir
     play.show();
     //limpia el intervalo de tiempo
     clearInterval(tiempo);
     Ti.Media.stopMicrophoneMonitor();
 } else {
  //dar error en caso de que no haiga hardware necesario
    if (!Ti.Media.canRecord) {
      Ti.UI.createAlertDialog({
        title:'Error!',
        message:'No hay dispositivo de grabacion disponible'
      }).show();
return; }
 //cambia etiqueta start
    start.title = "Detener Grabacion";
    //comienza grabar
    grabacion.start();
    //esconde etiqueta Reproducir
    play.hide();
    Ti.Media.startMicrophoneMonitor();
    //inicia en ceros duracion y luego nos muestra el tiempo transcurido
    duracion = 0;
    tiempo = setInterval(muestraNiveles,1000);
  }
});
play.addEventListener('click', function()
{
  if (sonido && sonido.playing)
  {
   //detiene la grabacion
    sonido.stop();
    //libera
    sonido.release();
    sonido = null;
    //cambia etiqueta
    play.title = 'Reproduce Grabacion';
} else {
 //guarda el nuevo archivo
    sonido = Titanium.Media.createSound({sonido:archivo});
    sonido.addEventListener('complete', function()
    {
     //cambia etiqueta play
      play.title = 'Reproduce Grabacion';
    });
    //cambia etiqueta play y reproduce
    sonido.play();
    play.title = 'Detiene Grabacion';
  }
});
//cambia formato por medio del switch
switchL.addEventListener('change',function(e)
{
  if (!switchL.value)
  {
    grabacion.compression = Ti.Media.AUDIO_FORMAT_ULAW;
     }
else {
       grabacion.compression = Ti.Media.AUDIO_FORMAT_LINEAR_PCM;
     }
});



Y como resultado veremos lo siguiente:


Desarrollo de apps con Titanium:Integración de Facebook

Sin duda uno de lo grandes impactos al momento de crear una aplicación es la integración de las redes sociales, en esta entrada hablaremos sobre como crear un login y hacer un post en tu muro del usuario.

Para ello debemos tener creada un aplicación en Facebook el cual es relativamente sencillo, si tienen alguna duda pueden entrar a esta liga que encontre en la cual explica como crear un aplicación en Facebook:


Ahora lo que nos interesa será esto, ya verán por que:


Ahora veremos como hacer un login, y como implementaremos lo anterior en el código :


//crea ventana
var win = Titanium.UI.currentWindow;
//funcion que hace el login de Facebook
function loginFacebook(){
 //Si el usuario no se logio entonces pedir permisos
 if(Titanium.Facebook.loggedIn == false){
  //Aqui colocaremos nuetra APP ID
  Titanium.Facebook.appid='168079606553295';
  Titanium.Facebook.permissions = ['publish_stream'];
  //Permiso que tu app necesita del login
  Titanium.Facebook.addEventListener('login',function(e){
   if(e.success) {
    alert('Te has logiado');
    botonFacebook.title='Postea muro'
   }else if(e.error){
    alert('Error: '+ e.error);
   }else if(e.cancelled){
    alert('Has cancelado el login');
   }
  });
  //Llama un metodo de la API de Facebook para hacer el login
  Titanium.Facebook.authorize();
 }
}

var botonFacebook = Titanium.UI.createButton({
 width: 280,
 height: 35,
 top: 330,
 title: 'Login Facebook'
});
win.add(botonFacebook);
botonFacebook.addEventListener('click', function(e){
 loginFacebook();
});


Nosotros agregamos en el código lo que es la APP ID para pedir permiso a que pueda hacer un login el usuario, más adelante veremos para que lo usamos.Ahora veremos por el momento nuestra captura de pantalla:


Ahora haremos un post  en el muro del usuario con una imágen y una pequeña descripción agregandole esta sentencia dentro de la función de loginFacebook:


 }else{
  //Si ya haz accedido entonces
  //Postea foto
 var f = Ti.Filesystem.getFile('paper.png');
 var imagen = f.read();
 var dato = {
  caption: 'Testeo de Post',
  picture: imagen
  };
  //Postea en este directorio me/photos, anexamos imagen
  Titanium.Facebook.requestWithGraphPath('me/photos', dato, "POST", function(e){
   if(e.success){
    alert("Excelente tu imagen sea posteado en tu muro");
   }else{
    alert('Tu imagen no se pudo postear en tu muro :( intenta denuevo');
   }
  });
 }
}


Y veremos lo siguiente en nuestra app:


Desarrollo de apps con Titanium:Envío de email

Para tener una aplicación muy completa muchos desarrolladores colocan su email para alguna sugerencia y esto es bueno ya que retroalimentan al desarrollador.A continuación haremos una mini-app en la que enviaremos un pequeño contenido con un titulo.

Para ello necesitamos hacer lo siguiente:


//crea ventana
var win = Titanium.UI.currentWindow;
//Nos ayuda crear la forma para enviar un correo
var email = Titanium.UI.createEmailDialog();
//Campo de texto para el titulo, dentro del mismo un aviso
var titulo = Titanium.UI.createTextField({
 width: 200,
 height: 35,
 top: 90,
 value: 'Titulo del mensaje',
 borderStyle: 4
});
win.add(titulo);
//Crearemos un area de texto, a diferencia de campo es que este es mas grande
var texto = Titanium.UI.createTextArea({
 width: 200,
 height: 140,
 top: 130,
 value: 'Cuerpo del mensaje',
 font: {fontSize: 15},
 borderStyle: 4
});
win.add(texto);
//funcion para llenar datos del correo
function llenado(){
 //titulo
 email.subject = titulo.value;
 //correo
 email.toRecipients = ['saul.gausin@gmail.com'];
 //cuerpo del mensaje
 email.messageBody = texto.value;
 //nos envia a nuestra app de correo
 email.open();
}

//boton de enviar
var boton = Titanium.UI.createButton({
 width: 300,
 height: 35,
 top: 280,
 title: 'Enviar correo'
});

//evento de boton
boton.addEventListener('click',function(e){
 if(titulo.value == 'Titulo del mensaje' || titulo.value == null){
  alert('Necesitas tener un titulo.');
 }else if(texto.value == 'Cuerpo del mensaje' || texto.value == null){
  alert('Necesitas tener un contenido.');
 }else{
  llenado();
 }
});

win.add(boton);

Y lo que nos despliegará será lo siguiente :


Le agregamos unas cuantas excepciones si no han sido modificados los campos y si no tiene nada en el campo, y esas excepciones no nos dejan enviar el correo hasta que haya contenido alguno.


martes, 15 de mayo de 2012

Desarrollo de apps con Titanium:Captura/Selección de imágen

Ahora hablaremos sobre como hacer una captura o selección de imágen usando un dialogo, un dialogo es una forma de desplegar varias opciones al usuario  y así se ve:


Para haer que un dialogo se despliegue necesitamos hacer el siguiente código:

//crea ventana
var win = Titanium.UI.currentWindow;
//creamos un dialogo con las siguientes opciones para obtener una imagen segun la opcion elegida
var dialogo = Titanium.UI.createOptionDialog({
 title:'Elige la fuente de la imagen ',
 options: ['Camara','Galeria','Cancelar'],
 cancel:2 //Esto es para eligir cual sera la opcion cancelar
 //Donde comenzamos de 0 como por ejemplo tenemos cancelar
 // 0 Camara, 1 Galeria y 2 Cancelar
});
//agregamos el evento
dialogo.addEventListener('click',function(e){
 Ti.API.info('Seleccionaste'+e.index);
});
//boton para eligir foto
var eligirFoto = Titanium.UI.createButton({
 title: 'Elige',
 top: 20,
 right: 20
 
});

eligirFoto.addEventListener('click',function(e){
 dialogo.show();//muestra dialogo
});
win.add(eligirFoto);

Y obtendremos esto:

Dicho dialogo es desplegado después de haber dado click en el botón.Ahora que ya tenemos este dialogo haremos lo funcional, osea que haremos que tome primero la cámara del telefono y después que tome de la galería.A continuación veremos como tomarlo del teléfono.

//agregamos el evento
dialogo.addEventListener('click',function(e){
 Ti.API.info('Seleccionaste'+e.index);
 //Si eligio Camara
 if(e.index== 0 )
 {
  //Desde nuestra camara
  Titanium.Media.showCamera({
   success:function(event)
   {   
    //Guarda imagen en esta varible
    var imagen = event.media;
    if(event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO)
    {
     //coloca la imagen como una vista
     var imagenView = Titanium.UI.createImageView({
      top:20,
      left:20,
      width: 280,
      height: 320
     });
     imagenView.image=imagen;
     win.add(imagenView);
    }
   },
   cancel:function()
   {
    //Ha sido cancelado, la opcion de tomar imagen desde la camara
   },
   error:function(error)
   {
    //crea una alerta
    var alerta = Titanium.UI.createAlertDialog({
     title:'Camara'
     });
    //Daremos aviso si no tuvo camara o si realmente es otra cosa
    if(error.code == Titanium.Media.NO_CAMERA)
    {
     alerta.setMessage('El dispositivo tiene camara disponible');
    }else{
     alerta.setMessage('Error desconosido');
    }
    //nos muestra la alerta
    alerta.show();
    },
    //permitimos que nuestro dispositivo edite la imagen
   allowImageEditing:true,
   //permitimos a nuestro dispositivo que guarde la imagen en la galeria
   saveToPhotoGallery:true
 });
 }else{
  //canelado
  
 }
});

 Y que obtendremos será un evento en el cual guarda la imágen capturada con el dispositivo, en caso de no tener cámara alguna nos mostrará una alerta diciendonós si el dispositivo no tiene cámara o si fue otro error.Ahora veremos como tomar imágenes desde una galería de fotos:


if(e.index == 1){
  //obtiene una imagen de la galeria de fotos del telefono
  Titanium.Media.openPhotoGallery({
   //Si se cumple
   success:function(event){
    //guarda imagen en variable
    var imagen= event.media
    //Lo coloca como una vista
    if(event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO){
     var imagenVista = Titanium.UI.createImageView({
      top:20,
      left:20,
      width: 280,
      height: 320
     });
     imagenVista.image=imagen;
     win.add(imagenVista);
    }
   },
   //Si no cumple cancela
   cancel:function(){
   //El usuario cancelo la opcion
   }
     });
    }else{
  //cancelado
 }


Con esto podremos tomar imágenes desde nuestra galería del dispositivo ó desde la cámara del mismo.

lunes, 14 de mayo de 2012

Desarrollo de apps con Titanium:Agregando filtro a un TableView

Ahora lo que haremos es agregarle un filtro a nuestra tabla, esto nos sirve mucho para cuando manejamos muchos datos y queremos encontrar de una manera más comoda algo.Para esto tomaré como base la app que vimos en esta entrada:

http://dispositivosmoviles-saulg.blogspot.mx/2012/05/desarrollo-de-apps-con.html

Ahora veremos como implementar un filtro en una tabla, para ello debemos agregar el siguiente código antes de definir una tabla:
//definimos la barra del buscador de la tabla
var buscador = Titanium.UI.createSearchBar({
 showCancel:true,//muestra opcion de cancelar
 height:43,
 top:0
});

//muestra en la consola el valor que busca
buscador.addEventListener('change',function(e){
 Ti.API.info('Busco : '+ e.value);
});
//cuando borra en el campo de texto quita el enfoque al buscador
buscador.addEventListener('return',function(e){
 buscador.blur();
});
//cuando cancela el usuario quita el enfoque a el
buscador.addEventListener('cancel',function(e){
 buscador.blur();
});

Ya definido el buscador vamos a agregar las siguientes propiedades a nuestra tabla para que pueda funcionar nuestro filtro:


Nosotros colocamos a la tabla la propiedad de search y ahi va el nombre de nuestro filtro que lo llamamos buscador, también nosotros agregamos la propiedad filterAttribute aquí es donde va ir la variable que utilizaremos para guardar nuestro filtro.

var win = Titanium.UI.currentWindow;
//declaracion del arreglo vacio
var datos = [];
//declaramos el objeto del cliente http
var xhr = Titanium.Network.createHTTPClient();

//definimos la barra del buscador de la tabla
var buscador = Titanium.UI.createSearchBar({
 showCancel:true,//muestra opcion de cancelar
 height:43,
 barColor: '#385292',
 top:0
});

//muestra en la consola el valor que busca
buscador.addEventListener('change',function(e){
 Ti.API.info('Busco : '+ e.value);
});
//cuando borra en el campo de texto quita el enfoque al buscador
buscador.addEventListener('return',function(e){
 buscador.blur();
});
//cuando cancela el usuario quita el enfoque a el
buscador.addEventListener('cancel',function(e){
 buscador.blur();
});
//creacion de la tabla
var tabla = Ti.UI.createTableView({
 height: 366,
 width: 320,
 top: 0,
 left: 0,
 hideSearchOnSelection: true,
 rowHeight:70, //Le decimos el tamaño de nuestras filas
 search: buscador,
 fitlerAttribute:'filter' //filtrado sera lo que aparecera en nuestras filas
});
//agregamos tabla
win.add(tabla);
//este metodo procesara los datos remotos
xhr.onload = function() {
 var xml = this.responseXML;
 //obtenemos el elemento del de la lista desde nuestro responseXML
 var items = xml.documentElement.getElementsByTagName("item");
 //ciclo por cada item en xml
 for (var i = 0; i < items.length; i++){
   
  //creacion de la fila de la tabla
  var fila = Titanium.UI.createTableViewRow({
   hasChild: true,//con esto decimos que tendrá una subsección la fila
   className: 'fila-rss',//propiedad de solo usar memoria necesaria, osea que solo las filas que veamos
   filter: items.item(i).getElementsByTagName("title").item(0).text//esta variable nos ayuda a saber que filas son las que buscamos con el buscador
  });
  //etiqueta de titulo
  var tituloLabel = Titanium.UI.createLabel({
   text:items.item(i).getElementsByTagName("title").item(0).text,
   //propiedades de la letra
   font:{fontSize: 14, fontWeight: 'bold'},
   left:70,
   color:'#000000',
   top:5,
   height:20,
   width: 210
  });
  fila.add(tituloLabel);
  //etiqueta de descripcion
  var descripcionLabel = Titanium.UI.createLabel({
   text:items.item(i).getElementsByTagName("description").item(0).text,
   font:{fontSize: 10, fontWeight:'normal'},
   left: 70,
   color:'#000000',
   top: 25,
   height: 40,
   width: 200
  });
  if(descripcionLabel.text == ''){
   descripcionLabel.text = 'Descripcion no disponible.';
  }
  fila.add(descripcionLabel);
  //Agregamos un icono en el lado izquierdo a cada fila
  var icono = Titanium.UI.createImageView({
   image:'paper.png',
   width: 30,
   height: 30,
   left: 10,
   top: 10
  });
  fila.add(icono);
  //agregamos la fila al arreglo datos
  datos.push(fila);
 }//termina nuestro ciclo
 //Ahora le especificamos la propiedad de datos a nuestra tabla
 tabla.data = datos;
};
 
//este metodo sera usado en caso de que haiga algun
//error accesando a los datos remotamente
xhr.onerror = function() {
 //Nos desplegara el log del error en la consola
 Ti.API.error(this.status + ' - ' + this.statusText);
};
 
//abre el feed de xml
xhr.open('GET', 'http://feeds.cristalab.com/clab')
 
//Ejecuta la llamada a el feed
xhr.send();

Y esto será lo que obtendremos:

Desarrollo de apps con Titanium:Trabajando con datos remotos

Ahora veremos los métodos que utiliza Titanium Studio para la lectura, análisis y guardado de datos, es importante saber manipular datos remotos para poder hacer una buena optimización de nuestra aplicación.Titanium nos provee una forma sencilla de hacer llamadas simples de XML bajo HTTP, y de igual manera implementando JSON.

Para comenzar primero veremos el siguiente código:
var win = Titatnium.UI.currentWindow;
//declaramos el objeto del cliente http
var xhr = Titanium.Network.createHTTPClient();

//este metodo procesara los datos remotos
xhr.onload = function() {
 //Despliega en la consola las respuesta
 Ti.API.info(this.responseText);
};

//este metodo sera usado en caso de que haiga algun
//error accesando a los datos remotamente
xhr.onerror = function() {
 //Nos desplegara el log del error en la consola
 Ti.API.error(this.status + ' - ' + this.statusText);
};

//abre el feed de xml
xhr.open('GET', 'http://www.elnorte.com/rss/ciencia.xml')

//Ejecuta la llamada a el feed
xhr.send();

Y lo que nos despliega el código en la consola es lo siguiente:


Ahora veremos como desplegarlo en tablas:
var win = Titanium.UI.currentWindow;
//declaracion del arreglo vacio
var datos = [];
//declaramos el objeto del cliente http
var xhr = Titanium.Network.createHTTPClient();
//creacion de la tabla
var tabla = Titanium.UI.createTableView({
 height: 366,
 width: 320,
 top: 0,
 left: 0
});
//agregamos tabla
win.add(tabla);
//este metodo procesara los datos remotos
xhr.onload = function() {
 var xml = this.responseXML;
 //obtenemos el elemento del de la lista desde nuestro responseXML
 var items = xml.documentElement.getElementsByTagName("item");
 //ciclo por cada item en xml
 for (var i = 0; i < items.length; i++){
  
  //creacion de la fila de la tabla
  var fila = Titanium.UI.createTableViewRow({
   title:items.item(i).getElementsByTagName("title").item(0).text
  });
  
  //agregamos la fila al arreglo datos
  datos.push(fila);
 }//termina nuestro ciclo
 //Ahora le especificamos la propiedad de datos a nuestra tabla
 tabla.data = datos;
};

//este metodo sera usado en caso de que haiga algun
//error accesando a los datos remotamente
xhr.onerror = function() {
 //Nos desplegara el log del error en la consola
 Ti.API.error(this.status + ' - ' + this.statusText);
};

//abre el feed de xml
xhr.open('GET', 'http://www.elnorte.com/rss/ciencia.xml')

//Ejecuta la llamada a el feed
xhr.send();

Y nos despliegará esto, que es un rss que lo tomé de la página de "El Norte":



Veremos como colocarle imágenes a cada fila y hacer que cada fila nos muestre el contenido, ya que en el anterior solamente vemos el título de la noticia:
var win = Titanium.UI.currentWindow;
//declaracion del arreglo vacio
var datos = [];
//declaramos el objeto del cliente http
var xhr = Titanium.Network.createHTTPClient();
//creacion de la tabla
var tabla = Titanium.UI.createTableView({
 height: 366,
 width: 320,
 top: 0,
 left: 0,
 rowHeight:70 //Le decimos el tamaño de nuestras filas
});
//agregamos tabla
win.add(tabla);
//este metodo procesara los datos remotos
xhr.onload = function() {
 var xml = this.responseXML;
 //obtenemos el elemento del de la lista desde nuestro responseXML
 var items = xml.documentElement.getElementsByTagName("item");
 //ciclo por cada item en xml
 for (var i = 0; i < items.length; i++){
  
  //creacion de la fila de la tabla
  var fila = Titanium.UI.createTableViewRow({
   hasChild: true,//con esto decimos que tendrá una subsección la fila
   className: 'fila-rss'//propiedad de solo usar memoria necesaria, osea que solo las filas que veamos
  });
  //etiqueta de titulo
  var tituloLabel = Titanium.UI.createLabel({
   text:items.item(i).getElementsByTagName("title").item(0).text,
   //propiedades de la letra
   font:{fontSize: 14, fontWeight: 'bold'},
   left:70,
   color:'#000000',
   top:5,
   height:20,
   width: 210
  });
  fila.add(tituloLabel);
  //etiqueta de descripcion
  var descripcionLabel = Titanium.UI.createLabel({
   text:items.item(i).getElementsByTagName("description").item(0).text,
   font:{fontSize: 10, fontWeight:'normal'},
   left: 70,
   color:'#000000',
   top: 25,
   height: 40,
   width: 200
  });
  if(descripcionLabel.text == ''){
   descripcionLabel.text = 'Descripcion no disponible.';
  }
  fila.add(descripcionLabel);
  //Agregamos un icono en el lado izquierdo a cada fila
  var icono = Titanium.UI.createImageView({
   image:'paper.png',
   width: 30,
   height: 30,
   left: 10,
   top: 10
  });
  fila.add(icono);
  //agregamos la fila al arreglo datos
  datos.push(fila);
 }//termina nuestro ciclo
 //Ahora le especificamos la propiedad de datos a nuestra tabla
 tabla.data = datos;
};

//este metodo sera usado en caso de que haiga algun
//error accesando a los datos remotamente
xhr.onerror = function() {
 //Nos desplegara el log del error en la consola
 Ti.API.error(this.status + ' - ' + this.statusText);
};

//abre el feed de xml
xhr.open('GET', 'http://www.elnorte.com/rss/ciencia.xml')

//Ejecuta la llamada a el feed
xhr.send();

Ahora veremos lo que nos despliega el código:

Ahora usaremos JSON, para ello nosotros usaremos Yahoo! YQL para acelerar el acceso a nuestros datos remotos.Para ello entramos a esta página http://developer.yahoo. com/yql/console :


Seleccionamos 'Data Tables', luego seleccionamos 'data' para después seleccionar 'feed'.Nos aparecerá algo como arriba pero con otra url, sustituimos por la misma que tenemos en la imágen y
seleccionamos JSON y Diagnostics,Para finalizar damos click en TEST y nos dará como resultado XML en formato JSON debajo de la etiqueta THE REST QUERY, una vez teniendo la url sustituimos esto ' por esto otro \' eliminaremos esta parte &callback=cbfunc que es la última.


Ahora modificaremos nuestro código:
var win = Titanium.UI.currentWindow;
//declaracion del arreglo vacio
var datos = [];
//declaramos el objeto del cliente http
var xhr = Titanium.Network.createHTTPClient();
//creacion de la tabla
var tabla = Titanium.UI.createTableView({
 height: 366,
 width: 320,
 top: 0,
 left: 0,
 rowHeight:70 //Le decimos el tamaño de nuestras filas
});
//agregamos tabla
win.add(tabla);
//este metodo procesara los datos remotos
xhr.onload = function() {
 //Creamos un objeto json usando la funcion JSON.parse; nos sirve para parsear datos en JSON
 var jsonObject = JSON.parse(this.responseText);
 //ciclo por cada item en json
 for (var i = 0; i < jsonObject.query.results.item.length; i++){
  //creacion de la fila de la tabla
  var fila = Titanium.UI.createTableViewRow({
   hasChild: true,//con esto decimos que tendrá una subsección la fila
   className: 'fila-rss',//propiedad de solo usar memoria necesaria, osea que solo las filas que veamos
   backgroundColor: '#FFFFFF'
  });
  //etiqueta de titulo
  var tituloLabel = Titanium.UI.createLabel({
   text:jsonObject.query.results.item[i].title,
   //propiedades de la letra
   font:{fontSize: 14, fontWeight: 'bold'},
   left:70,
   color:'#000000',
   top:5,
   height:20,
   width: 210
  });
  fila.add(tituloLabel);
  //etiqueta de descripcion
  var descripcionLabel = Titanium.UI.createLabel({
   text:jsonObject.query.results.item[i].description,
   font:{fontSize: 10, fontWeight:'normal'},
   left: 70,
   color:'#000000',
   top: 25,
   height: 40,
   width: 200
  });
  if(descripcionLabel.text == ''){
   descripcionLabel.text = 'Descripcion no disponible.';
  }
  fila.add(descripcionLabel);
  //Agregamos un icono en el lado izquierdo a cada fila
  var icono = Titanium.UI.createImageView({
   image:'paper.png',
   width: 30,
   height: 30,
   left: 10,
   top: 10
  });
  fila.add(icono);
  //agregamos la fila al arreglo datos
  datos.push(fila);
 }//termina nuestro ciclo
 //Ahora le especificamos la propiedad de datos a nuestra tabla
 tabla.data = datos;
};

//este metodo sera usado en caso de que haiga algun
//error accesando a los datos remotamente
xhr.onerror = function() {
 //Nos desplegara el log del error en la consola
 Ti.API.error(this.status + ' - ' + this.statusText);
};

//abre el feed de xml
xhr.open('GET', 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20feed%20where%20url%3D\'www.elnorte.com%2Frss%2Fciencia.xml\'&format=json&diagnostics=true')
//Ejecuta la llamada a el feed
xhr.send();

Esto es lo que nos despliega el código corriendo:


Vieron la diferencia?, si están leyendo probablemente dirán que esta loco veo lo mismo pero si lo corren verán de que estoy hablando ;) ... me refiero a velocidad .

Fuentes:

Ayuda de desarrollador de Appcelerator
http://developer.appcelerator.com/

Consola YQL
http://developer.yahoo.com/yql/


sábado, 12 de mayo de 2012

Desarrollo de apps con Titanium: Geolocalización

Una de las características de las aplicaciones que tienen gran éxito en el mercado sin duda es la geolocalización por ende explicaré un ejemplo sencillo, en el que colocaremos un pin dependiendo la latitud y longitud dada. 



Y esto es lo que despliega el código desde android:


En el código se crea una vista del mapa en el que pide como parámetros el tipo de mapa: TITANIUM.MAP.STANDARD_TYPE, TITANIUM.MAP.SATELLITE_TYPE y TITANIUM.MAP.HYBRID_TYPE.Estos se ven de la siguiente manera:


También tenemos latitud y longitud los cuales esos dependen de la ubicación exacta del mapa donde quieres que se despliegue la vista del map, de igual manera vemos unos que se llaman latitudDelta y longitudDelta con ellos le decimos cual es nivel de zoom que queremos en el mapa.

Animate es un valor booleano que nos permite el zoom y animación de movimiento dentro o fuera de la vista del mapa. Útil en el caso de la focalización dispositivos más antiguos, con capacidad de procesamiento de baja y / o ancho de banda bajo.

El parámetro region acepta por propiedad un arreglo de parámetros, el cual puede contener puntos de latitud y longitud que nosotros deseamos y colocarlos en el mapa de igual manera con los valores delta.userLocation es un valor booleano que puede apagarse o encenderse con un punto azul como indicador en el cual indica donde estás en relación con la vista del mapa.regionFit es un valor booleano que indica si la región seleccionada se ajusta a las dimensiones de vista dado.

La anotación agregada será descrita de la siguiente manera:

 
En la que tiene los mismos parámetros, con la excepción de algunos como leftButton, rightButton title, subtitle y pinColor.
Esta es la forma de usar colocar una imágen a un leftButton :




En la cual  tiene como parámetro image en donde colocas la dirección de la imágen a mostrar.

Ahora mostaré como colocarle una imágen en el rightButton y como agregarlo:



Y esta es la forma como se agregan eventos de la vista del mapa:


Los pines pueden ir de estos diferentes colores:

Verde
Titanium.Map.ANNOTATION_GREEN  

 Rojo
Titanium.Map.ANNOTATION_RED

Morado
Titanium.Map.ANNOTATION_PURPLE

Fuentes:

Imágenes fueron tomadas de esta presentación
http://www.slideshare.net/jhaynie/whats-great-in-appcelerator-titanium-08

martes, 21 de febrero de 2012

Los Diferentes Tipos de Comunicación Inalámbrica

En está entrada hablaremos de los diferentes términos que son usados en la comunicación inalámbrica entre los que se destacan bluetooth, infrarrojo, GSM, CDMA, 3G, 4G, EDGE, TDMA y GPRS.

Para comenzar empecemos todo desde el inicio... recuerdan cuando algunos de ustedes ya sea amigo o familiar tenian un celular y siempre en un tiempo libre estaban entre sus amigos intercambiando archivos ya sea en la escuela o en el trabajo, todo sucedia con solo acercar dichos celulares.


A está tecnología le llamábamos Infrarrojo el cual es un puerto en el telefono que sirve para comunicarse con otro dispositivo con el mismo tipo de puerto y compartir datos, para que haiga dicho intercambio de información se basa en rayos infrarrojos de los que son codificados y decodificados para convertirlos en un archivo, el cual ha sido enviado.


Este puerto no es visto con el ojo humano pero si puede ser visto por las cámaras convencionales.


Después de conocer el Infrarrojo fuimos avanzando hacia el Bluetooth que está es una especificación industrial para redes inalámbricas de área personal(WPAN) que posibilita la transmisión de voz y datos entre diferentes dispositivos mediante un enlace por radiofrecuencia en la banda ISM de los 2,4 GHz.


Su objetivo principal objetivo es facilitar las comunicaciones entre equipos móviles y fijos, eliminar cables y conectores entre éstos y ofrecer la posibilidad de crear pequeñas redes inalámbricas y facilitar la sincronización de datos entre equipos personales.


Entre los dispositivos que frecuentan usar está tecnología se encuentran las netbook, laptop, desktop, iPod, PSP, celulares, smartphones entre muchos otros.


GSM(2G)

Ahora hablaremos del término GSM que este corresponde a las siglas en inglés para "Global System for Mobile Communications", sabiendo esto nos daremos cuenta que cuando hablamos de un teléfono GSM es un teléfono celular que cuenta con tecnología en base a un sistema global de comunicaciones móviles, el cliente GSM puede conectarse a través de su teléfono con su proveedor y enviar y recibir mensajes por correo electrónico, faxes, navegador por internet, acceder con seguridad a la red informática de una compañía(red local/Intranet), así como utilizar otras funciones digitales de transmisión de datos, incluyendo el servicio de mensajes cortos (SMS) o mensajes de texto, por su velocidad de transmisión y otras características, un estándar de segunda generación 2G.

Este sistema tomó cada vez mayor importancia a lo largo del mundo, ya que este fue el más avanzado hasta su momento, dicha tecnología sigue funcionando hoy en día pero tiene sus desventajas ya que pueden ser escuchados los paquetes que son enviados.

Para ver mas sobre el tema de escuchar paquetes o "sniffing" entren a está presentación en pdf debajo.

http://events.ccc.de/congress/2010/Fahrplan/attachments/1783_101228.27C3.GSM-Sniffing.Nohl_Munaut.pdf
ó

Pueden checar este link:


Donde verán algo de sniffing usando una máquina como está.


CDMA

Está tecnología para diferenciar a los distintos usuarios usan códigos digitales únicos, los códigos son conocidos tanto por la estación móvil(teléfono celular) como por la estación base, y se llaman "Secuencias de Código Pseudo-Aleatorio", y por está razón todos los usuarios comparten el mismo rango del espectro radioeléctrico, todo esto sucede gracias a que usa una tecnología de Espectro Ensanchado, esto quiere decir la información se extiende sobre un ancho de banda mucho mayor que el original, conteniendo una señal identificativa, esto empieza con una transmisión a 9600 bits por segundo,por consiguiente la señal es ensanchada para ser transmitida a 1.23 Megabits por segundo aproximadamente.Un ensanchamiento implica que un código digital concreto se aplica a la señal generada por un usuario en una célula.

Posteriormente la señal ensanchada es transmitida junto con el resto de señales generadas por otros usuarios, usando el mismo ancho de banda.Cuando las señales se reciben, las señales de los distintos usuarios se separan haciendo uso de los códigos distintivos y se devuelven las distintas llamadas a una velocidad de 9600 bps.

La gran ventaja de está tecnología comparada con GSM es que este tipo de señales son muy difíciles de bloquear, de interferir y de identificar, por lo tanto está tecnología es muy segura.

En México actualmente, solo las compañias UNEFON y IUSACELL manejan esta tecnología, y las demás compañias como TELCEL, Movistar siguen usando la tecnología GSM.


Entonces cuando hablamos que un telefono tiene CDMA significa que dicho telefono tiene capacidad de acceso múltiple digital especificada por la Asociación de Industria de Telecomunicaciones (TIA) como "IS-95" y que hacen estos sistemas llamados "IS-95", bueno estos dividen el espectro radioeléctrico en portadoras de 1.25 MHz de ancho de banda.

3G

3G significa tercera generación en telefonía móvil, entre los servicios que proporcionan son la posibilidad de transferir tanto voz y datos (llamada telefónica) y datos no-voz como la descarga de programas intercambio de email y mensajería instantánea, está tecnología comenzó a utilizarse en Japón, y de a poco la fueron incorporando otros países el proceso fue muy lento debido que hacia el uso de muchas frecuencias diferentes por lo tanto requería una licencia adicional.


Está tecnología es muy buena para la transferencia de datos y se dice que podría alcanzar velocidades de hasta 3 Mbit/s.La desventaja de usar está tecnología es que te consume mucho saldo estando en México, ya sea en plan el internet sigue teniendo desventaja ya que es lento; con esto quiero decir que México no tiene muy buen soporte en este tipo de tecnologías aún sabiendo que el dueño de Telcel es el más rico del mundo.


4G


Al igual que 3G, 4G significa cuarta generación de servicio móvil.Para hacer un reencuentro recordemos que 2G nos trajo voz digital y mensajería de texto, luego apareció el 3G que nos trajo los smartphones, navegación rápida por Internet y aplicaciones.

El 4G está basada totalmente en tecnología IP, alcanzando la convergencia entre las redes por cable e inalámbricas así como en computadoras, dispositivos electrónicos y tecnología de la información para proveer velocidad de acceso de 100 Mbps en movimiento y 5 Gbps en reposo, manteniendo una calidad de servicio (QoS) de punta la punta de alta seguridad para permitir ofrecer servicios de cualquier lugar.

En Japón se inicio la experimentación de la tecnología 4G, con la compañia NTT DOCOMO la cual dicha empresa realizo muchas pruebas con éxito alcanzando 100Mbps a 200km/h.

TDMA


Está tecnología  de segunda generación, distribuye las unidades de información en ranuras alternas de tiempo, dando acceso múltiple a un número reducido de frecuencias, dicha tecnología permite dar servicios de alta calidad de voz y datos.Divide un canal de frecuencia de radio en varias ranuras de tiempo seis de D-AMPS y PCS, ocho en GSM.

A cada usuario que realiza una llamada se le asigna una ranura de tiempo específica para permitir la transmisión y esto permite que múltiples usuarios utilicen un mismo canal de frecuencia al mismo tiempo sin interferirse entre sí.

Está tecnología tuvo grandes problemas ya que cuando se caía la red podías hacer llamadas gratis por eso las compañias optaron por GSM, en la cual TDMA usa satélites mientras que GSM usa antenas.

GPRS



GPRS sus siglas significan Global Packet Radio Service y es una arquitectura para redes de área amplia(WAN) la cual está compuesta de sistemas y protocolos de comunicaciones claramente definidos y estandarizados.Dichos sistemas hacen posible la transmisión de datos en forma de paquetes a través de una red celular, en ellos se encuentra el servicio de WAP, SMS, MMS, Internet.

También es conocida como tecnología 2,5G por que constituye el primer paso de GSM hacia 3G

EDGE

Está es una tecnología de la telefonía móvil celular, que actúa como puente entre las redes 2G y 3G, se considera la evolución del GPRS, dicha tecnología funciona como redes GSM puede ser usado en cualquier transferencia de datos basada en conmutación por paquetes como lo es la conexión a Internet.


Puede alcanzar una velocidad de transmisión de 348 Kbps en modo de paquetes, para ello el operador debe implementar las actualizaciones necesarias, además no todos los teléfonos soportan está tecnología.

Links de referencia:

Infrarrojo + Imagenes
http://legacy.spitzer.caltech.edu/espanol/edu/learn_ir/
Bluetooth + Imagenes
http://es.wikipedia.org/wiki/Bluetooth
http://tecnyo.com
http://grupogeek.com
GSM + Imagenes
http://www.misrespuestas.com/que-es-un-telefono-gsm.html
http://es.wikipedia.org/wiki/Sistema_global_para_las_comunicaciones_m%C3%B3viles
http://tec.nologia.com/2009/12/29/descifran-el-codigo-que-protege-las-llamadas-de-telefonos-moviles-gsm/
http://blog.gold-lock.com/page/4/
CDMA + Imagenes
http://www.upv.es/satelite/trabajos/Grupo3_99.00/GlobalStar8.htm
3G + Imagenes
http://sincelular.com/1001/%C2%BFque-es-3g/
http://telecomnewspk.com/
http://www.newser.com/story/113780/carlos-slim-tops-forbes-billionaires-list.html
4G + Imagenes
http://www.informatica-hoy.com.ar/aprender-informatica/Que-es-4G.php
TDMA + Imagenes
http://www.alegsa.com.ar/Dic/tdma.php
http://dmrassociation.org/?page_id=710&lang=es
GPRS + Imagenes
http://trastoteca.blogspot.com/2011/12/que-es-gprs.html
http://www.guardmagic.com/03-spain/1spa-solution/00spa-short/1spa-shortly-12.htm
EDGE + Imagenes
http://www.lambdasi.com.ar/textocomp.asp?id=900
http://churmura.com/technology/internet/edge-technology/30747/

jueves, 16 de febrero de 2012

Colectores en Xcode

En esta entrada hablaremos de los diferentes colectores que existen en Xcode, veremos varios ejemplos para saber para cuando usarlos y para que nos sirven, esto le tomó mucha importancia ya que la mayoría de los programadores tienden a almacenar en un solo tipo de colector para no complicarse la vida al programar algo.Para ello tienes que contar con algún conocimiento básico de Objective-C, si no tienes alguna idea de que es este lenguaje de programación te recomiendo que pases a mi blog de lenguajes de programación en la cual tengo una introducción de programación orientada a objetos con Objective-C, pueden entrar con el link que dejaré debajo.


Los colectores son algo fundamental al momento de aprender Objective-C, algunas veces también son referidos como contenedores.Los colectores son un tipo de clase que pueden guardar y manejar varios objetos, en sí el proposito de estos es proveer una manera en la que puedas guardar y recuperar varios objetos de una manera eficiente.

Hay diferentes tipos de colectores pero de los más comunes que veremos en está entrada serán los siguientes:

  • NSSet

  • NSArray

  • NSDictionary

  • NSMutableSet

  • NSMutableArray

  • NSMutableDictionary

Como verán en la lista hay unos tipos de colectores que se les agrego la palabra clave Mutable, en Objective-C existen dos tipos los que son Mutables y No Mutables lo que estos dos tipos tienen en común es que pueden agregarse elementos y removerlos después de aver sido creados, ya que definimos que tienen en común ahora mencionaremos que es lo que los diferencia uno de otro, Mutable significa que puede ser modificado,por lo tanto, desde el inicio hasta el final puede ser modificado.No Mutables significa que después de aver sido inicializados con algunos valores no puede ser modificado.

Ahora empezaremos a definir cada uno de los colectores:

NSSet

En está clase es usada para almacenar una lista de objetos desordenada, lo que significa que los objetos pueden ser almacenados sin considerar su orden, la ventaja de está clase es que es el colector más rápido.

Ahora veremos un ejemplo de como se inicializa NSSet :

NSSet *lista = [NSSet setWithObjects:@"Algo", @"Genetico", @"Don Pedro", nil];

Como verán este es un ejemplo de una lista de strings, en donde la ultimo objeto tiene que ser nil y esto indica que la lista de objetos a sido finalizada.Este ejemplo no implica que tiene que ser solamente utilizado solo para strings, este puede estar compuesto por diferentes tipos de objetos.

Aquí tenemos un ejemplo muy común utilizado con la clase NSSet que se utiliza especialmente cuando se intenta capturar las veces que haz tocado la pantalla normalmente les dicen touches.

NSSet *lista [NSSet setWithObjects: @"Algo", @"Genetico", @"Don Pedro", nil];

NSString *valor = [lista anyObject];

Lo que vemos en la tercer linea un método que llamamos llamado anyObject que básicamente toma cualquier objeto que está dentro de lista, esto es sumamente necesario ya que en algunos casos algunas aplicaciones con solo tocar la pantalla, con al menos un dedo hacen algo en consecuencia.

NSArray

A diferencia de NSSet, NSArray te permite recuperar los objetos por un index que están en un arreglo en donde el index está enumerado con la posición en el cual el objeto ocupa.

Para ello veremos un ejemplo de usando NSArray donde asignaremos varios strings y los llamaremos con un index.

NSArray *Arreglo = [NSArray arrayWithObjects: @"Algo", @"Malo", @"Telefono",nil];

NSLog (@"%@", [Arreglo objectAtIndex:0]);
NSLog (@"%@", [Arreglo objectAtIndex:1]);
NSLog (@"%@", [Arreglo objectAtIndex:2]);

Impresión de resultado:


Esto es sencillo de explicar prácticamente el método objectAtIndex seguido del número de la posición del objeto es el que será tomado e imprimido por medio de NSLog.

Para saber el tamaño de un array o arreglo puede ser calculado de una manera muy sencilla por medio de esta manera:

int contador = [Arreglo count];

Impresión de resultado donde se logra apreciar en el debugger:


Como podrán observar para tener el tamaño primero debemos darle el nombre en este caso lo llamamos Arreglo y luego count que significa que contará el tamaño del Arreglo.

NSDictionary

La clase de NSDictionary en diferencia de NSArray y NSSet es que pueden crear una lista de objetos con index en el cual puede ser compuesta por otra lista que comúnmente las llamamos keys, el problema aquí es que no podemos repetir ninguna key.Dentro de la lista de objetos pueden ser agregados mas listas de objetos.

Ahora veremos un ejemplo:

NSDictionary *zoologico = [NSDictionary dictionaryWithObjectsAndKeys:
                               @"elefante", miObjetoElefante,
                               @"jirafa", miObjetoJirafa,
                               @"mono", [NSDictionary dictionaryWithObjectsAndKeys:
                                         @"Araña", miMonoAraña,
                                         @"Capuchino", miMonoCapuchino,
                                         @"Orangutan", miMonoOrangutan,nil]
                               @"zebra", miObjetoZebra, nil];

Este es un ejemplo de como se usa NSDictionary donde le estamos dando el objeto que en este caso colocamos un String  y después nuestra key para identificarla, con la condición de que no se repita.

Y la gran pregunta como manejarlos, o como identificarlos  tal ves creas que es algo mitico pero no lo es primero tenemos que identificar de que clase son para hacer esto mas didáctico supongamos que zebra, mono, elefante y jirafa son objetos de la clase NSDictionary y que la lista de monos son objetos de la clase Animal, ahora veremos el ejemplo para identificarlos uno de otro.

      for(id element in [zoologico allValues]){
         if ([element isKindOfClass:[Animal class]]){
             NSLog(@"Eres de la clase Animal");
       }
       if([element isKindOfClass:[NSDictionary class]]) {
             NSLog(@"Eres de la clase NSDictionary");
       }
     }
             

Primero que nada definamos por que usamos id, bueno id se utiliza cuando realmente no sabemos que clases están almacenadas en el colector.Como se observa toma todo lo que contenga zoologico con la palabra clave allValues y hace una iteración por cada elemento en el, luego dentro del if pregunta si dicho elemento es de la clase Animal si es así imprime Eres de la clase Animal y lo mismo sucede con el otro if.Esto funciona gracias al metodo llamado isKindOfClass que regresa un valor boleano si es la clase que estamos buscando nos retornara un True en caso contrario un False.

Hasta aquí hemos visto nadamas clases No Mutables, como lo habíamos comentado una vez que inicializan no podrán ser cambiadas, ahora veremos clases Mutables que estas si pueden ser modificadas una vez que han sido inicializadas.

NSMutableSet

Este contenedor puede ser inicializado de igual manera que el NSSet o puede ser inicializado sin ningún valor para posteriormente agregar algunos objetos.

Ahora veremos un ejemplo de ello:

NSMutableSet *lista = [[NSMutableSet alloc] init];
 [lista addObject:@"Algo"];
 [lista addObject:@"Genetico"];
 [lista addObject:@"Don Pedro"];

 for (id valor in lista) {
 NSLog(@"%@", valor);
 }

Como veremos inicializamos nuestro contenedor con el nombre de lista, luego agregamos en cada línea un objeto diferente con el método addObject, después para imprimirlo por medio de un for donde tomará todo el contenido de lista y gracias a id mostrara cada uno de ellos y será imprimido por NSLog.Ahora veremos una captura de la consola.



Ahora si queremos eliminar todos los objetos haremos lo siguiente por el método llamado removeAllObjects.

[lista removeAllObjects];

Ahora que pasa si queremos eliminar un objeto en especifico, bueno lo que tenemos que hacer es lo siguiente:

NSString *Cosa =@"Cosa";

 [lista addObject: Cosa];
 [lista addObject: Cosa];
 
 for (id valor in lista){
     NSLog(@"%@",valor);
  }
 
 [lista removeObject: Cosa];

 for (id valor in lista){
     NSLog(@"%@", valor);
 }

Ahora como observamos creamos una variable Cosa tipo String en la cual posteriormente la agregamos a lista, se agregó dos veces para demostrar que no podemos repetir el mismo objeto mas de dos veces, luego utilizamos el for para demostrar que se agregaro el objeto, después usaremos el método removeObject seguido del objeto que queremos eliminar para luego pasar al otro for para comprobar que se haya eliminado si todo salió bien verás algo como esto.


NSMutableArray

Este contenedor es lo mismo a usar un NSArray con diferencia de que pueden ser agregadas, modificadas y eliminadas, algo interesante que agregar es que podemos utilizar los métodos anteriores que utilizamos con NSMutableSet.

Ahora veremos un ejemplo agregando e insertando objetos:

 NSMutableArray *Arreglo = [[NSMutableArray alloc] init];
    
    [Arreglo addObject:@"Algo"];
    [Arreglo addObject:@"Pasa"];
    [Arreglo addObject:@"Siempre"];
     
     for(id valor in Arreglo){
     NSLog(@"%@", valor);
     }
     
     [Arreglo insertObject:@"Inserte algo entre Algo y Pasa"];
    
    for(id valor in Arreglo){
        NSLog(@"%@", valor);
    }

Lo que hicimos fue agregar el objeto(lo mismo que en NSSet) luego demostramos que han sido agregados en el for, después insertamos un objeto en el index 1 esto quiere decir que se posicionará en la posición 1 y se recorrerán los demás hacia abajo, como podrán observar debajo.

Los métodos mas usamos son removeAllObjects que quita todos los objetos que esten dentro del contenedor, removeLastObject que quita el último objeto agregado del contenedor, removeObjectAtIndex que este remueve un objeto dependiendo del index que haya sido dado.

NSMutableDictionary

Este contenedor no es muy diferente a NSDictionary, ya que este te provee de los mismo con la diferencia que poder agregar y remover elementos.

A continuación veremos un ejemplo agregando objetos:


 NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
 
 [dic setObject:@"Primero" forKey:@"1"];
 [dic setObject:@"Segundo" forKey:@"2"];
 [dic setObject:@"Tercero" forKey:@"3"];

 for(id valor in dic){
    NSLog(@"%@", valor);
 }
 
 [dic setObject:@"Primero y Segundo" forKey:@"1.5"];
 
 for(id valor in dic){
    NSLog(@"%@", valor);
 }

Agregamos tres objetos con ciertas keys, luego comprobamos que están, ya comprobadas agregamos un objeto, usamos el for para verificar lo que sucedió:


Como podrán ver se agregó un nuevo objeto con que no puede ser insertada en una posición en especifico como NSArray.

Libro de referencia:
Objective-C for Absolute Beginners, Excelente libro se los recomiendo

lunes, 13 de febrero de 2012

Introducción a Titanium

Existen varias maneras de crear aplicaciones móviles ya sea por eclipse para Android o ya sea para Xcode para iOS, esto algunas veces sea vuelto complicado ya que esto conlleva tiempo tener que entender y aprender los dos ambientes de desarrollo.Afortunadamente existen algunas plataformas como Titanium que nos permiten hacer una aplicación  de manera nativa en Android e iOS con un lenguaje de programación muy conocido y práctico, para ello les mencionare una introducción para que se enteren de que trata muy bien Titanium.


Titanium es una herramienta open source lo que significa que es gratis, es fácil de usar ya que tiene una IDE similar a la de eclipse.


Este puede ser descargado por medio del link que está debajo.


El único requisito es registrarse ya que con ello, podrás descargar algunos modulos que podrás implementarlos en el desarrollo de app y dichos modulos serán enviados a tu cuenta.

Por el momento pasaremos por alto la instalación ya que esto no es complicado y tambien la instalación de  el simulador de Android ya que estamos suponiendo que has programado una app de Android en eclipse alguna vez.

Unos de los componentes que mas son usados en una aplicación son los botones con eventos, secciones que son llamados tabs, ventanas, alertas entre otros aquí les explicaré algunos ejemplos sencillos sobre como usar algunos componentes para ello les pondré dos capturas de un Android y de un iOS para que puedan ver los resultados.

Para comenzar crearemos un nuevo proyecto File/New/Titanium mobile project después le daremos nombre a nuestro proyecto como Ejemplo1 luego observaran en App Id esto com.gsgv.Ejemplo1, donde com significa company que es compañía en ingles y después de eso verán gsgv que esas son mis iniciales comúnmente ahi va el nombre de la compañía luego de eso, veremos que dice Ejemplo1 que es el nombre del proyecto.Si les quedó alguna duda dejaré una captura de pantalla de esto.


Ahora nos centraremos dentro de la carpeta Resources en el archivo app.js en el copiaremos y pegaremos el siguiente código, en el cual se hicieron dos secciones diferentes donde cada sección está compuesto de una ventana que contiene una etiqueta y un botón, dicho botón tiene un evento que al momento de dar click en el envia un mensaje de alerta.Todo está comentado para que esto sea entendible.

// Creamos el grupo de tabs
var tabGroup = Titanium.UI.createTabGroup();


//
// Creamos una ventana en la que agregaremos un label y un boton.Y la misma ventana será agregada a un tab que es una sección de la app.
//

//Creamos ventana
var win1 = Titanium.UI.createWindow({  
    title:'Tab 1',                        //Titulo de la ventana
    backgroundColor:'#fff'               //Color de fondo blanco
});
//Creamos el tab donde sera agregada la ventana
var tab1 = Titanium.UI.createTab({  
    icon:'KS_nav_views.png',             //Imagen que sera puesta en el tab
    title:'Soy Tab 1',                   //Titulo del Tab
    window:win1                          //Ventana que sera agregada
});

//Creamos una etiqueta
var label1 = Titanium.UI.createLabel({
 color:'#999',                        //Color del label
 text:'Yo soy la ventana 1',          //Texto dentro de la ventana
 font:{fontSize:20,fontFamily:'Helvetica Neue'},//Tamanio de letra y tipo de letra 
 textAlign:'center',                  //Texto alineado en el centro
 width:'auto'                         //Esta en auto lo ancho, esto significa que tomara el tamanio necesario nadamas
});
//Creamos un boton
var boton1 = Titanium.UI.createButton({
 title:'Boton 1',                     //Texto dentro del boton
 top:200,        //Posicion del boton
 width:300,        //Ancho del boton
 height:100        //Altura del boton
});
//Creamos un evento del boton
boton1.addEventListener('click', function(e){ //click significa que en caso de dar click una vez hacer lo siguiente
 alert('Hola desde el botón 1');           //Aparecera una alerta con el mensaje que tiene dentro
});
//Agregamos los componentes a la ventana
win1.add(label1);
win1.add(boton1);
//
// Creamos una ventana en la que agregaremos un label y un boton.Y la misma ventana será agregada a un tab que es una sección de la app.
//

//Creamos ventana
var win2 = Titanium.UI.createWindow({  
    title:'Tab 2',                       //Titulo de la ventana
    backgroundColor:'#fff'               //Color de fondo blanco
});
//Creamos el tab donde sera agregada la ventana
var tab2 = Titanium.UI.createTab({  
    icon:'KS_nav_ui.png',
    title:'Soy Tab 2',
    window:win2
});
//Creamos una etiqueta
var label2 = Titanium.UI.createLabel({
 color:'#999',
 text:'Yo soy la ventana 2',
 font:{fontSize:20,fontFamily:'Helvetica Neue'},
 textAlign:'center',
 width:'auto'
});
//Creamos boton
var boton2 = Titanium.UI.createButton({
 title:'Boton 2',
 top:200,
 width:300,
 height:100
});
//Creamos el evento del boton
boton2.addEventListener('click', function(e){
 alert('Hola desde el botón 2');
});
//Agregamos elementos a la ventana
win2.add(label2);
win2.add(boton2);



//
//  Agregamos los tabs que usaremos al tab group
//
tabGroup.addTab(tab1);  
tabGroup.addTab(tab2);  


// Abre el tabGroup esto significa que abrira todas las tabs que han sido agregadas
tabGroup.open();


Y como prometí colocare dos capturas de pantalla la primera con Android y la segunda con iOS.

Android


iOS



Links de referencia:

Logotipo de Titanium


Smartphones y Computadoras Portátiles


Comparación de algunos smartphone's


iPhone 4s


Características sobresalientes 
  • Procesador Apple A5 de doble núcleo
  • Sistema operativo iOS 5
  • Memoria RAM 1GB
  • GSM/CDMA
  • Batería de duración de hasta 8 horas en conversación vía 3G, 9 navegación web vía Wifi, 10 horas con vídeo y hasta 40 en modo música.
  • Camara 8 megapíxeles retroiluminado
  • Graba 1080p
  • Asistente personal Siri
  • Disponible en 16, 32 y 64 GB
  • GPS
  • Cámara frontal de 2.0 megapíxeles.
  • Precio en contrato entre los $3,899.00 hasta $8,669.00
  • Resolución de pantalla 960x640.
Ventajas
  • Puedes tomar fotografías de manera profesional.
  • Tiene una gran velocidad de booteo, no hay lags, o freeze’s
  • Buen smartphone para gente.
  • Gracias a su procesador puedes disfrutar de juegos en HD con una calidad comparable a las de una consola de videojuegos.
  • Su asistente Siri te ayuda en cualquier problema que tengas y gracias esto complementa su accesibilidad.
  • Tiene servicio iCloud dicho servicio es como una memoria USB pero en la red virtualmente sincronizada a todos tus dispositivos de Apple.
Desventajas
  • Tiene problemas de batería, debido a que se calientan demasiado por gran tiempo de usó.
  • Siri no esta disponible para todos los idiomas.
  • Su precio es muy caro.
  • Su sistema operativo no permite instalar aplicaciones externas.
  • iCloud está limitado hasta 5GB y para almacenar mas tienes que pagar.

Conclusión

Nos permite correr muchas aplicaciones de manera rápida, tiene gran accesibilidad muy bueno para personas con alguna discapacidad visual, buen telefono para los fotografos ya que toma fotos casi perfectas, es excelente para un profesionista que regularmente usa mucho el mail, y se mantiene siempre en contacto con la gent,ya que con su antena GSM/CDMA puede ser usado alrededor del mundo.


HTC Evo 4G


Características sobresalientes
  • Procesador Snapdragon de 1 GHz.
  • Sistema operativo Android 2.3 Gingerbread
  • 1GB RAM
  • Memoria RAM 512 MB.
  • Cámara de 8 megapixeles.
  • Salida HDMI
  • Cámara frontal de 1.3 megapixeles.
  • Tarjeta microSD hasta 32GB, 8 GB incluida.
  • Antena CDMA, WiMAX y soporte para redes 3G.
  • Duración de pila hasta 9 h 20 min (2G) Y hasta 7 h 45 min (3G)
  • Resolución de pantalla 540 x 960 pixels
  • Precio en contrato entre los $1,899.00 hasta $5,669.00
Ventajas
  • Puedes hacer video llamadas.
  • Tiene la capacidad de compartir su acceso a internet hasta con 8 dispositivos.
  • Conector HDMI para reproducir su contenido en televisores.
  • Delgado comparandolo con las características que tiene, con otros equipos.
Desventajas
  • Tiene una batería con muy poca vida.
Conclusión

Este smartphone consta de unas características peculiares ya que su velocidad de 4G y la opción de manejar múltiples ventanas en internet le da ventaja a sus usuarios de estar enterados de todo en todo momento.Al igual que el iPhone 4s tiene una antena CDMA que nos permite ser usado alrededor de mundo.
Comparación de computadoras portatiles


Samsung ChromeBook


Características sobresalientes  
  • Peso de 3.26 libras.
  • Pantalla de 12.1 pulgadas.
  • Batería Li-ion con más de 8.5 horas de uso continuo.
  • Procesador Intel AtomTM Dual-Core.
  • Wi-Fi con banda doble y 3G World-mode (opcional) integrados.
  • Webcam de alta definición con micrófono con cancelación de ruido.
  • 2 puertos USB 2.0.
  • Ranura para tarjeta de memoria 4 en 1.
  • Minipuerto VGA.
  • Teclado Chrome de tamaño estándar.
  • Panel táctil completamente interactivo de gran tamaño.
  • 2 GB de memoria RAM.
  • Memoria interna SSD de 16 GB.
La Samsung Series 5 ChromeBook puede ser comprada desde Amazon, Best Buy, Ebay entre otros a un precio de $429.00 dólares para la versión WiFi y $499.00 dólares para la versión 3G.


Ventajas

Debido a la combinación del sistema operativo Chrome OS y la memoria principal SSD conforman una combinación que permite arrancar la ChromeBook en menos de 10 segundos.La batería nos permite una navegación web de un aproximado de 8.5 horas y con reproducción de video bajaría hasta las cinco horas.Todos los logs, historial entre otras podrá ser almacenada en tu cuenta de Google con este gran beneficio no perderíamos nuestros datos.


Desventajas

Una de las principales desventajas es el precio de la Samsung Series 5 ChromeBook ya que con ello te podrías comprar un iPad, una tablet Android, una laptop e incluso una Mac, realmente este nuevo producto es una mala apuesta por parte de Samsung y también por parte de Google porque por un lado Samsung no vende sus productos ya que la competencia tiene otros y con mejores características y por parte de Google la mayoría de la gente no conocerá su sistema operativo ya que no es muy factible el precio de los portadores de dicho sistema operativo.

Conclusión 

No es una buena inversión ya que puedes comprar con el mismo dinero un smartphone y tener las mismas funciones pero con la opción de tenerlo en tu bolsillo, aunque es muy rápido.






MacBook Pro 13,3 edición 2011




Características sobresalientes
  • Procesador Intel Core i5 (Sandy Bridge) con dos núcleos a 2,3 GHz.
  • 4 Gbytes de memoria SDRAM DDR3 1333 MHz.
  • Disco duro SATA con 500 Gbytes de capacidad.
  • Gráficos integrados Intel HD 3000 con 384 Mbytes de memoria compartida.
  • Pantalla de 13,3 pulgadas con resolución 1280 x 800 píxeles.
  • Webcam FaceTime HD.
  • Unidad SuperDrive 8x.
  • Slot para tarjetas de memoria con soporte SDXC.
  • Puerto FireWire 800.
  • 2 puertos USB 2.0.
  • Puerto Thunderbolt: Mini DisplayPort (Light Peak)
Esta Mac puede ser comprada en Amazon, Best Buy, iStore,Walmart, Sams su precio ronda dentro de los $1,199.99 dólares y en $1,499.99 con un disco duro de 750GB.

Ventajas

  • Hay descuentos para estudiantes tales descuentos pueden ser de 30%.
  • Son fáciles de usar si no se tienen conocimiento sobre computadoras gracias a su gran sistema operativo que tiene.
  • No existen virus en Mac, posiblemente hay uno que otro pero esto regularmente se tratan de evitar mediante updates.
  • Son duraderas, gracias a su estructura de unibody.
  • Tiene un gran consumo eficiente de memoria.

Desventajas

Tienen un alto precio ya que si la comparamos con algunas laptops con exactamente las mismas características veremos que están mas baratas las que tienen Windows, pero como dice el dicho hay veces que lo barato sale caro por eso es una gran inversión, invertir en una ya que dura mas que esas laptops con Windows.Son incompatibles con gran variedad de software ya que casi el 80% de las personas usa Windows.Repararlas sale muy caro y solamente los hacen en los centros mac.

Conclusión

Macs son bonitas, PCs son feas.Las desventajas no son malas ya que es muy difícil que una Mac se te descomponga.

Viendo los diferentes dispositivos se llega a la conclusión de que para tener una computadora portatil tienes que ser una persona tiene que dedicar tiempo y concentrarse en un trabajo especifico en el cual puedes observar las cosas de manera agradable que a diferencia de un smartphone que es algo incomodo, ya que en el solo observarias una pequeña parte.Un smartphone es un dispositivo que regularmente se usa para estar en contacto con personas mediante redes sociales, algún tipo de mensajería instantanea, mail y algunas aplicaciones útiles al usuario, con esto ahorra el usuario tener que cargar con una computadora portátil y tiempo.

Links de referencia: