Posterous theme by Cory Watilo

Renombrar un proyecto en Xcode 4

En Xcode 3 había una opción para renombrar proyectos de Xcode, pero de nuevo en Xcode 4 (porqué en el 3.2 hacia atrás no existía), ha vuelto a ser no tan obvio.

Todo lo que tendrás que hacer es doble clic lentamente en la raíz del proyecto en el navegador del proyecto y entonces se convierte en editable. Después de cambiar el nombre del proyecto y pulsar 'enter'.

Quartz Composer - Demo 2 - Visualización de un ecualizador

Continuamos con nuestra visualización. Lo primero es abrir nuestra macro (doble-click sobre ella como ya comente antes) y añadir un patch Structure Index Member al editor. Conectamos el valor de salida de este nuevo patch al parámetro de entrada Inital Value de nuestro patch Amplificador. El visor parará de mostrarnos la barra animada que teníamos, no pasa nada.

Ahora mismo nuestra macro “Medidor Audio” solo tiene un parámetro de entrada (enabled). Ha llegado el momento de “hacer públicos” otros parámetros de nuestra macro (siguiendo con el símil de la programación tradicional).

Hacemos click derecho en el patch Structure Index Member y seleccionamos Published Inputs -> Structure, nos aparecerá un campo de texto donde podremos renombrar el parámetro, por ejemplo a Spectrum. Repetimos el mismo paso con el parámetro Index, y lo dejamos sin renombrar.

Highslide JS

Retornamos al nivel principal de la composición. Veremos como ahora nuestra macro tiene ahora dos nuevos parámetros de entrada, Spectrum e Index. Conecta el valor de salida Spectrum del patch Audio Input al nuevo parámetro de la macro, Spectrum. El visor volverá a mostrar nuestra barra animada pero la respuesta al sonido será más floja que antes (esto tiene que ver con el valor de Spectrum, que es más bajo que el de Volume Speak). Doble-Click sobre la macro para editarla de nuevo.

Click sobre el patch Amplificador, nos vamos al Inspector y seleccionamos en el botón Pop-Up “Settings”. Aquí modificamos “Number of Operations” a 2. Vemos como se añaden dos nuevos parámetros al patch. Seleccionamos “Input Parameters” en el botón Pop-Up y modificamos sus valores:

Highslide JS
  1. Operation #2: Multiply
  2. Operand #2: 10

Y diréis, ¿por que no multiplica por 100 poniendo 100 en el operand #1 y se deja de añadir otro Operand? Lo veréis ahora mismo.

Click derecho sobre el patch Amplificador, seleccionamos Published Inputs -> Operand #2 y lo renombramos a “Sensibilidad”. Esto nos servirá para controlar la amplitud del espectro amplificándola mucho o poco.

Lo siguiente es posicionar 12 columnas individuales de LEDs 2 veces para crear en total 24 columnas (12 a la derecha y 12 a la izquierda). Esto viene a ser modificar el parámetro X Position de Sprite y Cubo. ¡Vamos a ello!

Hacemos click derecho sobre el patch Structure Index Member y elegimos Insert Index Splitter -> Index. Esto nos creara un nuevo patch de nombre Index, lo seleccionamos. En sus Settings, en la ventana inspector configuramos su tipo a Number y sus min. y max. values a -12 y 12 respectivamente. Para acabar, hacemos click derecho sobre él (el patch) y seleccionamos Publish Inputs -> Input, renombrándolo a Index.

Añadimos un nuevo patch Mathematical Expession y configuramos sus Settings en el inspector añadiendo “abs(a)-1”. Ahora conectamos el valor de salida Output del patch Index al parámetro de entrada “a” del patch que acabamos de añadir y el valor de salida de este (Result) lo conectamos al parámetro de entrada Index del patch Structure Index Member.

Creamos otro patch Math y lo renombramos a Posicionador-X configurándolo como sigue:

  1. Initial Value: Arrastramos desde Index su valor de salida Output
  2. Operation #1: Multiply
  3. Operand #1: 0.075
Highslide JS

