Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales...

40
Objective-C Curso práctico para programadores Mac OS X, iPhone y iPad Fernando López Hernández

Transcript of Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales...

Page 1: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

Objective-C

Curso práctico para programadores Mac OS X,

iPhone y iPad

Fernando López Hernández

Page 2: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

Objective-C. Curso práctico para programadores Mac OS X, iPhone y iPad Fernando López Hernández ISBN: 978-84-938312-7-1 EAN: 9788493831271 Copyright © 2012 RC Libros © RC Libros es un sello y marca comercial registrados Objective-C. Curso práctico para programadores Mac OS X, iPhone y iPad. Reservados todos los derechos. Ninguna parte de este libro incluida la cubierta puede ser reproducida, su contenido está protegido por la Ley vigente que establece penas de prisión y/o multas a quienes intencionadamente reprodujeren o plagiaren, en todo o en parte, una obra literaria, artística o científica, o su transformación, interpretación o ejecución en cualquier tipo de soporte existente o de próxima invención, sin autorización previa y por escrito de los titulares de los derechos de la propiedad intelectual. RC Libros, el Autor, y cualquier persona o empresa participante en la redacción, edición o producción de este libro, en ningún caso serán responsables de los resultados del uso de su contenido, ni de cualquier violación de patentes o derechos de terceras partes. El objetivo de la obra es proporcionar al lector conocimientos precisos y acreditados sobre el tema tratado pero su venta no supone ninguna forma de asistencia legal, administrativa ni de ningún otro tipo, si se precisase ayuda adicional o experta deberán buscarse los servicios de profesionales competentes. Productos y marcas citados en su contenido estén o no registrados, pertenecen a sus respectivos propietarios.

RC Libros Calle Mar Mediterráneo, 2. Nave 6 28830 SAN FERNANDO DE HENARES, Madrid Teléfono: +34 91 677 57 22 Fax: +34 91 677 57 22 Correo electrónico: [email protected] Internet: www.rclibros.es Diseño de colección, cubierta y pre-impresión: Grupo RC Impresión y encuadernación: Depósito Legal: Impreso en España 15 14 13 12 11 (1 2 3 4 5 6 7 8 9 10 11 12)

Page 3: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

Cuando Steve Jobs abandonó Apple, creó una empresa llamada NeXT. El objetivo de NeXT era crear un sistema operativo técnicamente superior a los que entonces existían en el mercado, al que llamaron NeXTSTEP. Objective-C es el lenguaje que eligió la empresa NeXT para su sistema operativo. Apple compró NeXTSTEP cuando Steve Jobs volvió a Apple, y ha conservado el lenguaje Objective-C como lenguaje principal para el desarrollo de aplicaciones.

Apple ha evolucionado el antiguo sistema operativo NeXTSTEP para cubrir dos áreas de mercado. La primera área es Mac OS X, el sistema operativo para ordenadores de escritorio, como son los portátiles MacBook o los ordenadores de mesa Mac mini, iMac o Mac Pro. La segunda área es iOS, el sistema operativo para dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación fuertemente orientado a objetos, y que utiliza como base el lenguaje de programación Objective-C.

Objective-C 2.0 es una extensión a Objective-C para proporcionar nuevas características. Normalmente, este libro utiliza el término Objective-C para referirse tanto a las características originales como a estas nuevas características.

PREFACIO

Page 4: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

XX © RC Libros

La similitud que existe entre Mac OS X y iOS hace posible escribir programas que compilan en ambos sistemas. Este libro aprovecha esta similitud para enseñar a programar en Objective-C, y recalca los puntos donde la forma de programar ambos sistemas operativos difiere.

La experiencia de más de 10 años al frente de MacProgramadores.org del autor de este libro dice que Objective-C no es un lenguaje que se suela escoger como primer lenguaje de programación. Lenguajes como C++ o Java son los lenguajes más elegidos por los recién llegados al mundo de la programación. Los programadores que se interesan por el desarrollo de aplicaciones Mac OS X o iOS suelen ser profesionales de la programación con experiencia en el desarrollo de aplicaciones en otros entornos. La entrada de Apple en el mundo de los sistemas operativos móviles ha incrementado significativamente la llegada de este tipo de profesionales.

Esta observación hace posible diseñar un libro adaptado a programadores que ya conocen los conceptos básicos comunes a todos los lenguajes de programación, y que no quieren dedicar su tiempo a volver a leer otro libro de introducción a la programación. Este libro está pensado para que estos programadores aprendan a desarrollar aplicaciones Mac OS X o iOS rápidamente. Para facilitar aún más el aprendizaje, este libro también incluye comparaciones entre aspectos Objective-C y la forma en que estos aspectos se implementan en C++ y en Java. Creemos que esta forma de aprendizaje ágil animará a muchos programadores a elegir este libro como su libro de referencia para introducirse en el apasionante mundo de la manzana.

Qué contiene este libro

Este libro tiene dos partes. La primera parte estudia en detalle el lenguaje Objective-C. El lenguaje es la base para poder empezar a estudiar la extensa librería de clases y funciones que proporcionan tanto Mac OS X como iOS.

La segunda parte del libro estudia Foundation Framework, una librería con el conjunto de funciones y clases básicas que comparten Mac OS X y iOS. Foundation Framework proporciona funcionalidad para el manejo de ficheros, los procesos e hilos, el runtime de configuración sistema, la programación multihilo y sus técnicas de sincronización, la programación en red y los objetos distribuidos. Foundation Framework también se basa en otra librería llamada Core Foundation, que también se estudia en este libro.

Al acabar este libro, el lector conocerá todos los detalles del lenguaje Objective-C, y tendrá una base sólida sobre el manejo de la librería Foundation Framework. En

Page 5: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

PREFACIO

© RC Libros XXI

este momento, cada programador tendrá que decidir si sus objetivos profesionales le exigen centrarse en estudiar las librerías de Mac OS X, o las de iOS.

Conocer la librería Foundation Framework es una inestimable ayuda antes de afrontar el aprendizaje del extenso grupo de librerías que proporciona Mac OS X o iOS. Cocoa es el nombre que agrupa a las librerías de programación propias de Mac OS X. Cocoa Touch es el nombre que agrupa a las librerías para desarrollar aplicaciones para iOS.

Acerca del autor

El autor de este libro es un entusiasta del mundo de la programación Apple. Su interés despertó cuando en el año 2000 Apple sacó al mercado la primera versión de su sistema operativo Mac OS X. En febrero de 2001, inició el sitio web MacProgramadores.org donde ha moderado foros, publicado numerosos tutoriales, reportajes, trucos y noticias relacionados con la programación de Mac OS X. Con la llegada de iPhone añadió la programación de iOS.

Fernando López Hernández nació en 1973, tiene el título de Doctor Europeo en Ingeniería Informática y Telecomunicación. Profesionalmente ha trabajado en diversos laboratorios de investigación en España, Reino Unido y Austria, ha trabajado en varios proyectos de investigación financiados por la Unión Europea, y tiene un considerable número de publicaciones científicas. Asimismo, ha trabajado impartiendo cursos, tanto a nivel universitario como a nivel profesional.

Para que el lector pueda consultar sus dudas y reportar posible erratas, el autor ha habilitado un foro en http://www.macprogramadores.org/?q=forum.

Agradecimientos

Este libro ha llegado a ser una realidad con el apoyo de dos personas. Una de ellas ha sido Carolina Fernández Arias, mi mujer, que no solo ha prescindido de mí mientras lo escribía, sino que ha revisado el texto de este libro en busca de mejoras. La otra persona ha sido Alberto Corbi Bellot, mi amigo y compañero de admiración por las tecnologías Apple. Muchas de las nuevas características de las herramientas de desarrollo no estarían descritas en este libro sin su revisión.

