Posterous theme by Cory Watilo

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.