iOS SDK

Ξ 22 comentarios

Cómo programar apps para iOS #1: Instalación y primera app

por Vertig0
Cómo programar apps para iOS #1: Instalación y primera app

Xabadu ya cumplió una parte de la promesa, así que vengo para cumplir la otra parte y dar inicio a la saga de tutoriales donde aprenderemos a crear aplicaciones para iOS.

En esta primera parte vamos a ir a lo más simple: La instalación (con revisión) y la primera aplicación, la cual será el siempre bienvenido “Hola Mundo”.

¿Donde?

¡Adivinen!

¡Exacto!, después del salto (Les advierto que salió laaaaaaaargo).

Me robaré Aprovecharé la introducción hecha por Xabadu en Como Aprender a programar apps para Android y les explicaré como lo haremos acá:

I.- ¿Cómo se estructurará esta saga?

Bien, la idea es que luego de este tutorial, empecemos a hacer “mini-aplicaciones” en las cuales aplicaremos distintas cosas que, a medida que se expliquen, iremos aprendiendo.

Con el paso de los números de esta saga, iremos haciendo aplicaciones más complejas (pero no esperen programar Facebook) e ir integrando lo que se vaya aprendiendo en números anteriores.

¿Por que no llevar un orden estilo “libro a programación”?

Hay varias razones, pero las 2 principales son que:

1.- Yo no soy ningún experto.

2.- Ese método, generalmente, se vuelve aburrido y difícil de seguir.

II.- ¿Es necesario saber programar? ¿En qué lenguaje?

Sí, partiremos de la base que se conocen conceptos básico de programación y que han hecho alguna que otra cosilla con códigos, pero nada complejo, sabiendo las bases y manejando a un nivel medio-bajo algún lenguaje de programación debería bastar para empezar a hacer nuestras aplicaciones nativas.