Page 6: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

PARTE I:

EL LENGUAJE OBJECTIVE-C

Page 7: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

EMPEZANDO A PROGRAMAR CON

OBJECTIVE-C

OBJETIVOS DEL CAPÍTULO

Este primer capítulo de naturaleza introductoria empieza describiendo los entornos donde podemos programar con Objective-C, y después describe las herramientas necesarias para crear aplicaciones.

Antes de que en el Capítulo 2 se adentre en los conceptos del lenguaje, creemos que será útil para el lector familiarizarse con el uso de las herramientas de programación. Con este fin, este capítulo empieza enseñando al lector cómo crear sencillos programas, y describe la forma de compilar y enlazar estas aplicaciones.

El capítulo empieza describiendo cómo compilar aplicaciones Objective-C desde la consola, utilizando Clang y las herramientas de programación de GNU. En la segunda parte de este capítulo se estudia cómo, usando la herramienta gráfica Xcode, podemos mejorar la productividad del programador.

ENTORNOS DE PROGRAMACIÓN

Objective-C procede de los tiempos de NeXTSTEP, el sistema operativo en el que se basa Mac OS X. A su vez iOS es una evolución de Mac OS X para adaptarlo a dispositivos móviles. iOS es el nombre que Apple ha dado al sistema operativo de dispositivos como iPhone, iPad, iPod Touch y Apple TV. Objective-C es el lenguaje principal y nativo para desarrollo de aplicaciones en todos estos sistemas operativos.

Una vez que el programador de aplicaciones Mac OS X o iOS aprende el lenguaje Objective-C, su siguiente paso será empezar a conocer la extensa librería de clases y funciones que proporcionan estos sistemas operativos. Estas librerías se pueden dividir, grosso modo, en tres grandes grupos:

Page 8: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

4 © RC Libros

• Foundation Framework. Son un conjunto de clases de utilidad que permiten representar estructuras de datos complejas (arrays, listas, diccionarios, etc.). Estas clases también incluyen otras funcionalidades como el acceso a red, la gestión de procesos e hilos, el runtime de configuración del sistema, la programación multihilo y las técnicas para sincronizar estos hilos. La principal característica de estas clases es que, en su mayoría, son comunes a Mac OS X y iOS. Esto se debe a que no incluyen las clases relacionadas con la parte que más cambia: la interfaz gráfica de usuario.

• Cocoa. Aquí se incluyen las clases propias de Mac OS X. Estas clases están relacionadas con la interfaz gráfica, la impresión, el acceso a audio y vídeo, y todos los demás servicios que proporciona Mac OS X. Tradicionalmente, Apple también ha utilizado el término Aplicación Kit Framework (AppKit Framework) para referirse a estas clases. Dentro del Cocoa encontramos otros kits de desarrollo especializados en determinadas tareas como puedan ser Image Kit, QuickTime Kit, Apple Scripting Kit, etc.

• Cocoa Touch. Aquí se incluyen las clases propias de la interfaz de usuario de iOS. Las clases de Cocoa están pensadas para manejar aplicaciones mediante un teclado y un ratón, con lo que Apple tuvo que crear un conjunto de librerías distintas, llamado Cocoa Touch, para poder manejar dispositivos táctiles. La principal librería que encontramos en Cocoa Touch es UI Kit, el kit que permite desarrollar los elementos de la interfaz gráfica de las aplicaciones iOS. Otros kits que encontramos son, por ejemplo, Map Kit para gestionar mapas Google, iAd Kit para gestionar los banners de publicidad, Game Kit para juegos o Audio Unit Kit para gestionar el sonido.

La Figura 1.1 muestra un resumen de las capas software de programación tanto de Mac OS X como de iOS. Observe que las partes de más alto nivel son programables en Objective-C, mientras que el bajo nivel (Core Services) se programa en C. Esta organización permite alcanzar mayor productividad a los programadores de alto nivel mediante el uso de la programación orientada a objetos. Como se explicará en el Capítulo 2, Objective-C es una extensión de C para aprovechar las ventajas de la programación orientada a objetos. Observe que hay librerías Objective-C (por ejemplo, Quick Time Kit o Foundation Framework) que tienen su correspondiente librería C (QuickTime y Core Foundation, en el ejemplo anterior). En este caso, las llamadas a las librerías Objective-C suelen estar mapeadas directamente; es decir, envuelven a su correspondiente llamada a librería C.

Otra API no mostrada en esa figura es Carbon, la antigua API de programación de Mac OS Classic (Mac OS 9 e inferiores). Carbon es un API programable en C y de transición, que Mac OS X integra para mantener compatibilidad con aplicaciones

Page 9: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 5

antiguas. El fin último de Carbon es desaparecer, y de hecho, iOS ya no incluye esta API.

Figura 1.1: Capas software de programación en Mac OS X y iOS

En este libro vamos a centrarnos en estudiar el lenguaje Objective-C. También estudiaremos algunas clases de Foundation Framework. Las clases de Cocoa y Cocoa Touch se dejan para otros libros que usted podrá leer, una vez que domine el lenguaje.

COMPILANDO CON LAS GCC

Las GCC (GNU Compiler Collection) son un conjunto de herramientas que proporciona GNU para programar en varios lenguajes y plataformas. Mac OS X y iOS se apoyan en estas herramientas para realizar las tareas de compilación y enlazado de sus aplicaciones.

Para mejorar la productividad y la facilidad de uso de estas herramientas, Apple creó Xcode, un IDE (Integrated Development Environment) que permite realizar de forma gráfica las tareas comunes de programación. Xcode hace llamadas a las GCC para realizar las tareas de compilación y enlazado de forma transparente al programador.

Page 10: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

6 © RC Libros

En esta sección veremos cómo utilizar las herramientas de programación de GNU para compilar y enlazar aplicaciones Objective-C desde el terminal1. Al final del capítulo veremos cómo se puede utilizar Xcode para mejorar la productividad del programador.

En este capítulo vamos a pasar por encima los detalles relativos al lenguaje, con lo que si no conoce Objective-C puede que muchos aspectos de lenguaje le resulten confusos. En el Capítulo 2 introduciremos el lenguaje a nivel conceptual, y en el Capítulo 3 empezaremos a detallar todos los aspectos del lenguaje con el nivel de detalle que se requiere para su correcta comprensión.

Crear un ejecutable

Debido a que Objective-C es una extensión al lenguaje C, un programa C compila en Objective-C sin necesidad de cambios. El Listado 1.1 muestra un programa básico Objective-C que solo usa la sintaxis de C, excepto por dos aspectos:

/* holamundo.m */ #import <stdio.h> #import <stdlib.h> int main() { printf("Hola desde Objective-C\n"); return EXIT_SUCCESS; }

Listado 1.1: Programa Objective-C básico

El primer aspecto es que, en vez de usar la directiva del preprocesador #include, hemos usado la directiva del preprocesador #import. Ambas directivas incluyen un fichero dentro de otro fichero, pero a diferencia de #include, la directiva #import asegura que el fichero incluido no se incluya más de una vez. En consecuencia, en los ficheros de cabecera incluidos con #import no es necesario hacer un control de inclusiones con la directiva del preprocesador #ifdef, tal como acostumbra a hacerse en C y C++.

1 Si, al final de este capítulo, cree que todavía no conoce lo suficiente estas herramientas, encontrará una descripción a fondo de estas herramientas en el tutorial "Compilar y depurar aplicaciones con las herramientas de programación GNU", publicado online en MacProgramadores.org.