El valor 0.075 será multiplicado por otro valor (en el rango antes definido: -12, 12) para producir una posición en el eje X, dandonos un bonito espacio entre columnas. Para ello conectamos el valor de salida del Posicionador-X al parámetro de entrada X Position de los patches Cubo y Sprite.

¿Quieres probar lo que llevamos hecho? Pues volvemos al nivel principal y clickamos en la macro, en su configuración probamos a cambiar su parámetro Index (el cual solo se puede mover entre el rango -12, 12), como verás, al cambiar este valor la barra se mueve en el eje X. Lo dejamos a -12.

Pulsamos y mantenemos pulsada la tecla “option” (también llamada Alt en el mundo PC), hacemos click sobre el patch Medidor Audio (nuestra macro) y la arrastramos, esto nos creará una copia del patch. Ahora conectamos el valor de salida del patch Audio Input al parámetro de entrada de la copia creada de la macro. También debemos cambiar el parámetro Index de la copia, en este caso a -11.

Highslide JS

Ahora en el visor se mostrarán dos barras, ligeramente separadas. Este último paso debemos repetirlo 22 veces más, poniendo 12 barras entre el rango -12, -1 y otras 12 barras entre el rango 1, 12 (Sí, lo sé, un poco tedioso...).

Para que la aplicación en la que usemos nuestra visualización pueda decidir sobre la sensibilidad del espectro de audio necesitamos hacer un par de ajustes.

Click derecho sobre el Medidor Audio que tenía el Index -12 y elige Insert Input Splitter -> Sensibilidad. Seleccionamos el nuevo patch creado y en la ventana Inspector elegimos la sección Settings. En esta sección modificamos el min. y el max. values a 0 y 100 respectivamente. Conectamos su valor de salida Output al parámetro Sensibilidad de los patches Medidor Audio cuyo index sea -12 y 12. Hacemos click derecho sobre el patch y seleccionamos Publish Input -> Input, lo renombraremos como “Sensibilidad 12”.

Highslide JS

Este último paso debemos repetirlo pero para cada par de medidores (-11, 11; -10, 10; -9, 9;...), cambiando el uso de 12 por el número del par que estemos editando.

Con esto hemos acabado nuestra visualización y está preparada para ser usada en una aplicación.

 

 

 

(download)

Quartz Composer - Demo 1 - Visualización de un ecualizador

Lo primero que necesitamos para esta composición es crear un fondo negro. Para ello arrastramos desde la “Patch Library” un patch llamado Clear, esto limpiará el fondo del color que queramos, negro en este caso, y el cual es ya el color por defecto del patch.

Highslide JS

Bien, continuamos añadiendo dos paches más, un Cube y un Audio Input desde la Patch Library. Renombramos el patch Cube, haciendo doble-click sobre el nombre del patch, a “Cubo”. Arrastramos el valor de salida Volume Peak del patch Audio Imput hasta el parámetro de entrada Height de Cubo.

Ahora modificamos un par de parámetros más de Cubo abriendo el Inpector:

1.Width: 0.045
2.Depth: 0

En estos momentos el cubo ya responde al sonido, pero de una manera bastante floja, para solucionarlo añadimos un nuevo patch, un patch Math. Lo modificamos:

1.Renómbralo a: “Amplificador”
2.Initial Value; Arrastra el Volume Peak desde el patch Audio Input.
3.Operation #1: Multiply
4.Operand #1: 10

Lo siguiente será hacer que el cubo se mueva de arriba a abajo. La parte de arriba del cubo es como si estuviese anclada y solo se pudiese mover la parte de abajo estirándose y contrayéndose desde abajo. Pues bien, para conseguir esto añadiremos dos nuevos patch Math y los modificaremos
como sigue:

Highslide JS

1.Renombra a uno como “Divisor”
2.Operation #1: Divide
3.Operand #1: 2

1.Renombra al otro como “Posicionador-Y”
2.Initial Value: 0
3.Operation #1: Subtract
4.Operand #1: Arrastra el Resulting Value desde el patch Divisor