(Si no manejan los conceptos básicos, pueden partir revisando esta saga: http://www.comolohago.cl/como-aprender-a-programar-y-no-morir-en-el-intento-parte-1/.)

III.- Momento que soy lento, ¡¿aplicaciones nativas?!

(Descaradamente usaré exactamente lo mismo expuesto por Xabadu. ¡Trabajo en equipo!)

Si, esta saga cubrirá el desarrollo de aplicaciones para iOS de forma nativa. Actualmente hay una serie de aplicaciones y frameworks que permiten crear aplicaciones móviles multiplataforma  (Android, iOS, Blackberry, Windows Phone, etc.) utilizando una sola tecnología de desarrollo (habitualmente Javascript o algún otro lenguaje). En este caso no las cubriremos, pero si son una alternativa a tener en cuenta, considerando las ventajas y desventajas que presenta cada una de ellas.

IV.- ¿Es esta la guía definitiva para crear apps en iOS?

No, no y sobre todo: no.

Como les comenté arriba, yo no soy ningún experto. La mayoría de lo que sé lo aprendí de manera auto-didacta y espero poder ayudar y ser el punto de partida. Sobre esto mismo, no espero no cometer errores y siempre voy a estar feliz de que me corrijan (ahora, si quieren usar insultos, se pueden ir por donde llegaron 😀 ) y aprendamos en conjunto. ¡De eso se trata Como Lo Hago!.

Y bueno, robada hecha la introducción: ¡Hi-yo, Silver!

1.- Instalación

Lo primero que tienen que saber, es que para hacer aplicaciones en iOS necesitan un Mac. Lo se, tampoco me gusta esta limitación, pero Apple no ha entregado sus herramientas para otras plataformas.

Se de personas que han usado un Hackintosh, pero no he visto ningún caso que se pueda calificar de exitoso.

Sabiendo esto, necesitamos instalar Xcode, pero ¿Que es Xcode? ¿Es un integrante de los X-Men?

Nope, Xcode es el entorno de desarrollo que nos facilita Apple (de manera gratuita) para realizar nuestra aplicaciones, Xcode se instala con varias utilidades extras que iremos viendo en el desarrollo de esta saga ( y si se me olvida, ¡recuérdenmelo!).

Para instalar Xcode, buscamos en el Dock de Mac el icono de la App Store:

01-icono-appstore

Segundo icono de arriba hacia abajo, con la A grandota.

Cuando abramos la aplicación de la Appstore, buscamos “Xcode” en el campo de búsqueda arriba a la derecha:

02-buscar-apstore

Realizada la búsqueda, luego de unos segundos, aparecerán los resultados:

03-Resultado

El primer resultado, el icono del plano con el martillo, ese es Xcode (Sí, el que dice Xcode). En este caso pueden ver que aparece un botón “Actualizar” porque ya esta instalado en mi equipo, pero en caso contrario, el botón dirá “Gratis” (Como se ve en el icono de la derecha).

Si presionan el botón (el que en el caso de ustedes dirá “Gratis”), cambiará de color y el texto dirá “Instalar App”. Presionan el botón nuevamente (con el texto nuevo) y les pedirá que ingresen su cuenta de la AppStore (la misma que usan para descargan aplicaciones).

04-cuenta

Si no tienen una cuenta, puede crearla con el botón “Crear ID de Apple”.

Luego de ingresar sus credenciales, la descarga se iniciará y en el Dock, en su icono de Launchpad se verá el progreso de la descarga:

05-descarga

El icono de la nave inter-espaciodimensional (el tercero de arriba a abajo) es su Launchpad.

Solo nos queda esperar que la descarga termine (puede demorar bastante, son 1.65 GB).

Terminado, abrimos Launchpad y le damos un click al icono de Xcode e iniciamos la instalación. Afortunadamente la instalación no requiere ninguna configuración compleja, es del tipo: Siguiente, siguiente, finalizar.

2.- Nuestra Primera App

Nota antes de partir: Durante la explicación me leerán usar “método” y “función” indistintamente, esto es una mala costumbre mía. La diferencia entre ambos, es que el método es un proceso que no retorna ningún resultado, mientras que las funciones sí. Ya están advertidos y me disculpo de antemano.

Al abrir Xcode (desde nuestra carpeta de Aplicaciones), nos recibirá una pantalla de bienvenida mostrándonos nuestros proyectos recientes (que en este caso estará en blanco) y preguntándonos que queremos hacer. Seleccionamos comer hasta morir “Create a new Xcode Project”.

06-xcode

Una vez seleccionada esta opción, aparecerá una ventana pidiéndonos que seleccionemos una plantilla para empezar a trabajar.

Con Xcode no solo podemos crear aplicaciones para iOS (Móviles), sino también para OS X (Escritorio), así que es importante que seleccionemos una plantilla para iOS. Afortunadamente esto esta bien delimitado.

07-templates

A la izquierda podemos ver un menú dividido en 2 secciones “iOS” y “OS X”, que a su vez tienes sub-menus. Nosotros, como se ve en la imagen, usaremos la opción “Application” dentro del menú “iOS”.

Esta opción nos permite elegir entre 7 plantillas o templates:

  1. Master-Detail Application: Se usa normalmente para aplicaciones con información “jerárquica”. La plantilla viene con tablas ya integradas para que ingresemos la información y contemos con un listado de algo, por ejemplo noticias.
    Viene preparado para editar, borrar y agregar elementos , y para que al hacer tap (así le vamos a decir a los “clicks” en el teléfono. ¿Alguien se opone? ¿Nadie? ¡Yei!) en un encabezado nos lleve al detalle de esta noticia.
  2. OpenGL Game: Es bastante auto-explicativo, la plantilla viene preparada para realizar juegos usando el motor de OpenGL, por ahora estamos bastante lejos de empezar a ver cosas por este lado.
  3. Page-Based Application: Nos ahorra el trabajo de hacer que la aplicación funcione con páginas (como una revista). Cuenta con todo para agregar páginas y hacer fácil el paso de una a otra. Se usa principalmente en iPad.
  4. Single View Application: Una plantilla bien sencilla, solo viene con una vista (sección o como lo quieran llamar, es lo que el usuario ve). Esta es la plantilla que usaremos en la mayoría de los casos.
  5. Tabbed Application: Es bastante común ver aplicaciones con pestañas (botones al pie de la aplicación para pasar de una sección a otra). Bueno, esta es la plantilla que viene con eso pre-armado.
  6. Utility Application: Bastante sencilla también, viene con 2 vistas y con la transición de una a otra. Se utiliza para aplicaciones simples como las del clima o las conversoras de moneda.
  7. Empty Application: No se si cuenta como plantilla ya que es la ausencia de cualquiera de las anteriores, es una aplicación con lo absolutamente básico para que funcione y nada más.

No importa que plantilla seleccionemos, ninguna nos priva de hacer algo, solo viene con trabajo armado. Puedo seleccionar la plantilla número 1, pero nada me impedira integrar pestañas en esa aplicación

Como mencioné en el listado, generalmente usaremos la plantilla número 4. Aunque las otras nos ahorren trabajo, lo que intentaremos en esta saga es aprender y lo mejor para aprender, es hacer.

Ya seleccionada la plantilla nos aparecerá una ventana pidiéndonos información de la aplicación que vamos a hacer.

08-informacion-app

Podemos ver que nos pide algunos cuantos datos, así que pasemos a describirlos:

  • Product Name: Es el nombre de la aplicación que vamos a crear. En este caso no lo hice, pero el nombre puede llevar espacios. (Se puede cambiar, por si se arrepienten del nombre)
  • Organization Name: Es el nombre de la compañía o persona que esta realizando la aplicación.
  • Company Identifier: Es el identificador de la compañía o persona dueña de la aplicación, si bien no es obligación, se recomienda fuertemente el formato que se ve en la imagen, el cual es, la dirección web de lo compañía, en dirección opuesta. En el caso de Como Lo Hago es cl.comolohago, en el caso de ejemplo.ca sería ca.ejemplo. El motivo de esto es intentar hacer el identificador único. Este nombre no es el que se verá en la App Store como desarrollador de la aplicación. El nombre que aparece ahí es el nombre del dueño del certificado con el que se firma la aplicación (no veremos eso en este número, pero si que lo veremos.)
  • Bundle Identifier: Es el identificador de la aplicación, es de uso interno y esta compuesto por el identificador de la compañía, unido por un punto (.) con el nombre de la aplicación sin espacios ni caracteres especiales. Si el nombre de la aplicación cambia, el identificador no cambiará, pero esto no será un problema.
  • Class Prefix: Prefijo de las clases. Cada vez que creen un archivo, automáticamente se sugerir ese prefijo en su nombre. Es opcional y al momento de crear un archivo se puede modificar o eliminar.
  • Devices: Podemos seleccionar para que dispositivos vamos a desarrollar. Iphone, Ipad o Universal (ambos). La elección de uno no impide agregar el otro después, sin embargo se recomienda tomar esta decisión en este momento. Nosotros trabajaremos con iPhone.
  • Use Storyboards: Los Storyboard son formas de presentar y manejar las vistas y navegación de la aplicación. Se integraron en iOS 5 y tienen tantos amigos como enemigos, personalmente no me gustan mucho, pero tampoco les he dado muchas oportunidades. Los veremos, sin duda, pero por ahora los dejaremos fuera.
  • Use Automatic Reference Counting: El uso de memoria, aun es un tema delicado en el desarrollo móvil (y debería serlo en todo tipo de desarrollo), por lo que manejarla de manera correcta es escencial. Esta opción (Conocida como ARC) hace la parte básica de ese trabajo por nosotros, aunque también puede darnos algunos dolores de cabeza en desarrollos un poco más complejos. Personalmente creo que las ventajas que nos da, son muy superiores a los problemas que nos puede ocasionar. Aún así, esta opción tiene firmes detractores. Pero bueno, para gustos, colores.
  • Include Unit Tests: Desafortunadamente esto no es algo que se pueda ver a la pasada, a grandes rasgos nos ayudaría a generar un código mas robusto y estable, pero lo veremos mucho más adelante.

Completamos la información solicitada y al presionar “Next”, nos preguntará donde queremos guardar la aplicación, aunque les recomiendo que creen alguna carpeta para llevar sus proyectos, la decisión es completamente de ustedes. Seleccionando el lugar donde guardar la aplicación ya habremos creado la base de nuestra aplicación.

09-aplicacion-creada

Xcode no mostrará bastante más de lo que veremos ahora, sin embargo revisar todo lo que trae nos tomaría demasiado tiempo y para esta número de la saga, veremos lo más básico.

Arriba  a la izquierda podemos ver, en un boton “Play”, la acción “Run” con la cual podremos ejecutar la aplicación en el simulador de iPhone, de iPad o en nuestro equipo, pero para esto último necesitaremos haber comprado e instalado un certificado de desarrollo. Si apretamos en “Run” se abrirá el simulador con una aplicación en blanco (en gris realmente).

10-aplicacion-en-blanco

En este caso, para el ejemplo, estamos simulando un iPhone 5 con una versión de iOS de 6.1.

(Volveré a poner la imagen de Xcode acá para seguir revisando.)

09-aplicacion-creada

Muy bien, al lado de “Run”, tenemos “Stop” que como se imaginarán sirve para detener la simulación de la aplicación.

A la derecha de esto tenemos una barra donde podemos seleccionar en que dispositivo y en que versión de iOS queremos hacer la simulación, en el ejemplo se ve que estamos simulando en un iPhone con iOS 6.1

Abajo de esto tenemos 3 secciones, aunque en la imagen podemos ver 2:

  • La zona de navegación (izquierda de la foto):
    • Acá tenemos los archivos del proyecto y el proyecto como tal, tenemos 3 carpetas que a su vez tiene sub-carpetas o archivos:
      • La carpeta de nuestra aplicación: que lleva el nombre de nuestra aplicación. Acá tenemos 5 archivos (porque la plantilla que elegimos usa estos 5 archivos), 2 de ellos son “la cabeza” de la aplicación y llevan por nombre AppDelegate.h y AppDelegate.m. Para ponerlo de una manera simple, veamos la aplicación completa como un “objeto”, mientras que los demás archivos van a manejar partes de la aplicación y se van a comunicar entre sí, el AppDelegate va a manera la aplicación como tal, definirá que se hace al abrir, al cerrar, al minimizar, al recibir una notificación, etc…
        La plantilla que escogimos viene con una vista creada. Una vista es algo que el usuario verá (do’h) y normalmente se divide en 3 archivos. Un .h o cabecera, que es donde se hacen la definiciones de los métodos o funciones y/o propiedades de la vista; Un .m o implementación que es donde se declara que hará cada método y donde se encuentra el ciclo de vida de la vista (lo veremos en un momento más) y un .xib que es la vista propiamente tal.
      • La carpeta Supporting Files: Contiene archivos de ayuda y/o configuración de nuestra aplicación.
        • El archivo .plist contiene las configuraciones básicas, como nombre, identificador, orientaciones soportadas, etc.
        • El archivo .strings, con este archivo podemos usar cadenas de texto “localizadas”, podemos agregar idiomas y, usando el método correcto, reemplazar automáticamente los textos de nuestra aplicación según el idioma en el cual está el dispositivo sin necesidad de agregar miles y miles de comprobaciones.
        • main.m es el primer archivo que se ejecuta, este contiene la función principal de la aplicación, la cual realiza la primera llamada y donde se da inicio al ciclo de vida de la aplicación (Sí, sí, dije que lo veríamos en unos minutos, ya viene, ya viene).
        • El Archivo .pch, en el cual podemos pre-cargar clases y hacer definiciones, todo lo que definamos acá estará disponible para todas las clases sin necesidad de incluirlas una a una. Es importante no abusar de este archivo ya que puede perjudicar el desempeño de la aplicación.
        • Las imágenes bases: Son 3 imágenes negras con distintos nombres. Estas imágenes , que obviamente se pueden cambiar, son la imagen “splash” de la aplicación, la imagen que veremos mientras la aplicación hace las cargas básicas antes de poder ejecutarse.
          Son 3 porque iPhone tiene 3 resoluciones posibles. No-Retina de 320 x 480 (Default.png), Retina de 640 x 960 (exactamente el doble, [email protected]) y retina de 4 pulgadas 640 x 1136 (iPhone 5, [email protected]).
      • La carpeta de frameworks: Contiene los frameworks básico para poder desarrollar aplicaciones en iOS, podemos (y probablemente tendremos) agregar más, tantos propios de iOS como algunos externos desarrollados por terceros. La verdad es que no es necesario agregarlos en esa carpeta, pero para mantener un orden, se recomienda.
      • La carpeta Products: Cuando realizamos una compilación, se genera un archivo .app que es referenciado en esta carpeta.

Podemos crear y eliminar carpetas en la zona de navegación, pero estas solo son virtuales y nos ayudan a mantener un orden visual. Físicamente las carpetas no se crean y nos encontraremos con una ensalada de archivos a medida que vayamos creandolos

  • La zona de edición (derecha de la foto, centro de la pantalla en Xcode): Según el archivo que estemos editando, acá es donde codearemos o diseñaremos o cambiaremos opciones. En la imagen podemos ver la opción “iOS Deployment Target” dentro de “Project”, acá definiremos la versión mínima de sistema operativo. Si bien el porcentaje de equipos que actualizan a la última o penúltima versión es muy alta, siempre se recomienda incluir algunas versiones más, al menos desde 5.0. Para este ejemplo lo mantendremos en 6.1 y si quisiéramos probar la aplicación en un equipo con un iOS menor, nos arrojaría un error.

Como les había dicho, quedaron muchísimas cosas más por ver en Xcode, pero las iremos viendo a medida que avancemos con la saga. Espero haber cubierto lo más básico para empezar.

Luego de aprender lo más aburrido básico, ¡vamos al código!

Antes de mirar el código, tenemos que saber que el lenguaje de programación es Objective-C, el cual es una extensión de C y es orientado a objetos.
Este lenguaje nos va a cambiar varios paradigmas como la declaración de funciones, la forma de llamar a los métodos, etc… pero sin asustarse, si bien al principio cuesta un poquito acostumbrarse luego lo llegaremos a querer.

Haremos una aplicación que tendrá un campo de texto, en la cual el usuario ingresará un texto y este aparecerá o reemplazará un texto en pantalla.

Si vamos a ViewController.m encontraremos los siguientes:

@interface ViewController ()// 1

@end

@implementation ViewController

- (void)viewDidLoad//2
{

    [super viewDidLoad];

}

- (void)didReceiveMemoryWarning//3
{

    [super didReceiveMemoryWarning];
}

@end

Dejé algunos comentarios en el código para poder explicar de que se trata cada parte.

  1. En esta parte podemos declarar métodos privados. Si en algún momento creamos una instancia de esta clase en otro lado, podemos acceder a los métodos declarados en el .h, pero no a los declarados acá, a estos solo se puede acceder desde esta misma clase.
  2. Como les mencioné antes, las clases tiene un ciclo de vida (¡ajá! ¿vieron que sí lo nombré?). En el caso de la clase ViewController, el método ViewDidLoad es el primero es el primero en ser llamado (En estricto rigor no, el primer método es el inicializador, pero de los que vemos acá es el primero método). Este método se llama inmediatamente después de que la vista es cargada en la memoria, todo lo que suceda acá, se hará antes que el usuario pueda ver la vista.
    Existen otros 2 métodos que no son obligatorios, el método ViewWillAppear y ViewDidAppear, el primero se llama cuando la vista ya está lista para se mostrada y el segundo se llama inmediatamente una  la vista se mostró, no adentraré mucho en esto en este momento, pero lo veremos en uno de los próximos números.
  3. Este método es llamado automáticamente cuando la aplicación recibe una alerta de memoria, aquí tenemos que liberar todo lo que sepamos que no sea esencial para evitar la caída (cierre o crash) de la aplicación.

Ahora, si vamos a ViewController.h, veremos:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

Acá podemos ver que hay muy poco, una importación del Framework básico, la declaración de la clase ViewControler que hereda de UIViewController (Es decir que tiene todo lo que esta clase tiene, más todo lo que le agreguemos). El nombre es similar, pero ViewController es el nombre que nosotros le dimos a nuestra clase (en verdad lo hizo Xcode), bien podría llamarse LaloLandasController o PanConPalta.

Es aquí donde se declaran los métodos públicos, las variables privadas y las variables públicas (propiedades) como veremos más adelante (pero en este mismo número).

Si seleccionamos ViewController.xib, no veremos código (podríamos, pero no lo haremos) más bien veremos el Interface Builder, que es el entorno de diseño gráfico de las aplicaciones. Interface Builder está integrado en XCode desde, si mal no recuerdo, la versión 4 de este, antes de esto era una aplicación aparte (aunque se instalaban en conjunto) y cuenta la leyenda, que antes de eso, no existía y tenían que hacer todo el diseño en base a XML, lo cual no sería un problema si fuéramos este sujeto:

11-overly-manly-man

pero no lo somos.

Como decía, al abrir el . xib, veremos lo siguientes:

12-interface-builder

Podemos fácilmente ver la imagen dividida en 3 partes:

  • Izquierda: Acá podemos ver todos los objetos que vayamos agregando a través del Interface Builder (abajo) y 2 elementos bases (arriba):
    • File’s Owner: Este elemento hace referencia al objeto dueño de la vista, es decir al objeto al cual se llamó a (uno de) sus métodos “init” (¿Recuerdan que les dije que ViewDidLoad no era en realidad el primero en ser llamado, si no que era el método “init”? Bueno, a este me refiero. Se que es un poco confuso ahora, pero a medida que vayamos realizando aplicaciones, espero que todo esto tendrá más sentido). En este caso particular, el File’s Owner es la clase viewController que creamos (o que la plantilla creo por nosotros (¿Es válido poner paréntesis dentro de paréntesis?))). Si creáramos otra vista que se llamara superVista, el File’s Owner sería el objeto superVista.
    • First Responder: Los objetos (van a leer mucho esta palabra, y es que en al programación orientada a objetos, prácticamente todo es un objeto), que tengamos agregados, crearán una cadena de jerarquía en tiempo de ejecución (o runtime). Esta cadena variará según lo que ocurra en nuestra aplicación. Por ej: En este momento podemos ver que tenemos un objeto “view” agregado (que por cierto, se agregó automáticamente), si agregáramos un campo de texto y en el momento de usar la aplicación le diéramos el foco a ese campo de texto, este pasaría a ser el First Reponder y respondería (si pudiese) a los mensajes que enviemos al First Responder o sería el objetivo si es que solicitamos hacer algo sobre el First Responder, una vez que el campo de texto pierde el foco, dejaría de ser el First Responder, bajando uno o más niveles en la cadena de jerarquía.
  • Centro: Este es el “lienzo” acá se diseñan las vistas. No nos confundamos, en la imagen se puede ver un rectángulo gris, pero este representa al objeto “view” que esta agregado. El “lienzo” como tal, es el fondo blanco a cuadros.
  • Derecha: En la sección donde dice “No Selection” veremos las propiedades, configuraciones e información de los objetos que seleccionemos. Abajo de esto, tenemos los objetos “nativos” que podemos agregar a la vista: Botones, campos de texto, tablas, pickers, loaders, etc.. además si es que hemos agregado imágenes, también las podremos ver acá.

