Archivo de la categoría: XCode

Añadiendo un remoto a un proyecto en XCode5

En uno de los comentarios de la al post sobre las novedades de XCode 5, nos comentaba un lector que estaba teniendo algún problema para añadir un repositorio remoto a un proyecto en XCode 5. A continuación os indico cómo hacerlo usando la interfaz gráfica. Para ello, necesitamos lo siguiente:

  • Un proyecto XCode 5 que ya está bajo git.
  • La URL de un repositorio remoto, ya sea en BItbucket, Github, gitolite o el que sea en vuestro caso

Añadiendo un repositorio remoto git en Xcode 5

Desplegamos el menú “Source Control” dentro de XCode en nuestro proyecto. Dentro de este menú, en la sección “Working Copies”, seleccionáis la única que inicialmente tendréis y que contiene el nombre del proyecto y la rama (normalmente master). En el submenú que se despliega, debéis seleccionar la última opción, que se llama “Configure [nombre del proyecto]”.

Menú "Source Control" desplegadoAl hacer esto, nos aparecerá una ventana emergente con tres pestañas. Seleccionamos la pestaña “remotes” que mostrará un listado vacío. En la parte inferior derecha, hacemos clic sobre el icono “+” y se desplegará un menú con dos opciones:

  • Add remote
  • Create new remote

Seleccionamos la primera opción: “Add remote”

menú re repositorios remotosEn la siguiente ventana emergente que nos aparecerá, añadimos el nombre del repositorio remoto en el campo “Name” y la URL del repositorio en el campo “Address”

Selección de nombre del remoto y URLPresionáis en “Add Remote” y listo, ya tenéis el repositorio remoto configurado.

Para terminar, desplegáis el menú “Source Control”, y seleccionáis push. En la ventana emergente seleccionáis el repositorio remoto que acabáis de crear, pulsáis el botón “Push” y ya tenéis el repositorio en vuestro remoto.

“Create New Remote”

En el menú de creación del repositorio remoto, hay una opción adicional “Create new remote” que está relacionada con las nuevas funcionalidades que nos traerá Mavericks y de la que hablaremos en un futuro.

Repaso rápido a las novedades de git en XCode 5

Hace ya una semana que la nueva versión de XCode, la versión 5, está disponible públicamente en la Mac App Store. En la presentación de la NSSpain de Logroño la semana pasada comenté que el soporte para git dentro de XCode ha mejorado en esta nueva versión aunque no pude entrar en detalles (cosas del NDA). Voy a empezar a destripar cuáles son las novedades que tenemos a nuestra disposición.

La cosa ha mejorado pero…

La verdad es que no es para echar cohetes. El cliente git sigue estando a años luz de otros IDEs que lo tienen integrado como Eclipse, Netbeams o los productos de jetbrains. Y si lo comparamos con SourceTree, Git Tower o Smart Git te das cuenta de que los ingenieros de Apple todavía tienen mucho trabajo por hacer.

Ahora bien, con las novedades que hay disponibles lo cierto es que hay algunas tareas más o menos recurrentes que ahora sí podemos hacer desde XCode, ahorrándonos unos cuantos cambios de pantalla al día.

Hacer commits desde XCode

Esta es una opción que ya estaba disponible en las versiones anteriores. Basta pulsar CMD-ALT-C para que se abra la interfaz, escribamos el mensaje y hagamos el commit. Esta pantalla no ha cambiado prácticamente nada con respecto a la versión 4.

Operaciones más habituales

Una de las características que tiene que tener cualquier SCM es la de “desaparecer”, es decir, no darte cuenta de que lo estás usando. Las operaciones que hagas con él deben de ser rápidas y ágiles. Pues bien, XCode 4 estaba diseñado justo para lo contrario: para crear una rama era necesario abrir el organizador. El proceso era lento y suponía tener que cambiar de ventana, buscar un botón por ahí escondido, crear la rama, cambiarnos a ella y volver a la ventana del proyecto.

Aquí hay una sustancial mejoría. Ahora disponemos de un menú en la parte superior desde el que podemos hacer las operaciones más comunes: crear ramas, cambiarnos de rama, hacer push y hacer pull, deshacer cambios, resolver conflictos e incluso gestionar los remotos.Nuevo menú SCM en XCode5

Estas son las tareas más comunes así que cuando estamos trabajando nosotros solos o tenemos un flujo de trabajo muy simple, este menú nos puede ahorrar el tener que estar cambiando de aplicación para hacer cosas sencillas.