Arrastra el Resulting Value del patch Posicionador-Y hasta el parámetro Y Position del patch Cubo. Con esto, como verás, la parte superior del cubo queda anclada y éste crece para abajo.

Bien, ahora nos centraremos en darle a nuestra composición un mejor aspecto añadiendo una bonita columna de LEDs para lograr el efecto visual deseado. Lo que haremos es construir la columna de LEDs y el cubo creado hasta ahora nos servirá para enmascarar o revelar los LEDs.

Añadimos un nuevo patch Math:

1.Renómbralo a: “Inversor”
2.Initial Value: 1
3.Operation #1: Subtract
4.Operand #1: Arrastra el Resulting value desde el patch Amplificador

Y modificamos el Posicionador-Y:

1.Initial Value: 1
2.Operation #1: Add
3.Operand #1: Arrastramos el Resulting Value desde el patch Divisor

Arrastra el Resulting Value del Inversor hasta el parámetro Height del Cubo. Pasamos, ahora si, a crear la columna de LEDs, para ello creamos un patch Sprite y modificamos su parámetro Width a 0.045.

Una cosa que no comenté anteriormente en la parte “teórica” es como manejar el nivel de visualización entre los patches, bien, si nos fijamos en el aspecto de los patches Cubo y Sprite veremos que tienen unos cuadrados amarillos situados en la esquina superior derecha, con un número en su interior.

Highslide JS

Ese número indica la capa en la que está situado el patch y si hacemos click en él nos deja elegir la capa (layer) en la que situar el patch. El funcionamiento y comportamiento es parecido que el de las capas de Photoshop (un símil siempre ayuda a situarse), las capas de menor numeración se sitúan detrás de las capas de mayor numeración.

Después de esta explicación vamos a cambiar la capa del Sprite para situarla detrás de la capa del Cubo. Para ello, hacemos click en el número de Sprite y seleccionamos Layer 2. Después de hacer esto los patches Clear y Cubo deberían tener como capa los números 1 y 3 respecivamente.

Seguimos añadiendo un patch Linear Gradient, configurándolo así:

1.Renómbralo a: “Gradiente”
2.Point 1 (X): 0
3.Point 1 (Y): 100
4.Point 2 (X): 0
5.Point 2 (Y): 200
6.Color 1: Green
7.Color 2: Red

Los gradientes necesitan ser “cropeados” (cropped, es decir, eliminar las aristas y quedarnos con la parte interior). Para ello arrastramos un patch Image Crop al editor y conectamos el valor de salida Image del patch Gradiente hasta el parámetro de entrada del patch que acabamos de añadir (Image Crop).

Si ahora arrastramos el valor de salida Cropped Image del patch Image Crop hasta el parámetro de entrada Image de nuestro patch Sprite obtendremos una barrita coloreada con un bonito gradiente verde-rojo y sin ningún tipo de arista que nos moleste. Perfecto. Lo siguiente será crear el efecto de LEDs.

Añadimos un nuevo patch, Linear Screen y pasamos a configurarlo:

1.Center (X): 0
2.Center (Y): 10
3.Angle: 90
4.Width: 4
5.Sharpness: 1

Highslide JS

Conectamos el valor de salida Cropped Image del patch Image Crop con el parámetro de entrada Image del patch Linear Screen. El valor de salida de este último arrástralo hasta el parámetro de entrada Mask Image del patch Sprite.

Para terminar sitúate en Cubo y configura su Front Color a negro. ¡Ya lo tenemos! nuestra barra danzante de brillantes LEDs. Bien, aún quedan por construir sus 23 compañeras restantes, pero antes de pasar a eso un pequeño retoque a lo que tenemos.

Seleccionamos todos los patches menos Clear y Audio Input. Hacemos click en el botón de la toolbar llamado “Create Macro”, esto nos meterá todos los patches que teníamos seleccionados en un solo pacth individual llamado Macro Patch. Lo renombramos a “Medidor Audio” por ejemplo. Si quisiésemos editar los patches que teníamos antes (Cubo, Sprite, etc) simplemente haríamos doble-click en cualquier parte del patch macro (o padre) que no fuese en la parte del nombre y se nos mostrarían sus patches hijas. Para volver al padre hacemos click en el botón de la toolbar “”Edit Parent”