Uf! Costó pero llegamos, ahora sí que sí, ¡código!.

Wo wo wo wo, ¿que y que pasa con los AppDelegate? ¿No son importantes?. ¡Sí que lo son! ¡y mucho! Pero no deben ser vistos a la rápida y por ahora no los ocuparemos, así que prefiero que esperemos antes de verlos.

¿Ya, puedo ir al código o me seguirán haciendo preguntas?…. Sí, sí pueden ir al baño…..

Ahora que están de vuelta, ¡código!

Lo que hará aplicación, como creo dije antes, será solicitar al usuario ingresar un texto en un campo de texto y al presionar un botón este texto se mostrará en otra otro lado de la vista (o reemplazará al que ya exista).

Entonces, para esto necesitamos 3 cosas:

  1. Un campo de texto: El nombre de esta clase es UITextField, la parte de TextField se entiende y el prefijo “UI” viene de User Interface y se le da a los elementos que son usados en la parte que ve el usuario. (labels, tablas, botones, campos, datepickers, etc..)
  2. Una etiqueta: El nombre de esta clase es UILabel, misma explicación de arriba.
  3. y un botón: UIButton.

Les aviso que haré que nos demos la vuelta larga en más de una ocasión, pero todo esa en pro del aprendizaje (¡La educación nos gobierna!).