Page 11: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 7

La segunda diferencia está en que la extensión de los ficheros Objective-C es .m. Esta es la extensión que permite al comando gcc saber que se trata de un programa Objective-C.

Para compilar y ejecutar este programa, bastaría con ejecutar los siguientes comandos:

$ gcc holamundo.m -o holamundo

$ ./holamundo

Hola desde Objective-C

Framework y runtime de Objective-C

Para programar en Objective-C disponemos de dos frameworks distintos: el primer framework es el framework de clases de GNU, que son un conjunto de clases inicialmente desarrollado por NeXTSTEP para Objective-C, que fueron abiertas bajo licencia GNU, y cuya clase base es la clase Object. El segundo es el framework de clases de NeXTSTEP, que es el conjunto de clases que desarrolló NeXTSTEP en 1994, cuya clase base es NSObject, y que actualmente es el usado por Mac OS X y iOS para implementar Cocoa y Cocoa Touch. Apple no ha abierto el código fuente del framework de clases de NeXTSTEP.

Actualmente, el framework de clases de GNU ha dejado de actualizarse, y GNU también está haciendo una implementación de código fuente abierto del nuevo framework de clases de NeXTSTEP, llamado GNUStep. Esta implementación también utiliza la clase base NSObject, así como el resto de clases del framework de NeXTSTEP, pero aún no está terminada.

Para usar el framework de clases de GNU, debemos enlazar con el fichero libobjc.a usando la opción del enlazador -lobjc. Por el contrario, para enlazar con el framework de clases de NeXTSTEP debemos enlazar con el framework Foundation.framework usando la opción del enlazador -framework Foundation. Lógicamente, podemos enlazar con ambos frameworks de clases, proporcionando ambas opciones durante el enlazado.

Es importante no confundir los frameworks de Objective-C con los runtime de Objective-C. Los frameworks de Objective-C son las librerías de clases (cuya clase base es Object o NSObject, respectivamente). Los runtime de Objective-C son un conjunto de funciones de librería, escritas en C, en las que se apoyan las clases de Objective-C para alcanzar el potencial dinámico característico de este lenguaje. Por defecto, Mac OS X usa el runtime de NeXTSTEP, el cual actualmente da soporte tanto

Page 12: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

8 © RC Libros

al framework de clases de GNU como al framework de clases de NeXTSTEP. Podemos pedir usar el runtime de GNU usando la opción del enlazador -fgnu-runtime, pero en este caso solo tendremos acceso al framework de clases de GNU. En este último caso deberemos enlazar con la librería libobjc-gnu.a, usando la opción -lobjc-gnu.

Programar con el framework de clases de GNU

En esta sección, vamos a ver cómo programar usando el framework de clases de GNU. En la siguiente sección, veremos las diferencias cuando usamos el framework de clases de NeXTSTEP.

Normalmente, cada clase Objective-C consta de dos ficheros: uno con la extensión .h que contiene la interfaz, y otro con la extensión .m que contiene la implementación. El Listado 1.2 y el Listado 1.3 muestran, respectivamente, un ejemplo de interfaz e implementación de una clase Objective-C llamada Saludador. Observe que estamos usando como clase base la clase Object situada en el fichero de cabecera <objc/Object.h>.

/* Saludador.h */ #import <objc/Object.h> @interface Saludador : Object { char* saludo; } - init; - (void)setSaludo:(char*)unSaludo; - (void)setSaludo:(char*)unSaludo y:(char*)unaColetilla; - (void)saluda; @end

Listado 1.2: Interfaz de una clase Objective-C con el framework de clases de GNU

/* Saludador.m */ #import "Saludador.h" #import <stdio.h> #import <stdlib.h> #import <string.h> @implementation Saludador - init { if ((self = [super init])) { saludo = "Hola mundo"; } return self; } - (void)setSaludo:(char*)unSaludo {

Page 13: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 9

saludo = unSaludo; } - (void)setSaludo:(char*)unSaludo y:(char*)unaColetilla { saludo = malloc(strlen(unSaludo)+strlen(unaColetilla)+1); strcpy(saludo,unSaludo); strcat(saludo,unaColetilla); } - (void)saluda { printf("%s\n",saludo); } @end

Listado 1.3: Implementación de una clase Objective-C con el framework de clases de GNU

Una vez tengamos definida la clase, para instanciar y usar un objeto de esta clase, necesitamos un programa principal como el del Listado 1.4.

/* pidesaludo.m */ #import <stdlib.h> #import "Saludador.h" int main() { Saludador* s = [[Saludador alloc] init]; [s saluda]; [s setSaludo: "Hola de nuevo"]; [s saluda]; [s setSaludo: "Hola buenos dias," y: "encantado de verle"]; [s saluda]; [s free]; return EXIT_SUCCESS; }

Listado 1.4: Programa que usa un objeto Objective-C del framework de clases de GNU

Al estar usando el framework de clases de GNU, el programa puede ser compilado y enlazado con los siguientes comandos:

$ gcc -c Saludador.m

$ gcc -c pidesaludo.m

$ gcc Saludador.o pidesaludo.o –lobjc –arch i386 -o pidesaludo

O bien realizar los tres pasos a la vez con el siguiente comando:

$ gcc pidesaludo.m Saludador.m –lobjc –arch i386 -o pidesaludo

Observe que hemos ejecutado gcc con la opción –arch i386. Esto se debe a que Apple ha dejado de mantener este conjunto de clases, las cuales no compilan en 64 bits (x86_64), que es la arquitectura por defecto desde Mac OS X 10.6. Para usar el

Page 14: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

10 © RC Libros

framework de clases de GNU, tenemos que compilar para una plataforma en la que se soporte. En concreto, el framework de clases de GNU está soportado en i386 (Intel de 32 bits) y ppc970 (PowerPC). Las arquitecturas armv6 y armv7 de iOS y ppc64 (PowerPC de 64 bits) tampoco soportan el framework de clases de GNU. Dado que Apple ha dejado de dar soporte al framework de clases de GNU, en el resto de este libro nos vamos a limitar a estudiar el framework de clases de NeXTSTEP.

Programar con el framework de clases de NeXTSTEP

El Listado 1.5, el Listado 1.6 y el Listado 1.7 muestran cómo implementar y usar la clase Saludador de la sección anterior, pero enlazando con el framework de clases de NeXTSTEP. La principal diferencia está en que ahora derivamos de NSObject, en vez de derivar de Object. La segunda diferencia está en que importamos el fichero <Foundation/NSObject.h>, en vez de importar el fichero <objc/Object.h>.

/* Saludador.h */ #import <Foundation/NSObject.h> @interface Saludador : NSObject { char* saludo; } - init; - (void)setSaludo:(char*)unSaludo; - (void)setSaludo:(char*)unSaludo y:(char*)unaColetilla; - (void)saluda; @end

Listado 1.5: Interfaz de una clase Objective-C con el framework de clases de NeXTSTEP

/* Saludador.m */ #import "Saludador.h" #import <stdio.h> #import <stdlib.h> #import <string.h> @implementation Saludador - init { if ((self = [super init])) { saludo = "Hola mundo"; } return self; } - (void)setSaludo:(char*)unSaludo { saludo = unSaludo; } - (void)setSaludo:(char*)unSaludo y:(char*)unaColetilla { saludo = malloc(strlen(unSaludo)+strlen(unaColetilla)+1); strcpy(saludo,unSaludo);

Page 15: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 11

strcat(saludo,unaColetilla); } - (void)saluda { printf("%s\n",saludo); } @end