Highslide JS

Ahora sí, nuestra primera barra a quedado perfecta. En la siguiente parte de la demo veremos como construir 23 barras más (¡Tranquilos!, no os asustéis, no tendremos que repetirlo todo otra vez 23 veces, por algo hemos creado un macro antes), reaccionando cada barra de forma particular al espectro del audio.

(download)

Quartz Composer - Un entorno para la programación visual

Lo primero que notas al abrir Quartz Composer es que no es como las demás herramientas de desarrollo que hayas visto. Se parece mucho más a un programa de composición de vídeo como puede ser Flame, Nuke o Fusion. Y es que en esencia es lo que es: un compositor de animaciones / vídeo, pero para uso más orientado al desarrollo de aplicaciones gráficas (aunque también las composiciones echas en él pueden ser importadas en programas de edición de video como Final Cut).

Highslide JS

En lugar de escribir cientos o miles de líneas de código manipularemos varias librerías gráficas del sistema (las tecnologías nombradas más atrás) de forma visual procesando objetos llamados “patches” (podríamos traducirlos como parches, pero yo me referiré a ellos en la demo por su termino original, “patch”). Cuando se trabaja en una composición,añadiendo patches y conectándolas, puedes ver el resultado en un visor (la “viewer window”). Cada uno de los cambios que se hagan serán reflejados inmediatamente en el visor, esto quiere decir que no necesita ningún tipo de compilación.

Un patch es similar a las funciones o procedimientos de los lenguajes de programación tradicionales. Se les puede proveer de parámetros de entrada y el patch se ejecutará y producirá algún resultado. Los círculos de la columna de la izquierda representarían lo diferentes parámetros que el patch acepta. Los círculos de la columna de la derecha son las salidas que el patch produce. Los tipos de entradas y salidas que acepta y produce respectivamente dependen de la funcionalidad del patch.

Highslide JS

Por ejemplo, el patch Math (lo utilizaremos en la demo) acepta los parámetros: Initial Value, Operation #1, Operand #1 y retorna un Resulting Value, los tipos de estos valores son: Number, Index, Number y Number. ¿Qué cómo se sabe esto? Pues yo simplemente dejo el puntero del ratón sobre el nombre del parámetro y me sale una descripción detallada de él (Descripción, tipo y valor que tiene en ese momento).

Los parámetros de entrada pueden ser modificados de dos formas diferentes. La primera es por medio de la ventana “Inspector”, en la cual podremos modificar otras muchas cosas además de sus parámetros de entrada, para mostrar esta ventana hacemos click sobre un patch y pulsamos “manzana + i”.

Highslide JS

La segunda opción es conectar un valor de salida de otro patch al parámetro de entrada de otro diferente. Como vemos en la imagen de la izquierda: La ventana Inspector nos muestra los valores de entrada del patch Random, mientras que el valor de salida (Value) de este se conecta al parámetro de entrada del patch Math, Initial Value. Cuando la composición se inicie, el patch Random generará un número aleatorio entre 0 y 10, y lo devolverá como valor de salida, pasando al Initial Value del patch Math.

Como vemos, básicamente el flujo de trabajo en Quartz Composer consiste en seleccionar de la Patch Library los patches que queramos usar y conectarlos entre ellos para lograr el efecto deseado.

Así pues, como lo mejor para entender algo es un buen ejemplo, vamos a ello.

 

¿Qué es Quartz? - Algunos conceptos

Quartz es el corazón gráfico de Mac OS X. Provee soporte a renderización de contenido 2D y combina un rico modelo de imagen con renderización, composición y anti-aliasing de contenidos, todo ello al vuelo. También implementa el sistema de ventanas para Mac OS X y ofrece servicios de bajo nivel como rutinas de eventos y manejo del cursor.

Quartz consta de un API (Quartz 2D) y un servidor de ventanas (Quartz Compositor). El API provee clases para manejar el contexto gráfico y para dibujar primitivas, imágenes, texto y otro contenido. El servidor de ventanas controla la pantalla y ofrece servicios esenciales tales como manejo básico de ventanas, rutinas de eventos y manejo del comportamiento del cursor.