Entonces, partamos por crear nuestro campo de texto, volvamos al viewController.h y agreguemos lo siguiente:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

{

    __weak IBOutlet UITextField *campoDeTexto;

}

@end

Primero que todo, vemos que agregamos unas llaves, las llaves se usan parar declarar variables privadas, la clase misma puede acceder a ellas, modificarlas, etc… pero si creáramos una instancia de esta clase en otra parte, no podríamos acceder a la variable “campoDeTexto” por ser privada (esta dentro de las llaves).

En segundo lugar, vemos algunas cosas raras:

  • __weak: Este modificado se usa para decirle a nuestra aplicación, que cuando el objeto deje de ser utilizado, puede liberal la memoria tranquilamente.
  • IBOutlet: Nosotros podemos crear elementos de interfaz de usuario (UI) sin agregarlos directamente a través del Interface Builder, pero los que si son a través de él, tienen que tener el modificador “IBOutlet” (IB viene precisamente de Interface Builder). Si la variable no tiene este modificador, la podremos usar igual, pero no la veremos en el Interface Builder y ahora queremos eso.
  • UITextField: Es el tipo de variable, en este caso un campo de texto.
  • *campoDeTexto: campoDeTexto es el nombre de la variable, puede ser el que sea mientras no tenga espacios ni caracteres especiales y mientras no este usado anteriormente (independiente de que sea de otro tipo, no puede haber un campo de texto y un botón con el mismo nombre.). El “*” indica que es un puntero, al ser un puntero se esta haciendo referencia al espacio en al memoria que ocupa esta variable, por lo que cualquier cambio que hagamos sobre ella en cualquier parte, hará que esa modificación sea permanente. No se preocupen si esto no queda claro, para efectos prácticos, todos los objetos de desarrollo en iOS son punteros, así que el “*” va prácticamente (ojo, prácticamente) siempre.