Listado 1.6: Implementación de una clase Objective-C con el framework de clases de NeXTSTEP

/* pidesaludo.m */ #import <stdlib.h> #import "Saludador.h" int main() { Saludador* s = [[Saludador alloc] init]; [s saluda]; [s setSaludo: "Hola de nuevo"]; [s saluda]; [s setSaludo: "Hola buenos dias," y: "encantado de verle"]; [s saluda]; [s release]; return EXIT_SUCCESS; }

Listado 1.7: Programa que usa un objeto Objective-C con el framework de clases de NeXTSTEP

Ahora, para compilar y ejecutar el programa usamos los siguientes comandos:

$ gcc Saludador.m pidesaludo.m -framework Foundation -o pidesaludo

$ ./pidesaludo

CLANG, LLVM Y LLDB

El compilador de GCC consta de un front-end y de varios back-ends. El back-end permite generar instrucciones en los distintos lenguajes y arquitecturas. El front-end de GCC es el comando gcc, y las distintas opciones de línea de comandos que soporta.

LLVM (Low-Level Virtual Machine) es un nuevo conjunto de back-ends para distintos lenguajes y arquitecturas que presenta varias ventajas técnicas respecto a los back-ends tradicionales de GCC.

En 2005, Apple contrató a miembros del equipo de desarrollo de LLVM para trabajar en mejorar estos back-ends. La idea inicial era mantener el front-end de GCC y reemplazar sus back-ends. LLVM-GCC es el nombre que recibió este proyecto.

Page 16: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

12 © RC Libros

El intento de combinar LLVM con GCC dio lugar a varios problemas:

• Apple usa principalmente Objective-C, pero el lenguaje Objective-C tiene poca prioridad para los desarrolladores de GCC.

• El front-end de GCC no se integra bien con las funcionalidades interactivas que los ingenieros de Apple querían meter en Xcode.

• Apple no está de acuerdo con algunas restricciones de patentes que introduce la licencia GPLv3, bajo la que se distribuye GCC 4.3.

Estos problemas hicieron que en 2007 Apple decidiera escribir un nuevo front-end al que llamaron Clang. Clang es un front-end que es en gran parte similar al front- end de GCC. El comando que lo implementa es clang y es una alternativa al comando gcc de las GCC. Algunas diferencias entre ellos son:

• La mayoría de las opciones del comando clang son similares a las del comando gcc. Con el tiempo, es posible que estas opciones diverjan cada vez más.

• Clang solo soporta los lenguajes C99, C++0x, C++ y Objective-C. GCC, además de estos lenguajes, soporta Java, Fortran y Ada.

• Clang y LLVM se distribuyen bajo la licencia abierta de la Universidad de Illinois. GCC se distribuye bajo licencia GNU. La licencia abierta de la Universidad de Illinois es parecida a la licencia BSD, en el sentido de que no exige distribuir el código fuente con las modificaciones que se hagan al compilador.

Aunque Apple sigue distribuyendo el comando llvm-gcc, el objetivo es que en el futuro solo se use el comando clang. GCC 4.2.1 es la última versión de GCC con licencia GPLv2, y posiblemente la última versión de GCC que incluyan las herramientas de desarrollo de Apple.

Las principales ventajas que indica Apple para el front-end Clang frente a GCC son:

• Durante el proceso de compilación, Clang mantiene más información sobre el código fuente original que GCC. Esto permite mapear más fácilmente los errores en el código fuente.

• Clang permite una compilación incremental más sencilla y eficiente, la cual se puede usar para reducir el tiempo de compilación de Xcode cuando se hacen pequeños cambios en el código fuente. Por su parte, aunque GCC soporta la compilación incremental, está pensado para seguir un ciclo más tradicional, basado en compilar-enlazar-ejecutar.

• Clang permite indexar los símbolos del código fuente. Estos símbolos son usados por Xcode para facilitar al usuario la navegación por el código fuente.

Page 17: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 13

• Clang permite compilar en varios hilos paralelos, reduciendo el tiempo de compilación en máquinas multi-core.

Las principales ventajas que indican los desarrolladores de GCC frente a Clang son:

• GCC soporta los lenguajes Java, Fortran y Ada, que Clang no soporta. • En tests realizados en 2011, aunque Clang compila más rápido que GCC, GCC

genera código más optimizado que Clang.

El proyecto LLVM fue iniciado en la Universidad de Illinois bajo la dirección de Vikram Adve y Chris Lattner. En 2005, Apple contrató a Chris Lattner como líder del equipo de desarrollo de LLVM.

La principal novedad de LLVM, frente a los back-ends de GCC, es que genera una representación intermedia llamada IF (Intermediate Form). Esta representación intermedia permite obtener errores y warnings más precisos, y optimizar más fácilmente el código fuente. Durante la fase de enlazado, esta representación intermedia se convierte en instrucciones del ensamblador para la máquina destino.

LLVM se distribuye con un nuevo depurador llamado lldb. El comando lldb es similar al comando gdb de GCC, pero permite aprovechar mejor la información que genera LLVM2.

Compilando con Clang

Actualmente, Xcode permite elegir entre usar Clang o GCC para compilar aplicaciones Mac OS X, aunque el front-end por defecto es Clang. En esta sección vamos a ver cómo se usa Clang para compilar aplicaciones. También veremos que las opciones de línea de comando de clang son muy parecidas a las de gcc. En el resto de este libro usaremos clang para compilar nuestras aplicaciones.

Para compilar el ejemplo del Listado 1.1 con Clang, en vez de hacer:

$ gcc holamundo.m -o holamundo

Hacemos:

2 El comando lldb se encuentra en la ruta /Developer/usr/bin/lldb. Si quiere usar este comando desde el terminal, deberá añadir su directorio al PATH.

Page 18: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

14 © RC Libros

$ clang holamundo.m -o holamundo

Análogamente, el ejemplo del Listado 1.2, del Listado 1.3 y del Listado 1.4 se compilaría con el siguiente comando:

$ clang pidesaludo.m Saludador.m -lobjc -arch i386 -o pidesaludo

O el ejemplo del Listado 1.5, del Listado 1.6 y del Listado 1.7 con el siguiente comando:

$ clang Saludador.m pidesaludo.m -framework Foundation -o pidesaludo

Crear una librería estática o dinámica

Al igual que con C o C++, con Objective-C también podemos crear una librería de enlace estático o dinámico, que luego usemos desde otros programas. Por ejemplo, para crear una librería de enlace estático que incluya la clase Saludador del Listado 1.6, podemos generar el fichero de librería con el siguiente comando:

$ ar -r libsaludos.a Saludador.o

ar: creating archive libsaludos.a

Una vez creada la librería de enlace estático, podemos enlazar con ella desde el programa del Listado 1.7 ejecutando el siguiente comando:

$ clang pidesaludo.m libsaludos.a -framework Foundation -o pidesaludo

Si lo que queremos es crear una librería de enlace dinámico, podemos crear la librería de enlace dinámico, y enlazar el programa principal del Listado 1.7 con la librería, ejecutando los siguientes comandos:

$ clang -dynamiclib Saludador.o -framework Foundation -o

libSaludos.dylib

$ clang pidesaludo.m libSaludos.dylib -framework Foundation -o

pidesaludo

Compilación cruzada para iOS

Aunque los programas anteriores compilan directamente para Mac OS X, si queremos compilar este programa para iOS, necesitaremos conocer más a fondo Clang.

Page 19: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 15

Ya hemos visto que la opción -arch permite indicar la plataforma para la que queremos generar el binario. Actualmente, iOS soporta dos opciones:

• armv6 para iPhone 3G e inferiores. • armv7 para iPad y iPhone 3GS y superiores.

La opción armv6 es la opción más segura, ya que todos los dispositivos iOS ejecutan los programas compilados con esta opción. Si nuestra aplicación es solo para iPad podemos usar la opción armv7 para que el compilador genere nuevas instrucciones máquina que mejoran ligeramente el rendimiento.

Sin embargo, esta opción no es suficiente para que Clang genere una aplicación que pueda ejecutar en iOS. Las diferencias entre Mac OS X y iOS son suficientes como para que Apple haya decidido crear diferentes versiones de sus herramientas de desarrollo, una por cada plataforma. En concreto, estas plataformas de desarrollo (que se muestran en la Figura 1.2) son:

• iPhoneOS.platform es la plataforma de desarrollo para generar binarios para los procesadores ARM. Estos binarios se generan preparados para enlazar con las librerías de enlace dinámico del dispositivo.

• iPhoneSimulator.platform es la plataforma para desarrollar aplicaciones que ejecutan en iPhone Simulator. Se diferencia de la anterior en que el binario contiene instrucciones Intel, y enlaza con las librerías de enlace dinámico del simulador.

Figura 1.2: Plataformas de desarrollo

Page 20: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

16 © RC Libros

• MacOSX.platform es la plataforma por defecto. Genera binarios Intel que enlazan con las librerías de enlace dinámico del sistema operativo Mac OS X.

Si queremos generar una aplicación iOS, debemos cambiar de plataforma de desarrollo, lo cual se suele hacer creando la variable de entorno DEVROOT de la siguiente forma:

$ export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer

Una plataforma de desarrollo puede tener más de un SDK (Software Development Kit). Luego, además de la plataforma de desarrollo, debemos indicar con qué SDK queremos trabajar, declarando la variable de entorno SDKROOT de la siguiente forma:

$ export SDKROOT=$DEVROOT/SDKs/iPhoneOS4.3.sdk

Dado que el comando clang, ld, etc., a utilizar son también distintos dependiendo de la plataforma de desarrollo, para compilar aplicaciones iOS también se suele modificar la variable de entorno PATH para que encuentre los comandos de la plataforma de iOS, antes que los de Mac OS X:

$ export PATH="$DEVROOT/usr/bin:$PATH"

Una vez declaradas estas variables de entorno, podemos compilar nuestra aplicación con el siguiente comando:

$ export CFLAGS="-isysroot $SDKROOT -miphoneos-version-min=4.0"

$ clang -arch armv6 $CFLAGS -c Saludador.m pidesaludo.m

La variable de entorno CFLAGS proporciona la opción de compilación -isysroot, que indica el directorio raíz donde clang debe buscar los ficheros de cabecera. De no proporcionar esta opción, clang buscaría ficheros de cabecera en /usr/include (el directorio de ficheros de cabecera por defecto). Esto significa que usaría los ficheros de cabecera de Mac OS X, en vez de usar los de iOS. Esto posiblemente produciría errores de compilación, ya que estos ficheros de cabecera son distintos. La opción -miphoneos-version-min indica la versión mínima de iOS para ejecutar la aplicación. En el ejemplo, 4.0, indica que nuestra aplicación debe ejecutar en iOS 4.0 o superior. Conviene que este número sea lo más bajo posible para que nuestra aplicación ejecute en versiones antiguas de iOS. Solo si estamos usando funcionalidades nuevas, debemos elevar este número para poder compilar con esa nueva funcionalidad.

Obsérvese que la opción -c hace que clang compile los ficheros Saludador.m y pidesaludo.m, para generar los ficheros Saludador.o y pidesaludo.o. Sin embargo,

Page 21: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 17

clang no ha enlazado estos ficheros de código objeto. Para ello, debemos ejecutar el siguiente comando:

$ export LDFLAGS="-framework Foundation"

$ clang -arch armv6 $CFLAGS $LDFLAGS Saludador.o pidesaludo.o -o

pidesaludo

En este caso, LDFLAGS proporciona a clang la opción de enlazado -framework, que indica que queremos enlazar con Foundation.framework.

Como no, ambos pasos (compilación y enlazado) se pueden ejecutar en un solo paso de la siguiente forma:

$ clang -arch armv6 $CFLAGS $LDFLAGS Saludador.m pidesaludo.m -o

pidesaludo

Por último, copiamos el binario a nuestro dispositivo iOS, y lo ejecutamos:

$ scp pidesaludo [email protected]:

$ ssh mobile@ferpod

$ ./pidesaludo

Hola mundo

Hola de nuevo

Hola buenos dias,encantado de verle

COMPILANDO CON XCODE

En las siguientes subsecciones vamos a aprender a manejar Xcode. En Xcode, un proyecto incluye los ficheros e información requerida para compilar y ejecutar los productos. El proyecto contiene uno o más targets. Un target especifica cómo construir un producto a partir de un conjunto de ficheros. Las instrucciones del target se dividen en fases, llamadas build phases, y en variables llamadas build settings. Podemos usar Xcode para ver y modificar las build phases y build settings de cada target. La Figura 1.3 muestra un proyecto traduce con dos targets. Una aplicación de consola llamada traduce, y una librería de enlace dinámico llamada libtraduce.

El proyecto tiene build settings, pero no build phases. Los targets heredan los build settings del proyecto, y pueden redefinir o añadir más build settings. En la Figura 1.3 vemos cómo el target hereda build settings por defecto (Mac OS X

default), build settings del proyecto traduce, y por último podemos modificar build settings propios del target. La columna Resolved muestra el valor actual que toma

Page 22: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

18 © RC Libros

cada build setting. Además, nos marca con un rectángulo verde la posición de donde se hereda cada build setting.

Figura 1.3: Elementos de un proyecto Xcode

Cuando creamos un nuevo proyecto con Xcode (usando la opción de menú File | New Project), Xcode nos muestra un diálogo donde nos pregunta qué tipo de proyecto queremos crear. Al crear el proyecto se crea un producto con el mismo nombre que el proyecto elegido. Si queremos, más tarde podemos añadir más productos al proyecto. Desde el principio indicamos si el proyecto es para Mac OS X o para iOS, y la configuración del proyecto varía para adaptarse al entorno para el que vamos a programar. Aunque hay muchos tipos de proyectos, en esta sección vamos a ver solo cuatro tipos de proyectos: un proyecto que crea una aplicación de consola Objective-C, un proyecto que crea una librería de enlace estático, otro proyecto que crea una librería de enlace dinámico, y otro proyecto más que crea un framework.

Page 23: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 19

También, veremos cómo desde otro proyecto Xcode, podremos enlazar con estos tres últimos tipos de productos3.

Crear un programa

En esta sección vamos a ver cómo se crea un proyecto cuyo producto es un programa de consola Objective-C. Aunque el uso de Xcode puede resultar muy cómodo, tenga en cuenta que Xcode está llamando por usted a Clang, con lo que procure tener siempre presentes qué opciones son las que Xcode pasa por usted al compilador y enlazador de Clang.

Para crear un proyecto de consola, ejecute Xcode, y elija la opción de menú File | New Project. Aparecerá un diálogo donde se le preguntará qué tipo de proyecto desea crear. Dentro del grupo Mac OS X, seleccionamos Application | Command Line Utility

4. Esto nos permite crear un proyecto Objective-C que enlaza con Foundation Framework. A continuación, se le preguntará el nombre del producto, y con qué librerías enlazar. En nuestro caso, elegiremos el tipo Foundation para enlazar con esta librería, y como nombre de producto indicaremos pidesaludo. Esto creará un comando de consola pidesaludo similar al comando que hicimos en la sección "Compilando con las GCC" de este capítulo, solo que ahora lo vamos a desarrollar desde Xcode.