El API Quartz 2D está implementada como parte del framework “Application Services” (ApplicationServices.framework), el cual es el que debes incluir en tus proyectos si quieres usar Quartz. Este framework incluye a su vez el framework Core Graphics (CoreGraphics.framework). Este define las interfaces, tipos y constantes de Quartz que se usarán en tus aplicaciones.

El API Quartz Services (el cual también es parte del framework Core Graphics) provee acceso directo a algunas características de bajo nivel del servidor de ventanas. Puedes usar este API para coger información sobre el monitor conectado, capturar el monitor para uso exclusivo o ajustar los atributos del monitor, tales como su resolución, profundidad, frecuencia de refresco...

Quartz también ofrece soporte para operar remotamente un sistema Mac OS X.

La metáfora del papel digital:

La arquitectura de imagen de Quartz está basada en una “metáfora” del papel digital. En este caso, el papel digital es el PDF, el cual es el modelo interno usado por Quartz para almacenar el contenido renderizado. El contenido almacenado en este medio tiene una altísima fidelidad y puede ser reproducido en muchos tipos diferentes de dispositivos, como monitores, impresoras y fax. Este contenido puede ser escrito a un archivo PDF y ser visto por cualquier aplicación que pueda abrir PDFs.

El modelo PDF da al desarrollador mucho más control sobre la apariencia final de sus contenidos. PDF tiene en cuenta caracerísticas de la aplicación como por ejemplo el espacio de color, fuentes, compresión de la imagen y resolución.

 

Mac OS X toma algunas de las ventajas de la flexibilidad de PDF implementado con él algunas de sus características. Por ejemplo, al imprimir; el dialogo de impresión ofrece opciones tales como salvar el documento como un PDF, vista previa del documento antes de imprimir o enviarlo por fax. El PDF usado por estas operaciones viene de la misma fuente: el código de renderizado de la aplicación. La única diferencia es el dispositivo a donde enviar el contenido.

Quartz Compositor

Quartz Compositor, el servidor de ventanas de Mac OS X, coordina todos los comportamientos de bajo nivel de las ventanas y hace cumplir una igualdad uniforme en cuanto a la apariencia en la pantalla. Maneja las pantallas disponibles en el sistema de usuario, interactuando con el driver del dispositivo necesario.

Para la administración de ventanas, Quartz Compositor maneja la composición de todo el contenido visible del escritorio del usuario. Soporta efectos de transparencia a través del uso del canal de información alfa, lo cual hace posible mostrar sombras, recortes y otros efectos que añaden una textura más real y voluminosa a la ventana.

La ejecución de Quartz Compositor permanece constantemente activa por diversos factores. Para mejorar el redibujado de la ventana, Quartz Compositor soporta un bufer de ventanas y un sistema de capas componiendo la ventana y el contenido de la ventana. Así, las ventanas que son ocultadas detrás de contenido opaco no son nunca compuestas. Quartz Compositor incorpora también Quartz extreme, con lo que la velocodad de render aumenta haciendo llamadas al hardware gráfico siempre que sea posible.

La figura de abajo muestra las relaciones de alto nivel entre Quartz Compositer y las tecnologías de renderizado disponibles en Mac OS X. Quicktime y OpenGL tienen menos dependencias en Quartz Compositor por que implementan sus propias versiones para asegurarse ciertas capacidades.

Quartz 2D

Quartz 2D provee muchas características importantes para aplicaciones, algunas de ellas son:

  • Renderizado de alta calidad en pantalla.
  • Soporte para interfaces de usuario independientes de la resolución.
  • Anti-Aliasing para gráficos y texto.
  • Soporte para añadir información de transferencias a la ventana.
  • Compresión interna de datos.
  • Manejo del color a través de ColorSync.
  • Generación automática de PDF para impresión, envío de fax o guardado como PDF.