Gestión de repositorios remotos

La gestión de repositorios remotos del proyecto es ahora mucho más cómoda. En las pruebas que he realizado, he podido añadir el repositorio remoto de bitbucket y ha cogido mi clave SSH sin tener que hacer nada. En cuestión de un minuto tenía el remoto configurado y haciendo push/pull. En una entrada posterior veremos cómo hacerlo.

Mejoras sustanciales en la estructura de los ficheros XML

Esta es posiblemente la parte que más expectación ha despertado en los últimos meses desde que las versiones para desarrolladores han estado disponibles: ¡ahora se pueden hacer merges de los Story Boards!

Las mejoras más evidentes son:

  • Si ahora abres el story board o el fichero xib y no tocas nada, el fichero no aparece como modificado (lo que significa que no da conflictos).
  • Por otro lado, el formado de los ficheros ha cambiado y el XML, aunque sigue teniendo su miga, es más legible.
  • Este formato permite resolver conflictos en los XIB/Story Boards con mucha más facilidad, incluso de forma automática en algunos casos. En una primera prueba muy sencilla en la que creé dos botones en el mismo lugar en dos ramas diferentes dentro de un fichero .xib, pude resolver el conflicto muy fácilmente copiando un trozo del XML.

Aunque hay mejoras en este sentido, yo sigo siendo muy escéptico  En una prueba más elaborada en la que modifiqué un story board en dos ramas diferentes, la resolución del conflicto no era ya tan evidente y el XML no estaba tan claro. Me imagino que con un poco de práctica y experiencia será más fácil resolver los conflictos. Os iré contando cómo evoluciono según vaya usando más la herramienta.

¡El commit inicial incluye la configuración del IDE (xcuserdata)!

En XCode 4, cuando creabas un proyecto, había algunos ficheros que XCode no añadía al repositorio, en particular las carpetas xcuserdata. Pues bien, eso ya no es así y cuando creas un proyecto y marcas la casilla para que se cree el repositorio, XCode añade al repositorio todos los ficheros, incluido las carpetas xcuserdata.

A mi personalmente no me gusta tener esta información en el repositorio. Es cierto que existen algunos casos en los que puede ser útil: si queréis que todo el mundo comparta la configuración del IDE o para compartir breakpoints entre los miembros de un equipo. Mi experiencia es que en general, suele ser una fuente de conflictos que me quitan mucho tiempo y por eso ignoro estas carpetas en el .gitignore.

La que se lleva la palma…

La funcionalidad que más me gusta de todas las novedades que incluye XCode 5 en cuanto a la gestión de código fuente se refiere es…¡¡Poder desactivarla!!

Si abris las preferencias y vais a “Source Control”, podéis desactivar el soporte SCM. Si lo hacéis, lo único que ocurre es que XCode ignora el repositorio git del proyecto, las opciones del menú “Source Control” aparecen desactivadas y el soporte para git deja de funcionar. El repositorio git queda intacto, así que podéis seguir usando la línea de comandos o vuestro cliente favorito para seguir gestionando el código fuente fuera de XCode.

Si después queréis activarlo, deshacéis los pasos y listo; eso sí, tuve que cerrar el proyecto y volverlo a abrir para que la interfaz volviera a mostrar los ficheros modificados y añadidos.

Voila_Capture289

Lo que sigo echando en falta

Aunque la cosa ha mejorado mucho, todavía echo en falta algunas cosas:

  • No entiendo la obsesión por ocultar el grafo. El grafo es ese típico dibujito lleno de pelotas, líneas y etiquetas que al principio no se entiende bien. Una vez sabes cómo funciona, cuesta trabajar en un repositorio sin él y en XCode no está.
  • Stashing
  • Rebasing
  • Poder hacer commits de parte de un fichero (interactive staging)
  • Más documentación acerca del formato XML de los xib y story boards (si alguien sabe dónde está que por favor nos lo diga). Eso nos permitiría resolver los conflictos más fácilmente.
  • Poder trabajar con flujos de trabajo un poco más elaborados. Si habéis trabajado o estáis trabajando con git-flow, vais a necesitar línea de comandos o Sourcetree necesariamente.

Conclusión

Si no te quieres complicar y el uso que haces de git se limita a hacer commits, push y pull, crear ramas y hacer merge, estás de enhorabuena: estas operaciones puedes hacerlas ya de manera rápida y efectiva en la nueva interfaz.