Una vez que escribamos esta linea (y cerremos con “;”) veremos que a la izquierda aparecerá una circulo vacío, este el aviso de XCode diciendo “¡Hey! Creaste un elemento para el Interface Builder, pero el no tiene que idea que lo hiciste, ¡avísale!” ¿y como le avisamos?. ¡Conectando!

Volvamos al .xib y seleccionemos el File’s Owner y a la izquierda, en la parte donde aparecen las propiedades del objeto seleccionado (donde decía “No Selection”), aparecerán 6 pestañas. La última (con el icono de la flecha) se llama Connections Inspector o Inspector de Conexiones y es precisamente a donde tenemos que ir a buscar nuestro objeto recién creado.

13-connections-inspector

Abajo de esto, donde están los elementos nativos para agregar a las vistas, buscamos un UITextField y lo arrastramos sobre el “view” (el rectángulo gris) y le dan el ancho que deseen. Lo acomodaremos arriba.

(Vamos a hacer algo por ahora, seleccionen nuevamente el File’s Owner, pero ahora vayan a la primera pestaña con el icono de una hoja con la punta doblada, se llama ‘File Inspector’, acá busquen la opción “Use Autolayout” y desmarquenla, esta es una opción que ayuda a organizar los elementos dentro de la vista, pero no esta soportada antes de iOS 6, así que la sacaremos)