Algunas especificaciones técnicas sobre Quartz:

  • Profundidad de Bit: Mínimo una profundidad de 16-bits para usuarios normales. Una profundidad de 8-bits en modo pantalla completa para juegos, aplicaciones multimedia y aplicaciones Clásicas (aplicaciones de Mac OS9 o anteriores).
  • Resolución mínima: Soporte para 800x600 como resolución mínima para usuarios normales. 640x480 está disponible para iBooks y así como para juegos, aplicaciones multimedia y aplicaciones Clásicas (aplicaciones de Mac OS9 o anteriores).
  • Quartz Extreme: Quartz Extreme usa OpenGL para dibujar el escritorio de Mac OS X. Todo ello se lleva a cabo usando la GPU, liberando a la CPU para otras tareas.


Texto: Davíd Arias Vazquez

 

Renombar un proyecto en Xcode

Click here to download:
renameXcodeProject.sh (5 KB)

Siempre que reutilizamos un proyecto, una de las partes más difíciles de controlar con Xcode es el renombrado, ya que se hace largo y tedioso.

Pues bien, hace tiempo encontramos un script que hace esta tarea mucho más sencilla y que os adjuntamos más abajo.

 
#!/bin/sh 
 
################################################################################ 
# 
# renameXcodeProject.sh 
# 
# author: Monte Ohrt  
# date: Jan 27, 2009 
# version: 1.0 
# 
# This script will copy an xcode project to a new project directory name 
# and replace/rename all files within to work as expected under the new name. 
# Project names that contain characters other than alpha-numeric, spaces or 
# underscores MAY not work properly with this script. Use at your own risk! 
# Be CERTAIN to backup your project(s) before renaming. 
# 
# One simple rule: 
# 
# 1) The old project name cannot contain the new project name, so for instance, 
# renaming "MyStuff" to "MyStuff2" will not work. If you really need to do 
# this, rename the project to a temp name, then rename again. 
# 
# I also have instructions for manually renaming an xcode project here: 
# 
# http://mohrt.blogspot.com/2008/12/renaming-xcode-project.html 
# 
# 
# Installation: 
# 
# Copy (this) file "renameXcodeProject.sh" to your file system, and invoke: 
# 
# chmod 755 renameXcodeProject.sh 
# 
# to make it executable. 
# 
# usage: 
# 
# renameXcodeProject.sh   
# 
# examples: 
# 
# ./renameXcodeProject.sh OldName NewName 
# ./renameXcodeProject.sh "Old Name" "New Name" 
# 
################################################################################ 
 
OLDNAME=$1 
NEWNAME=$2 
 
# remove bad characters 
OLDNAME=`echo "${OLDNAME}" | sed -e "s/[^a-zA-Z0-9_ -]//g"` 
NEWNAME=`echo "${NEWNAME}" | sed -e "s/[^a-zA-Z0-9_ -]//g"` 
 
TMPFILE=/tmp/xcodeRename.$$ 
 
if [ "$OLDNAME" = "" -o "$NEWNAME" = "" ]; then 
 echo "usage: $0  " 
 exit 
fi 
 
echo "${NEWNAME}" | grep "${OLDNAME}" > /dev/null 
if [ $? -eq 0 ]; then 
 echo "Error: New project name cannot contain old project name. Use a tmp name first. Terminating." 
 exit 
fi 
 
if [ ! -d "${OLDNAME}" ]; then 
 echo "ERROR: \"${OLDNAME}\" must be a directory" 
 exit 
fi 
 
# set new project directory 
if [ -d "${NEWNAME}" ]; then 
 echo "ERROR: project directory \"${NEWNAME}\" exists. Terminating." 
 exit 
fi 
 
# be sure tmp file is writable 
cp /dev/null ${TMPFILE} 
if [ $? -ne 0 ]; then 
 echo "tmp file ${TMPFILE} is not writable. Terminating." 
 exit 
fi 
 
# create project name with unscores for spaces 
OLDNAMEUSCORE=`echo "${OLDNAME}" | sed -e "s/ /_/g"` 
NEWNAMEUSCORE=`echo "${NEWNAME}" | sed -e "s/ /_/g"` 
 