El proyecto Xcode se guarda en un fichero llamado pidesaludo.xcodeproj, en el subdirectorio que usted haya especificado5. Además, como puede apreciar en la Figura 1.4, dentro del grupo Frameworks aparece Foundation Framework, indicando que tenemos ya acceso a todas las clases Objective-C definidas en este framework.

Las carpetas amarillas se llaman Grupos, y no corresponden ni influyen en la estructura de los ficheros en el disco. Simplemente son una forma de organizar nuestros ficheros que podemos cambiar a nuestro antojo.

3 Podrá encontrar información más detallada sobre qué son, y cómo se configuran estos tipos de proyectos, en el tutorial "Compilar y depurar aplicaciones con las herramientas de programación de GNU" publicado en MacProgramadores.org. 4 Esta es la localización de los proyectos de consola que usan Foundation Framework en Xcode 4.0.2, Apple ha cambiado ya varias veces la distribución de los tipos de proyectos en este diálogo, y no sería extraño que en futuras versiones la localización de este tipo de proyecto volviese a cambiar. 5 Realmente pidesaludo.xcodeproj es un subdirectorio con el atributo de bundle que permite que usted lo vea desde el Finder como si fuese un único fichero.

Page 24: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

20 © RC Libros

Por defecto, se nos habrá creado un fichero llamado main.m con el contenido que muestra la Figura 1.4. En este esqueleto de programa se nos sugiere crear un objeto NSAutoreleasePool, el cual se usa para implementar el sistema de recogida automática de memoria de Objective-C, tal como veremos en la sección "Autorelease pools" del Capítulo 5. Nosotros vamos a cambiar el código generado automáticamente por el del Listado 1.7.

Figura 1.4: Programa de consola básico

También vamos a añadir al proyecto la clase Saludador que hicimos en la sección anterior. Para ello, podemos usar la opción de menú File | New File y seleccionamos el tipo Cocoa | Objective-C class. Se nos pregunta de qué clase queremos derivar, e indicamos NSObject. Después se nos pide un nombre de fichero y elegiremos Saludador.m. Dado que hemos pedido crear una clase Objective-C, al crearse el fichero Saludador.m, también se crea automáticamente el fichero de cabecera Saludador.h. Después, solo tenemos que cambiar el código que genera automáticamente Xcode por el del Listado 1.5 y del Listado 1.6.

Una vez introducido el código de la clase Saludador, el proyecto generado debería tener la forma de la Figura 1.5. Ahora, podemos usar la opción de menú

Page 25: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 21

Product | Build para compilar el programa, y la opción de menú Product | Run (o el botón Run) para ejecutar el programa.

Figura 1.5: Programa Objective-C terminado

También es posible iniciar el proceso de compilación desde el terminal con el comando xcodebuild. Para obtener la lista de targets y de configuraciones de compilación, podemos ejecutar desde el directorio pidesaludo:

$ xcodebuild -list

Information about project "pidesaludo":

Targets:

pidesaludo

Build Configurations:

Debug

Release

If no build configuration is specified "Release" is used.

Para indicar la configuración y target que queremos lanzar, usaríamos:

$ xcodebuild -configuration Debug -target pidesaludo

ProcessPCH

Page 26: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

22 © RC Libros

cd /Users/fernando/xcode4/pidesaludo

setenv LANG en_US.US-ASCII

/Developer/usr/bin/clang -x objective-c-header -arch x86_64 -

fmessage-length=0 -fdiagnostics-print-source-range-info

·················

CompileC

cd /Users/fernando/xcode4/pidesaludo

setenv LANG en_US.US-ASCII

/Developer/usr/bin/clang -x objective-c -arch x86_64 -fmessage-

length=0 -fdiagnostics-print-source-range-info -fdiagnostics-show-

category=id -fdiagnostics-parseable-fixits

·················

Ld build/Debug/pidesaludo normal x86_64

cd /Users/fernando/xcode4/pidesaludo

setenv MACOSX_DEPLOYMENT_TARGET 10.6

/Developer/usr/bin/clang -arch x86_64 -isysroot

/Developer/SDKs/MacOSX10.6.sdk

·················

Este comando genera un log que resulta útil para conocer los comandos que Xcode lanza para realizar la compilación. Una vez termina el proceso de compilación, se creará dentro del directorio de proyecto un subdirectorio build para la configuración elegida (Debug en este caso)6.

Crear una librería de enlace estático

En la sección "Crear una librería estática o dinámica" de este capítulo, usamos clang para crear una librería de enlace estático llamada libsaludos.a. Ahora vamos a crear otra vez esta librería, pero desde Xcode.

Para empezar, vamos a crear un nuevo proyecto con Xcode usando File | New Project, y dentro del grupo Mac OS X | Framework & Library elegimos ahora el tipo Cocoa Library. Después, se nos pregunta si queremos que la librería sea de enlace estático o dinámico y elegimos Static. Podemos deseleccionar la opción Include Unit Tests, porque para testear la librería luego crearemos una aplicación de consola. Si elegimos saludos como nombre de producto, Xcode nos generará un proyecto con el nombre saludos.xcodeproj, y una librería de enlace estático con el nombre libsaludos.a.

6 Xcode 4 no genera este directorio build en el directorio de proyecto, porque lo envía a un subdirectorio dentro de $HOME/Library/Developer/Xcode/DerivedData.

Page 27: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 23

La Figura 1.6 muestra qué forma tendrá ahora este proyecto. Observe que en el grupo Frameworks se nos han incluido varias librerías. Sin embargo, observando la pestaña Build Phases del target, vemos que nuestra librería solo enlaza con Cocoa Framework. Las demás librerías aparecen en el grupo por si queremos añadirlas. Realmente (véase sección "Crear una librería estática o dinámica" de este capítulo), para crear una librería de enlace estático no es necesario enlazar con ningún framework, ya que es la aplicación que usa la librería de enlace estático la que debe enlazar con los frameworks. En consecuencia, podemos eliminar los frameworks tal como muestra la Figura 1.7.

Figura 1.6: Proyecto de librería estática de partida

En el grupo Products de la Figura 1.6, vemos que se nos indica que el producto generado por este proyecto será el fichero de librería estática libsaludos.a. El color rojo indica que el fichero actualmente no existe.

En la sección "Crear un programa" anterior, Xcode generó un fichero de código fuente llamado main.m con una función main(). Observe que cuando creamos una librería, Xcode no genera ningún fichero de código fuente. Ahora podemos volver a crear los ficheros Saludador.h y Saludador.m usando la opción de menú File |

Page 28: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

24 © RC Libros

New File | Objective-C class. La Figura 1.7 muestra el resultado de crear la librería estática.

Figura 1.7: Resultado de crear una librería estática

Enlazar con la librería de enlace estático

Por otro lado, vamos a crear un proyecto con una aplicación de consola que llame a la librería. Para ello, igual que en la sección "Crear un programa", cree un proyecto de tipo Command Line Tool | Foundation llamado pidesadulo. El código fuente del fichero main.m lo podemos cambiar para que sea de nuevo idéntico al del Listado 1.7. Ahora no necesitamos incluir la implementación de la clase, ya que la vamos a coger de la librería estática, pero sí que necesitamos incluir el fichero Saludador.h con la interfaz de clase. Para ello, seleccionamos el grupo pidesaludo y usamos la opción de menú File | Add Files to "pidesaludo". Cuando añadimos el fichero Saludador.h, no es necesario marcar la opción Copy items into destination group's folder, ya que no queremos hacer una copia del fichero, sino solamente, añadirlo a nuestro proyecto para que la directiva #import lo encuentre.