Agregado el campo de texto, nuestra vista se verá algo así:

14-campo-de-texto

Bien, ahora tenemos el objeto declardo en el .h y agregado en el Interface Builder, con eso debería bastar…¡NO SEÑOR!.

Si volvemos al Connections Inspector del File’s Owner, veremos que “campoDeTexto” tiene un circulo vació a la derecha, que si ponemos el mouse encima, aparece un símbolo de batman “más”.

Tenemos que hacer click en ese circulo y sin soltar arrastramos hasta el campo de texto que pusimos en la vista, cuando ya estemos sobre el campo, soltamos el mouse. Aparecerá una linea conectando ambos elementos.

Si se fijan, solo lo pueden conectar con el campo de texto y no con el view, esto es por “campoDeTexto” esta declarado como UiTextField y no nos dejará que lo conectemos con algo de otro tipo, sin embargo, si tuviésemos más campos de texto, nos dejaría conectarlo con cualquiera (pero solo con uno). Al hacer esto, el círculo se llena y aparece que “campoDeTexto” está conectado con un Text Field.

Ahora si están conectados, por lo que cualquier referencia a “campoDeTexto” será una referencia al elemento que agregamos en al vista.

Vamos ahora a agregar nuestro label, y aquí es donde tengo que confesarles que los hice trabajar de más (Muahahahaha), vamos a hacer las cosas en otra manera

Agreguemos un UILabel a nuestra vista justo debajo del campo de texto. No hemos agregado nada al .h.

En Xcode, arriba a la derecha tenemos 6 botones divididos en 2 grupos: “Editor” y “View” (y un botón solitario al final).

Si presionamos el botón central del grupo “Editor” (el icono donde aparecer un Smoking), dividirá nuestra pantalla en 2, dejando en “lienzo” arriba y una sección que nos muestra el código del archivo viewController.h abajo.

Si seleccionamos nuestro Label y luego presionamos el click derecho (el secundario) y sin soltar arrastramos hasta la sección donde nos muestra el código, veremos algo como esto:

15-conexion-label

Y al soltar, aparecera esto:

17-datos-boton

La ventana que nos aparece, nos pregunta por algunos datos:

  • Connection: Acá indicamos que ser una conexión tipo IBOutlet (existen otros tipos que veremos después)
  • Object: Indica quien será “dueño” del objeto, no es modificable.
  • Name: El nombre que le daremos a la variable, para el campo de texto usamos “campoDeTexto”, para este caso usaremos “texto”
  • Type: El tipo de la variable que crearemos, en este caso un UILabel.
  • Storage: Indica el tipo de relación con la variable, puede ser __weak (que ya explicamos) o __strong, con la cual el espacio no será liberado hasta que la variable deje de ser referenciada (y no solo que deje de ser utilizada). Este es además el valor por defecto, es decir, si no indicamos ninguno, la relación será de tipo “strong”

Introducimos el nombre y presionamos “Connect”, la conexión ya estará realizada y el objeto se agregará automáticamente a nuestro .h, dejándolo así:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

{

__weak IBOutlet UITextField *campoDeTexto;

__weak IBOutlet UILabel *texto;

}

@end

Podemos ver que el trabajo es mucho más sencillo así.

Ya solo nos queda agregar nuestro botón, en este caso será algo distinto, ya que (en este caso) no necesitamos tener una referencia al botón como tal, sino a la acción que hará cuando sea presionado.

Lo que haremos será agregar un botón (UIButton) de la misma forma que agregamos el Label, pero lo haremos debajo de las llaves y cambiaremos el tipo de “Connection” de “Outlet” a “Action”. Al hacer esto, los datos a llenar cambian a lo siguiente:

17-datos-boton

  • Connection: Igual que antes, pero esta vez indicamos que es un IBAction, una acción desde el Interface Builder.
  • Object: Lo mismo que antes.
  • Name: El nombre de la función o método. Usaremos “cambiarTexto”
  • Type: A diferencia del caso anterior, aquí no se indica que tipo de variable es, sino que se indica el tipo de variable que va a recibir la función. En este caso nos permite “id” o “UIButton” y es que las acciones desde el Interface Builder, solo nos permite enviar como parámetro 2 cosas, quien envía la acción (el botón) y/o en base a que evento lo envía. “Id” es un tipo “comodín” si indicamos que es este tipo, podremos pasar cualquier variable “nativa” de iOS (UILabel, UITextField, UIButton, etc…), pero no podremos pasar ninguna variable primitiva (int, char, float, etc…).
    Un detalle que se me había escapado, las variables del tipo UILabel o UIButton (las que soporta el comodín “id”) son objetos. Es un dato importante a tener en cuenta a futuro, aunque ahora no le veamos gran utilidad.
    Nosotros dejaremos “id” en este caso.
  • Event: Define en que momento se llamará la función, si presionan la lista despegable verán varios eventos, describiré los que se usan con UIButton (pero no exclusivamente con él).
    • Touch Cancel: A mi parecer el caso menos usado, el usuario no puede cancelar el toque, es el sistema como tal el que lo cancela, por algún error o necesidad del mismo.
    • Touch Down: La acción se llama al presionar el botón (antes de levantar el dedo)
    • Touch Down Repeat: La acción se llama al tocar el botón repetidamente. (Según la documentación de Apple, más de una vez)
    • Touch Drag Enter: La acción se llama cuando se arrastra el dedo hacia adentro del botón.
    • Touch Drag Exit: Lo mismo que la anterior, pero cuando se arrastra hacia afuera.
    • Touch Drag Inside: La acción se llama cuando se arrastra el dedo dentro del botón (y no hacia adentro).
    • Touch Drag Outside: Lo mismo que la anterior pero fuera del botón (y no hacia afuera).
    • Touch Up Inside: La más usada, la acción se llama al presionar el botón, pero esta vez, cuando el dedo es levantado. Nosotros usaremos esta.
    • Touch Up Outside: Lo mismo que la anterior, pero cuando se realiza fuera del botón.
  • Arguments: Como se explico en Type, la acción puede recibir 1 o 2 parametros, acá se indica cuando serán, si solo el “quien” (Sender) o el “quien y el cuando” (Sender and Event). Usaremos “Sender”

Seleccionado todo, presionamos “Connect” y nuestro .h quedará de la siguiente manera:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

{

__weak IBOutlet UITextField *campoDeTexto;

__weak IBOutlet UILabel *texto;

}

- (IBAction)cambiarTexto:(id)sender;

@end

Aprovechamos de ver como se declara una función:

  • “-” indica que es un método de instancia. También puede ser “+”, en este caso el método es de clase. La diferencia es que para llamar a los metodos de instancia, se tiene que crear una instancia, valga la redundancia, del objeto, es decir, llamar antes al método init. Los métodos de clase pueden ser llamados sin necesidad de hacer esto.
  • (IBAction) indica el tipo de variable que devolverá el método, en este caso es “IBAction” que indica que la acción “devolverá” todo lo que suceda producto de haber presionado el botón. Solo para los casos “IBAction” y “void” se omite el uso de “return” dentro de la función, para los demás tipos se debe finalizar el método con un “return <variable>” donde la variable debe ser del tipo indicado entre paréntesis (los < >, no van).
  • “cambiarTexto:” es el nombre del método, noten como los “:” son parte del nombre y es que en Objective-C los parámetros se entregan de una forma muy particular. (Que explico aquí abajo)
  • (id)sender es el tipo y nombre del parámetro, entre paréntesis se indica el tipo, en este caso “id” y fuera de él, el nombre del parámetro, en ese caso sender (que hace referencia al botón presionado).

Les comentaba lo particular del paso de parámetros en este lenguaje, esto es porque los parametros se declaran entre medio del nombre de la función.

Supongamos que queremos declarar un función que suma 2 número y devuelve el resultado (para efectos prácticos, todos serán enteros), esta se declararía así:

“-(int)sumarElNumero:(int)primerNumero conEsteOtroNumero:(int)otroNumero”.

Donde el nombre de la función es “SumarElNumero:ConEsteNumero:” y los parámetros son “primerNumero” de tipo int y “otroNumero” también de tipo int. La función además retorna un entero.

Este lenguaje tiene la característica de tener nombres de funciones muy pero muy largos, aunque eso tiene la ventaja de que es muy fácil saber que hacen

Ok, volvamos a lo nuestro.

Al crear la acción de esta forma (arrastrando), no solo se agrega la declaración del método en el .h, si no que la implementación del mismo en el .m, vamos a ver:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad

{

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

}

- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

- (IBAction)cambiarTexto:(id)sender {

}

@end

Como ven, la función está ahí y ya está, además, conectada con el botón.

Pero si ejecutamos la aplicación y presionamos el botón, no hará nada. Lo cual es lógico porque dentro de la función no hay nada. Así que agreguemos lo que necesitamos a la función:

- (IBAction)cambiarTexto:(id)sender {

    texto.text = campoDeTexto.text;

}

Lo que estamos diciendo es algo como “Al presionar y levantar el dedo en el botón, cambia la propiedad ‘text’ (que es el texto como tal) del objeto ‘texto’ (Que es el label que nosotros creamos) por el contenido de la propiedad ‘text’ (también el texto como tal) del objeto campoDeTexto (el text field que nosotros creamos)“.

No podemos decir:

- (IBAction)cambiarTexto:(id)sender {

    texto = campoDeTexto.text;

}

Porque “text” es un objeto de tipo UILabel y el texto de este objeto es una de tantas propiedades que tiene (y se llama ‘text’)

Hay otra forma de hacer que esto funcione, en el fondo le diremos lo mismo pero de otra manera:

- (IBAction)cambiarTexto:(id)sender {

    [texto setText:[campoDeTexto text]];

}

Estamos diciendo lo mismo, pero me parece bueno hacerlo de esta forma para que conozcan los paréntesis cuadrados o “corchetes”.

En Objective-C, las funcionen se llaman así:

[deQuienEsLaFuncion NombreDeLaFuncionConParametro:(parametro)];

o si tiene mas de un parametro:

[deQuienEsLaFuncion NombreDeLaFuncionConParametro:(parametro) yConOtroParametro:(otroParametro)];

o sin parámetros:

[deQuienEsLaFuncion NombreDeLaFuncion];

En nuestro ejemplo la función “setText” pertenece al objeto texto y la función “text” pertenece a campoDeTexto. La primera no devuelve ningún valor y la segunda devuelve el valor de la propiedad ‘text’ (Es decir, el texto que este escrito en el campo de texto).

Al estar anidadas (o sea, corchetes dentro de corchetes), pasamos el resultado de la función “text” inmediatamente como parámetro a la función “setText”, evitando tener que declarar una variable donde guardar el resultado.

El resultado es exactamente el mismo que en el caso anterior.

Como detalle final, vamos a ir al .xib, haremos doble click en el botón y cambiaremos el texto “Button” por “Cambiar”.

Además agrandaremos hacia los lados el Label y también haremos doble click para cambiar el texto, pero lo dejaremos en blanco. (No lo van a ver, pero está ahí, se los juro).

Hagan click en Run en Xcode y se abrirá el simulador con la aplicación (a veces se demora).

Escriba un texto en el campo de texto y presionen “Cambiar”:

18-aplicacion-funcionando

Luego del tutorial más largo de la historia de la humanidad, les recuerdo que como siempre esto fue:

Sello de GarantÍa CLH

Cualquier duda y/o comentario que puedan tener, los invitamos a dejarnos unas líneas en el área habilitada a continuación.

¡Hasta la próxima!

Comparte este tutorial

El culpable de todo esto

Responsable de transformar miles de k310 en w200, y sobrevivir para contarlo, Jorge Nitales tuvo sus inicios en los barrios bajos de Papúa y Nueva Guinea, en una exitosa empresa productora de Paraguas de Bambú. Luego de alcanzar fama y fortuna, lo dejó todo para jubilar a la edad de 16 años y dedicarse a la cosecha de tomates hidropónicos en la zona de Pemuco. Es ahí donde fue reclutado para CLH por Dexter, un asiduo comprador de la hortaliza. A la fecha se le adjudica el haber enseñado a miles de personas en cientos de países como teletransportarse y hacer el famoso Kamehamehá, rumoreándose fuertemente una Genkidama en el futuro próximo. Las baterías vienen por separado.

En los barrios marginales se le conoce como: Vertig0

Comentarios en Facebook

22 Comentarios

  • Excelente tutorial, en cuanto llegue a mi casa lo pondré en práctica ¿Seguirán subiendo tuts?

    • Hola Paul,

      Si, estamos subiendo constantemente.

      Saludos!

  • Genial!!!!!
    Muchas gracias. Un gran trabajo.
    Ya espero ansioso la segunda entrega …

  • Hola! excelente tutorial viejo.. estoy muy agradecido, aunque solo he podido probar algo con un hackintosh .. y si funciona xD
    Mi duda es si existen continuaciones de este magnífico aporte, porque la verdad he quedado muy pegado !
    Un saludo!!

  • muchas gracias, realmente me ha servido

  • En dado caso que no sea usuario Mac que me recomiendas, o no hay ninguna manera?

    • Don Norris,

      No, tener Mac es requisito excluyente, ya que el SDK no está disponible para otros Sistemas Operativos.

      Saludos!

  • Podrías publicar un tutorial de hacer una app y esta manipula la cámara y luego de tomar la foto montes un sticker o pegatina a la foto. Gracias!

  • @Xabadu,
    No hace falta tener Mac ya que con Vmware puedes poner una imagen de Mavericks en un momento. Yo mismo lo he hecho y programo en el portatil (Dell) con Xcode sin problema, así que excluyente no lo es del todo! :S
    @DonNorris, googlea un poco con Mavericks retail image Vmware y tendrás la solución al problema de no ser usuario Mac 😉

    • @Pau V. Gran tip, no estaba al tanto que era factible de esa manera. Gracias por compartir!

1 2 3

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Gente linda que nos quiere

Donde mas estamos