# copy project directory 
echo copying project directory from "${OLDNAME}" to "${NEWNAME}" 
cp -rp "${OLDNAME}" "${NEWNAME}" 
 
# remove build directory 
echo removing build directory from "${NEWNAME}" 
rm -rf "${NEWNAME}/build" 
 
#find text files, replace text 
find "${NEWNAME}/." | while read currFile 
do 
 # find files that are of type text 
 file "${currFile}" | grep "text" > /dev/null 
 if [ $? -eq 0 ]; then 
 # see if old proj name with underscores is in the text 
 grep "${OLDNAMEUSCORE}" "${currFile}" > /dev/null 
 if [ $? -eq 0 ]; then 
 # replace the text with new proj name 
 echo found "${OLDNAMEUSCORE}" in "${currFile}", replacing... 
 sed -e "s/${OLDNAMEUSCORE}/${NEWNAMEUSCORE}/g" "${currFile}" > ${TMPFILE} 
 mv ${TMPFILE} "${currFile}" 
 cp /dev/null ${TMPFILE} 
 fi 
 # see if old proj name is in the text 
 grep "${OLDNAME}" "${currFile}" > /dev/null 
 if [ $? -eq 0 ]; then 
 # replace the text with new proj name 
 echo found "${OLDNAME}" in "${currFile}", replacing... 
 sed -e "s/${OLDNAME}/${NEWNAME}/g" "${currFile}" > ${TMPFILE} 
 mv ${TMPFILE} "${currFile}" 
 cp /dev/null ${TMPFILE} 
 fi 
 fi 
done 
 
# rename directories with underscores 
find "${NEWNAME}/." -type dir | while read currFile 
do 
 echo "${currFile}" | grep "${OLDNAMEUSCORE}" > /dev/null 
 if [ $? -eq 0 ]; then 
 MOVETO=`echo "${currFile}" | sed -e "s/${OLDNAMEUSCORE}/${NEWNAMEUSCORE}/g"` 
 echo renaming "${currFile}" to "${MOVETO}" 
 mv "${currFile}" "${MOVETO}" 
 fi 
done 
 
# rename directories with spaces 
find "${NEWNAME}/." -type dir | while read currFile 
do 
 echo "${currFile}" | grep "${OLDNAME}" > /dev/null 
 if [ $? -eq 0 ]; then 
 MOVETO=`echo "${currFile}" | sed -e "s/${OLDNAME}/${NEWNAME}/g"` 
 echo renaming "${currFile}" to "${MOVETO}" 
 mv "${currFile}" "${MOVETO}" 
 fi 
done 
 
# rename files with underscores 
find "${NEWNAME}/." -type file | while read currFile 
do 
 echo "${currFile}" | grep "${OLDNAMEUSCORE}" > /dev/null 
 if [ $? -eq 0 ]; then 
 MOVETO=`echo "${currFile}" | sed -e "s/${OLDNAMEUSCORE}/${NEWNAMEUSCORE}/g"` 
 echo renaming "${currFile}" to "${MOVETO}" 
 mv "${currFile}" "${MOVETO}" 
 fi 
done 
 
# rename files with spaces 
find "${NEWNAME}/." -type file | while read currFile 
do 
 echo "${currFile}" | grep "${OLDNAME}" > /dev/null 
 if [ $? -eq 0 ]; then 
 MOVETO=`echo "${currFile}" | sed -e "s/${OLDNAME}/${NEWNAME}/g"` 
 echo renaming "${currFile}" to "${MOVETO}" 
 mv "${currFile}" "${MOVETO}" 
 fi 
done 
 
rm -f ${TMPFILE} 
 
echo finished. 

Guardando los ajustes con la clase NSUserDefaults

Moz-screenshot-1
Cuando queremos guardar los ajustes de nuestra aplicación, podemos usar NSUserDefaults que hace que nuestra vida sea mucho más facil cuando nos proponemos este objetivo. La aplicación que vamos a construir como un ejemplo es un control segmentado que recordará qué botón seleccionamos la última vez que ejecutamos la aplicación en cuestión.