Page 29: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 25

Figura 1.8: Programa que usa una librería estática

Para usar la librería de enlace estático libsaludos.a desde nuestro programa, la tenemos que añadir a nuestro proyecto pidesaludo.xcodeproj con la opción de menú File | Add Files to "pidesaludo". Para encontrar el directorio donde Xcode ha depositado el fichero libsaludos.a, vuelva al proyecto saludos.xcodeproj, seleccione el producto libsaludos.a con el botón derecho, y ejecute la opción del menú contextual Show in Finder. Tras añadir esta librería, el proyecto tendrá la forma de la Figura 1.8, y podremos compilar y ejecutar el programa.

Crear una librería de enlace dinámico

En Mac OS X y iOS las librerías de enlace dinámico suelen tener la extensión .dylib. Para crearlas desde Xcode, volvemos a usar la opción de menú File | New Project, y dentro de Application | Framework & Library | Cocoa Library elegimos el tipo Dynamic. Como nombre de producto podemos elegir libsaludos.

Page 30: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

26 © RC Libros

Esto generará una librería de enlace dinámico llamada libsaludos.dylib7. La Figura 1.9 muestra la configuración inicial de este proyecto.

Figura 1.9: Proyecto inicial de librería de enlace dinámico

Los compiladores actuales pasan la mayoría de su tiempo compilando una y otra vez cabeceras mucho más grandes que el código fuente del fichero .m. Para evitarlo es muy común precompilar las cabeceras. En la Figura 1.9 vemos un fichero con el sufijo Prefix.pch. Este es el fichero que tanto GCC como Clang precompilan con los ficheros de cabecera más comunes del proyecto. De esta forma se evita tener que compilar estos ficheros de cabecera cada vez que se importan con #import. Xcode crea un fichero de cabeceras precompiladas para la mayoría de los proyectos que genera, no solo para las librerías de enlace dinámico. En la Figura 1.9 vemos que este fichero de cabecera se configura indicando en la opción GCC_PREFIX_HEADER el

7 Observe que en la librería estática anterior, Xcode asignaba al fichero de librería estática el nombre del proyecto precedido por lib. Sin embargo, Xcode no pone este prefijo a las librerías de enlace dinámico. Como también es muy común preceder a los nombres de librería de enlace dinámico con lib, nosotros hemos puesto este prefijo al nombre del proyecto.

Page 31: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 27

nombre del fichero precompilado. Además, debemos poner YES en la opción GCC_PRECOMPILE_PREFIX_HEADER.

En la Figura 1.9 vemos también que, al igual que cuando creamos un proyecto de librería estática, en el grupo Frameworks se nos han incluido varias librerías. A diferencia de las librerías de enlace estático, las librerías de enlace dinámico necesitan indicar los frameworks de los que dependen. Esto hace que antes de cargarse la librería de enlace dinámico, se carguen los frameworks de los que depende. Tal como Xcode ha creado el proyecto, Cocoa es el único framework que enlazará con nuestra librería de enlace dinámico. Tal como vimos en la Figura 1.6, el producto no se enlaza con todos los frameworks que aparezcan en el grupo Frameworks, sino solo con lo que indiquemos en la pestaña Build Phases del target. Los demás frameworks que aparecen en el grupo Frameworks son frameworks inicialmente inactivos para el target. La razón por la que Xcode nos los pone en el proyecto es porque, al ser frameworks muy usados, frecuentemente querremos activarlos.

Figura 1.10: Librería de enlace dinámico enlazada con Foundation Framework

Page 32: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

28 © RC Libros

Como nuestra librería de enlace dinámico no necesita enlazar con Cocoa8, solo con Foundation Framework, podemos eliminar los demás frameworks del proyecto y activar Foundation Framework en la pestaña Build Phases del target. Por defecto, Xcode añade Cocoa.h al fichero de cabeceras precompiladas libsaludos-

Prfix.pch. Como nuestra librería de enlace dinámico solo usa Foundation Framework, podemos cambiar Cocoa.h por Foundation.h en el fichero de cabeceras precompiladas.

Tras cambiar las librerías con las que enlazamos y el fichero de cabeceras precompiladas, el proyecto debería tener la forma de la Figura 1.10.

El resto del proceso de creación de la librería de enlace dinámico es similar al de la librería de enlace estático. Cree los ficheros de ejemplo Saludador.h y Saludador.m, y compile el producto para producir el fichero libsaludos.dylib. En la Figura 1.10, hemos sacado el fichero libsaludos-Prefix.pch del grupo Supporting Files para demostrar que los grupos no tienen ninguna influencia en la forma en que Xcode busca y compila los ficheros.

Enlazar con la librería de enlace dinámico

De nuevo, puede crear una aplicación pidesaludo, como la de la sección anterior, desde la que acceder a la librería de enlace dinámico. Después, debemos añadir la librería de enlace dinámico libsaludos.dylib al proyecto. Una forma alternativa a la opción de menú File | Add Files to "pidesaludo" es, arrastrar desde Finder el fichero libsaludos.dylib al grupo Frameworks de nuestro proyecto.

También tendremos que añadir el fichero Saludador.h (pero no Saludador.m, que está implementado en la librería de enlace dinámico). De nuevo, al añadir Saludador.h no debemos activar la opción Copy Items into destination

group's folder, ya que no queremos crear una copia de este fichero, sino enlazar el que ya existe en el proyecto libsaludos.

Seguramente, cuando vaya a ejecutar ahora el programa pidesaludo, obtendrá un mensaje de error de la siguiente forma:

8 Cocoa es un framework que engloba a Foundation Framework. A los frameworks que engloban otros frameworks se les llama umbrela frameworks.

Page 33: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 29

dyld: Library not loaded: /usr/local/lib/libsaludos.dylib

Referenced from: pidesaludo

Reason: image not found

pidesaludo has exited due to signal 5 (SIGTRAP).

La razón está en que las librerías de enlace dinámico tienen un nombre de instalación, que es el directorio donde se supone que debería estar instalada la librería. Cuando Xcode creó el proyecto de la librería de enlace dinámico, asignó a libsaludos.dylib el nombre de instalación /usr/local/lib/libsaludos.dylib, y al no encontrarse ahí la librería, falla la carga del programa pidesaludo.

Figura 1.11: Cambiar el nombre de instalación de la librería

Para solucionarlo, siempre puede copiar la librería de enlace dinámico en la ruta sugerida, pero si esta ruta no es de su agrado, puede cambiarla en la pestaña Build Settings del target del producto, de nuestra librería de enlace dinámico. Para ello, como muestra la Figura 1.11, busque la opción Installation Directory. En esta opción indica el nombre de instalación de la librería a generar. Después vuelva a compilar el programa. Ahora al ejecutarlo debería de encontrar la librería de enlace dinámico en la ruta del nombre de instalación.

Page 34: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

30 © RC Libros

El nombre de instalación de una librería también se puede pasar al comando clang cuando generamos la librería con la opción -install_name. Por ejemplo, en la librería de enlace dinámico que generamos en la sección "Crear una librería estática o dinámica", podríamos haber ejecutado el comando clang así:

$ clang -dynamiclib Saludador.o -framework Foundation -install_name

$HOME -o libSaludos.dylib

Y el directorio $HOME sería el nombre de instalación. Podemos usar el comando otool para comprobarlo:

$ otool -D libSaludos.dylib

libSaludos.dylib: /Users/fernando

Crear un framework