Ahora bien, si os soy sincero, la mayoría del tiempo sigo teniendo desactivado el soporte git y usando SourceTree y la línea de comandos, como hacía antes. El motivo principal: en cuanto quieres hacer cosas “normales” como un rebase, se te queda corto.

Por último, aunque el formato del fichero hace más sencillo el merging de ramas, sigo siendo escéptico en cuanto al uso de Story Boards. Sólo espero que esto no desemboque en Apple eliminando el soporte para ficheros xib en XCode ¡me tocará hacerlo todo por código!

.gitignore en XCode

Cuando creamos un proyecto nuevo en XCode y marcamos la opción para que utilice el control de versiones, ¿qué está haciendo XCode por debajo?

Básicamente sigue los siguientes pasos:

  • Crea e inicializa un repositorio git en la carpeta raíz del proyecto
  • Añade todos los ficheros al repositorio excepto las carpetas [nombre].xcodeproj/project.xcworkspace y [nombre].xcodeproj/xcuserdata/
  • Hace un commit con el comentario “Initial Commit”

Para ver en qué estado ha quedado el repositorio vamos a seguir los siguientes pasos:

  • Creamos proyecto nuevo en XCode, cualquiera de las plantillas que vienen por defecto nos vale (tanto de iOS como de Mac)
  • Abrimos SourceTree
  • En la ventana “bookmarks” hacemos clic sobre el icono para añadir repositorio

Añadiendo repositorio de XCode a SourceTree paso 1

  • A continuación seleccionamos “Add working copy”, ya que XCode ya ha inicializado el repositorio por nosotros. En el campo “Working copy path” buscamos la carpeta en la que está nuestro proyecto e introducimos un alias campo “”Bookmark Name” si el que crea SourceTree no nos gusta. Hacemos clic sobre “Add” cuando hayamos terminado

Añadiendo repositorio XCode a SourceTree paso 2

  • Cuando se cierre la ventana y volvamos al listado de repositorios de SourceTree, hacemos doble clic sobre el repositorio que acabamos de crear

Los ficheros que XCode no incluye

Cuando git crea el repositorio, añade el siguiente contenido al fichero .git/info/exclude

.DS_Store
UserInterface.xcuserstate

Este fichero, a diferencia de .gitignore, contiene reglas que se aplican sólo a nuestro repositorio local (si compartimos el repositorio con otros usuarios a través de github o bitbucket, no verán estas reglas).

Aparte de estas dos reglas, ¿qué más no ha incluido XCode en el repositorio nada más crearlo?

Si no habéis abierto todavía el repositorio en SourceTree (haced doble clic sobre él en la ventana de Bookmarks) hacedlo ahora. A la izquierda haced clic sobre la rama master, veréis que en la sección “Files in the working tree” nos aparecen los ficheros que XCode no ha añadido al repositorio:

Ficheros nos incluidos por XCode en el repositorio

Si os fijáis, estos ficheros no están incluidos y no se están ignorando. Eso significa que cualquiera podría añadirlos al repositorio en cualquier momento, veamos cómo.

Dejemos la ventana del SourceTree como está (luego volveremos a ella) y volvamos a XCode para modificar alguno de los ficheros (como si estuviésemos trabajando en algo serio). Una vez modificado, vamos a Archivo -> Source Control -> Commit (u OPCIÓN-CMD-C) para acceder a la pantalla para enviar un commit:

Commit desde XCode

Como podemos ver, en la parte de arriba a la izquierda tenemos los ficheros que no están incluidos inicialmente en el repositorio, y que son los mismos que hemos visto con SourceTree. Si los marcáis junto a los otros tres ficheros que he modificado, los añadiríamos al repositorio.

La pregunta es…

¿Deben estar los “Workspace Settings” y “User Data” en el repositorio?

“Workspace Settings” contiene información relacionada con los proyectos, así que a no ser que sea algo que estrictamente sólo vamos a usar nosotros, conviene incluirlo en el repositorio.

Sin embargo, la carpeta “User Data” que contiene la configuración propia de nuestro usuario, sí conviene ignorarla ya que si no lo hacemos y trabajamos con otras personas, vamos a encontrarnos constantemente con conflictos difíciles de resolver sobre el IDE, no sobre el proyecto en sí.

Para ignorar estos ficheros, abrimos un editor de textos cualquiera y dentro de la raíz del proyecto creamos un fichero de texto plano al que llamaremos “.gitignore” (no os olvidéis del “punto” delante del nombre del fichero) y añadimos las siguientes líneas:

.DS_Store
UserInterface.xcuserstate
xcuserdata

  • Las dos primeras reglas son el mismo contenido que teníamos en .git/info/exclude. Las ponemos aquí para asegurarnos de que todo el mundo que se descargue el repositorio ignora estos ficheros
  • La tercera línea es la que ignora las preferencias de usuario

Una vez creado el fichero, volvemos a la pantalla de commit del XCode y veremos lo siguiente:

Ignorando User Data

¡Ya no podemos enviar la carpeta “User Data” por error!. Marcamos la carpeta “Workspace Settings” junto al resto de ficheros y hacemos el commit.

¿Ya está?

No, todavía no. Cuando he creado el fichero .gitignore, no lo he creado usando XCode así que si habéis hecho los commits desde XCode como yo, el fichero .gitignore no está incluido en el repositorio. ¿No me crees? Vuelve a la ventana del SourceTree que hemos dejado olvidada hace unos minutos y verás:

Añadiendo .gitignore al repositorio

Efectivamente, no está incluido. En otro post os contaré porqué necesitamos incluirlo; para no desviarnos del tema de esta entrada, vamos a incluirlo arrastrándolo al área “Files staged in the index” y haciendo clic sobre “Commit”.

(Nota: si preferís añadir el fichero por línea de comandos os resumo los pasos. Abrís una terminal, vais a la carpeta raíz del proyecto de XCode, ejecutáis “git add .gitignore” y luego ejecutáis “git commit -m’Añadiendo .gitignore’ “)

Ahora sí, ya tenemos la versión más sencilla del fichero .gitignore.

¿La versión más sencilla? ¿…es que faltan más cosas?

Sí, en función del proyecto en el que estéis trabajando podéis necesitar no incluir otros ficheros como .nib, clases obsoletas, etc. La comunidad ha generado ya un fichero de reglas estándar que podéis consultar en Stack Overflow, y que copio un poco más abajo para que las tengáis a mano.

¿Usáis vosotros alguna regla que no esté en este fichero? ¿Cuáles son las reglas que utilizáis normalmente? Compartid vuestro .gitignore como un gist en github y poned aquí el enlace. ¡Compartir es vivir!

#########################
# .gitignore file for Xcode4 / OS X Source projects
#
# NB: if you are storing "built" products, this WILL NOT WORK,
#   and you should use a different .gitignore (or none at all)
# This file is for SOURCE projects, where there are many extra
#   files that we want to exclude
#
# For updates, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects
#########################

#####
# OS X temporary files that should never be committed

.DS_Store
*.swp
*.lock
profile


####
# Xcode temporary files that should never be committed
# 
# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...

*~.nib


####
# Xcode build files -
#
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"

DerivedData/

# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"

build/


#####
# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
#
# This is complicated:
#
# SOMETIMES you need to put this file in version control.
# Apple designed it poorly - if you use "custom executables", they are
#  saved in this file.
# 99% of projects do NOT use those, so they do NOT want to version control this file.
#  ..but if you're in the 1%, comment out the line "*.pbxuser"

*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
#    NB: also, whitelist the default ones, some projects need to use these
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3


####
# Xcode 4 - semi-personal settings, often included in workspaces
#
# You can safely ignore the xcuserdata files - but do NOT ignore the files next to them
#

xcuserdata


####
# XCode 4 workspaces - more detailed
#
# Workspaces are important! They are a core feature of Xcode - don't exclude them :)
#
# Workspace layout is quite spammy. For reference:
#
# (root)/
#   (project-name).xcodeproj/
#     project.pbxproj
#     project.xcworkspace/
#       contents.xcworkspacedata
#       xcuserdata/
#         (your name)/xcuserdatad/
#     xcuserdata/
#       (your name)/xcuserdatad/
#
#
#
# Xcode 4 workspaces - SHARED
#
# This is UNDOCUMENTED (google: "developer.apple.com xcshareddata" - 0 results
# But if you're going to kill personal workspaces, at least keep the shared ones...
#
#
!xcshareddata


####
# Xcode 4 - Deprecated classes
#
# Allegedly, if you manually "deprecate" your classes, they get moved here.
#
# We're using source-control, so this is a "feature" that we do not want!

*.moved-aside


####
# UNKNOWN: recommended by others, but I can't discover what these files are
#
# ...none. Everything is now explained.
.

¡Happy gitting!