La clase NSUserDefaults trabaja como un diccionario. Para un key dado, puedes proveer algunos tipos primitivos y algunos tipos de objetos como por ejemplo: NSData, NSString, NSNumber, NSDate, NSArray, o NSDictionary. Estos valores se guardarán en una base de datos y serán guardados en la caché para incrementar el rendimiento de la aplicación si se les invoca con frecuencia.

Estos datos  se guardarán periódicamente a disco, aunque sin embargo tendrás que llamar manualmente a la sincronización cuando la aplicación está apunto de salir.

En la aplicación de ejemplo, añadir un UISegmentedControl es bastante sencillo con lo que te dejamos eso a tu cargo. Lo que pretendemos cubrir en este tutorial es como actualizar la base de datos cuando la selección ha cambiado y como establecer el index cuando la aplicación se ejecute. Primero capturaremos el evento cuando el índice cambie y lo guardaremos

 - (IBAction)selectionChanged:(id)sender {
   NSInteger index = ((UISegmentedControl*)sender).selectedSegmentIndex;
   
   // Get the shared defaults object.
   NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
   
   // Save the index.
   [settings setInteger:index forKey:@"MySelectedValueKey"];
   
   // Write them to disk - this is optional here,
   // but should be done when the app exits.
   [settings synchronize];
 } 


Como puedes ver es bastante sencillo guardar cosas. Primero capturo el index seleccionado del UISegmentedControl, y después lo guardo con su correspondiente "key" en "MySelectedValueKey". El key puede ser cualquier cosa que quieras probablemente podría establecerse con un #define. Lo último que hacemos es sincronizar con la base de datos, la cual guarda todos los cambios en el disco. Esto no tiene que hacerse aquí, pero al menos deberías hacerlo cuando la aplicación se termina o arriesgarás que no se guarden tus cambios.

Lo siguiente que tenemos que hacer es establecer el índice seleccionado una vez la app se arranca de nuevo para que se abra como la dejamos por última vez.

 - (BOOL)application:(UIApplication *)application 


didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    


    
   // Override point for customization after application launch.
     
   [self.window makeKeyAndVisible];
   
   // Get the settings and set the selected index.
   NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
   if([settings objectForKey:@"MySelectedValueKey"] != nil) {
     options.selectedSegmentIndex = [settings integerForKey:@"MySelectedValueKey"];
   }
     
   return YES;
 }
 

NSUserDefaults no tiene una gran manera de saber si un key existe. Como objectForKey devolverá nil si no hay nada allí, me gusta usar este método. Si algo está allí, entonces usamos algo más específico como integerForKey y establecemos el índice seleccionado al valor guardado en la base de datos.


NSUserDefaults doesn't have a great way to see if a key exists. Since objectForKey will return nil if there's nothing there, I like using that method. If something is there, then I use the more specific integerForKey method and set the selected index to the value stored in the database.

 

Core Plot: Gráficas en tus aplicaciones

Normalmente nos encontramos con la necesidad de mostrar algún tipo de gráfico en nuestra aplicación de iOS u OSX. Por esta razón, para casi cualquier lenguaje disponible ahí fuera, siempre hay al menos un tipo de librería de ploteado y gráficos. En el caso de iOS me he encontrado con una librería curiosa y que además es open source, llamada Core Plot Esta librería parece estar bajo desarrollo muy activo y puede usarse para crear distintos tipos de gráficos como por ejemplo los que se pueden ver en está página.

Para conseguir esta librería, necesitaremos instalar el sistema de versiones llamado mercurial de la siguiente manera. Si no lo tenemos instalado, lo descargamos de su web oficial e instalamos el dpkg normalmente. Una vez hecho eso arrancamos una ventana de terminal, nos vamos al directorio donde queramos descargar el código fuente y escribimos el siguiente comando:

hg clone http://core-plot.googlecode.com/hg/ core-plot

El último argumento del comando anterior (core-plot) será el directorio donde haremos el check-out.

Una vez que tenemos el código veremos que dispone de varios ejemplos para iOS y OSX que podremos reusar para nuestra aplicación. Simple, intuitivo y rápido de implementar.