Para acabar esta introducción al manejo de Xcode con Objective-C, vamos a ver cómo crear un framework. Hasta ahora hemos enlazado con frameworks como Cocoa, Cocoa Touch o Foundation Framework. Ahora vamos a ver cómo podemos crear uno propio. La ventaja de los frameworks de Mac OS X y iOS está en que, junto con una librería de enlace dinámico, podemos guardar sus ficheros de cabecera, su documentación y otros recursos que use el framework (por ejemplo, iconos).

Los framework que crea el programador se suelen guardar en subcarpetas dentro de /Library/Frameworks. Los frameworks que crea Apple son una excepción, respecto a que son los únicos que se guardan en /System/Library/Frameworks. Cada framework es una subcarpeta con una estructura de subdirectorios estandarizada9 y con la extensión .framework.

Para crear un framework, de nuevo usamos la opción de menú File | New Project, y dentro del grupo Application | Framework & Library elegimos el tipo Cocoa Framework. Para nuestro ejemplo, vamos a crear un framework llamado Saludos.framework (el nombre del framework suele empezar con una mayúscula). Xcode nos pregunta el nombre del producto, que será Saludos. El proyecto que inicialmente obtendremos tiene la forma de la Figura 1.12.

9 Puede consultar el tutorial "Compilar y depurar aplicaciones con las herramientas de programación de GNU" publicado en MacProgramadores.org para obtener una descripción más detallada de la estructura y funcionalidad de un framework.

Page 35: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 31

De nuevo, podemos eliminar todos los frameworks de los que depende nuestro proyecto, excepto Foundation Framework. También debemos acordarnos de activarlo en el target, para lo cual, una forma alternativa de hacerlo es arrastrar al framework a la etapa Link Binary With Libraries del target.

Figura 1.12: Proyecto inicial de un framework

Lo siguiente que tenemos que hacer, igual que en los anteriores proyectos, es añadir al proyecto una clase con los ficheros Saludador.h y Saludador.m. Esta clase es la clase que compilamos en el framework.

Como hemos indicado anteriormente, los framework incluyen, junto a una librería de enlace dinámico, los ficheros de cabecera y documentación del producto. En nuestro caso, vamos a hacer que el fichero Saludador.h se incluya dentro de las cabeceras del framework, de forma que otras aplicaciones que usen nuestro framework puedan usarlo. Para ello, observe que Xcode ha añadido automáticamente el fichero Saludador.h a la etapa Copy Headers del target (véase Figura 1.13). Sin embargo, esta configuración que hace automáticamente Xcode con los ficheros de cabecera no es suficiente para que el fichero de cabecera sea incluido en el framework. Para que lo sea, debe seleccionar el fichero Saludador.h en la

Page 36: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

32 © RC Libros

etapa Copy Headers del target, y arrastrarlo desde el tipo Project al tipo Public. La Figura 1.13 muestra el resultado de realizar esta operación.

Figura 1.13: Proyecto del framework resultante

Enlazar con el framework

Ahora, vamos a mostrar cómo enlazar con el framework desde una aplicación de consola. Para ello, volvemos a crear un proyecto de consola como el de las secciones anteriores. Después, insertamos el framework Saludos.framework en el proyecto, usando la opción de menú File | Add File to "pidesaludo", o simplemente arrastrando Saludos.framework a nuestro proyecto pidesaludo. La Figura 1.14 muestra la forma de este proyecto.

El otro aspecto interesante es que no es necesario incluir en el proyecto el fichero Saludador.h del framework (con File | Add File to "pidesaludo"), ya que basta con que nuestro código se refiera al fichero de cabecera del framework usando el formato especial:

#import <Framework/Cabecera.h>

Page 37: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 33

Donde Framework es el nombre del framework, y Cabecera.h un fichero de cabecera del framework. Luego, para referirnos al fichero de cabecera Saludador.h usamos la siguiente directiva (véase Figura 1.14):

#import <Saludos/Saludador.h>

Ahora podríamos compilar y ejecutar la aplicación de consola.

Figura 1.14: Programa que usa el framework

Los ficheros de configuración Xcode

Los build settings (ver Figura 1.11) permiten indicar las opciones con las que GCC o Clang compilan un producto. Si disponemos de un conjunto de build settings comunes a muchos proyectos, resulta engorroso copiarlos de un proyecto a otro cada vez que abrimos un nuevo proyecto. Una forma elegante de solucionar este problema es creando un fichero de configuración Xcode (con la extensión .xcconfig). Este fichero puede ser compartido por muchos proyectos, o copiado a otros proyectos. Para crear este fichero, tenemos la opción de menú File | New | Other | Configuration Settings File.

Page 38: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

34 © RC Libros

Figura 1.15: Ejemplo de fichero de configuración Xcode

En la Figura 1.15 hemos creado un proyecto pcap con un fichero de configuración Xcode llamado libpcap.xcconfig. El Listado 1.8 muestra este fichero de configuración Xcode con las opciones de compilación que nos permiten acceder a la librería libpcap del paquete Fink.

// libpcap.xcconfig HEADER_SEARCH_PATHS=/sw/include LIBRARY_SEARCH_PATHS=/sw/lib LD_FLAGS=-lpcap

Listado 1.8: Fichero de configuración Xcode

Una vez creado el fichero de configuración, debemos indicar en qué configuraciones usarlo. En la Figura 1.15 hemos indicado que queremos usarlo en las configuraciones de Debug y Release. Al indicar que queremos usarlo a nivel de proyecto, estos build settings lo heredan todos los targets del proyecto.

Observe que los build settings del fichero libpcap.xcconfig se dan como pares clave-valor, donde la clave es el nombre interno del build setting. Podemos obtener

Page 39: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

CAPÍTULO 1: EMPEZANDO A PROGRAMAR CON OBJECTIVE-C

© RC Libros 35

este nombre interno seleccionando un build setting y pidiendo ayuda del elemento con Ctrl+Command+?, tal como muestra la Figura 1.16.

Figura 1.16: Obtener el nombre interno de un build setting

Los workspaces

Xcode 4 introduce el concepto de workspace, que básicamente es un contenedor de proyectos. Las principales ventajas que ofrece el workspace son:

• Todos los ficheros de un proyecto son visibles desde los demás proyectos del workspace. Es decir, no necesitamos copiar ficheros o librerías desde un proyecto a otro.

• Si un proyecto depende de un producto de otro proyecto del workspace, Xcode lo detectará automáticamente y comprobará que el producto del que dependemos esté actualizado antes de compilar nuestro proyecto.

Un proyecto se puede incluir en más de un workspace, o eliminar del workspace sin afectar al proyecto. El workspace simplemente tiene punteros a los proyectos. De hecho, toda la información de configuración se almacena en los proyectos.

Page 40: Curso práctico para programadores Mac OS X, iPhone y iPad · dispositivos móviles de Apple tales como iPhone, iPad o Apple TV. Mac OS X y iOS comparten un modelo de programación

OBJECTIVE-C. CURSO PRÁCTICO PARA PROGRAMADORES MAC OS X, IPHONE Y IPAD

36 © RC Libros

La Figura 1.17 muestra un workspace llamado libro.xcworkspace al que le hemos añadido varios de los proyectos que antes desarrollamos. Para crear el workspace, se usa la opción de menú File | New Workspace. Para añadir proyectos al workspace, usamos la opción de menú File | Add File to "libro", e indicamos el fichero de proyecto (.xcodeproj) a añadir. En la Figura 1.17, también vemos que para cambiar de proyecto actual debemos usar el popup desplegable de la esquina superior izquierda.

Figura 1.17: Workspace con proyectos