Como cambiar tu Info.plist usando Swfit

Posted by on 6 de febrero de 2018

En un proyecto que estoy trabajando en estos momentos, necesitaba sobre escribir algunas configuraciones de un plist global en los diferentes Info.plist de mis tragets. Nuestro proyecto tiene varios targets en estos momentos y hay algunas configuraciones que queremos que se mantengan igual en todos ellos, pero estar actualizando las listas de información de cada uno cuando necesitamos hacer un cambio, no es la mejor forma de hacerlo. Busqué alguna forma simple de hacer esto y no encontré buenas respuestas o no cubrían exactamente mis necesidades. Así que decidí probar distintas formas y aquí les presento las dos que encontré, una es la forma fácil pero sucia y la otra es la forma más elegante.

Forma fácil – Configuraciones definidas por el usuario

La forma más fácil de hacer esto es usando las User-Defined settings en el proyecto. Después en nuestros Info.plist lo único que tenemos que hacer es definir la configuración de la que vamos a heredar.

Después de eso, selecciona el botón de más en seguida de Levels, y escoge la opción de Add User-Defined Setting en el menú.

Verás que una nueva configuración aparece en la sección de User-Defined, donde podrás escoger el nombre que vas a utilizar en tu plist. No hay ninguna convención sobre como escribir estos nombre pero yo prefiero usar mayúsculas y guiones bajos, por ejemplo vamos a definir BUNDLE_DISPLAY_NAME.

Después, tenemos que ir a nuestro Info.plist que queremos cambiar y definir esta configuración.

Y ya, la próxima vez que corras tu proyecto se utilizará la configuración que se definió en el proyecto.

Esta solución también sirve para cuando quieres utilizar diferentes nombres, versiones o configuraciones dependiendo de tus schemes y targets.

Forma elegante – Script de Swift

Existe otra forma, una forma más elegante de hacerlo. creando un script de Swift que defina estas variables (leyendo de otra lista o hardcodéando los datos) y agregándolo como una fase de ejecución.

De hecho, esta solución se puede hacer con cualquier lenguaje de programación, pero yo quise implementarlo utilizando Swift para mejorar mi conocimiento del lenguaje fuera de iOS. Para este caso utilizaré Swift 4.

Primero necesitamos crear el archivo, prefiero mantenerlo fuera del proyecto en si, porque en realidad no modifica nada del comportamiento de nuestra app.

Si quieres saltar directamente a la solución, aquí está el gist con la solución final de este tutorial.

Lo primero que tenemos que hacer es la configuración del script.

Lo primero es importar el SDK de macOS si estamos trabajando con iOS o Apple Watch. Si tu proyecto es de macOS puedes ignorar esta linea de código. También necesitamos importar Foundation ya que utilizaremos FileManager para leer y escribir las listas.

Vamos a crear una constante llamada relativePlistFilesFolder para definir el directorio donde estarán nuestros archivos de información, recuerda que tienes que usar la ruta real de tu archivo y no la relativa del proyecto.

Por último definimos currentDirectoryPath como una constante para ahorrarnos el estar llamado el método.

Primero vamos a crear el método para leer los archivos Plist.

Vamos a recibir la ruta como un string, leer el archivo y regresar un diccionario con la información de la lista. Tenemos que utilizar Any, ya que la lista utiliza diferentes clases para definir la información. En caso de que no se encuentre el archivo, vamos a regresar un diccionario vacío.

Después, vamos a obtener la información del plist y transformarla en un diccionario. Utilizaremos la clase PropertyListSerialization para leer el archivo. Como este método puede generar un error, tenemos que poner este código dentro de un bloque do-catch (o podríamos forzar el try utilizando el signo de admiración  try! ), y regresar un archivo vacío en caso de que algo haya fallado o la información en caso de que todo haya salido bien.

Ahora vamos a definir nuestro método de escritura.

Este método es bastante simple, vamos a hacer un casting de nuestro diccionario a un  NSDictionary  para poder aprovechar el método de write de esta clase, también vamos a recibir la ruta donde vamos a escribir en forma de string y por último regresar true o false dependiendo de si tuvimos éxito al escribir el archivo o no.

Lo primero que vamos a hacer es revisar si el archivo existe, en caso de que no exista regresamos falso porque entonces algo hicimos mal al definir la ruta de nuestra lista.

Después vamos a llamar el método de escritura de NSDictionary en la ruta que definimos antes para sobre escribir el archivo. Este método hará el trabajo de convertir el diccionario en un archivo de tipo plist.

Por último, vamos a utilizar estos métodos para sobre escribir nuestro archivo.

Si quieres escribir o leer las configuraciones de Xcode (como Bundle name, Bundle version) recuerda utilizar las llaves raw, por ejemplo Bundle Version es en realidad CFBundleVersion. Para ver estas llaves tenemos que ir a nuestro archivo Info.plist en Xcode y dar click secundario para abrir el menú y seleccionar la opción.

También puedes crear tus propias llaves para utilizar después en tu código, éstas serán escritas en tu nuevo archivo.

Ya nada más tenemos que llamar nuestro método de escritura y regresar un error si algo salió mal.

El último paso es añadir este script como una fase de nuestro build para cada target.

Para hacer esto, tenemos que ir a la configuración de nuestro target, seleccionar la pestaña de Build Phases y luego dar click en el botón de más para seleccionar la opción New Run Script Phase.

Después de eso, se creará una nueva fase que debemos subir a la primera posición y después definir la ruta a nuestro archivo Swift.

Y ya, eso es todo. Haz un build de tu proyecto y veras como tu Info.plist cambiará las variables que definimos en el script.

Puedes encontrar el código completo aquí.

 

Espero que el tutorial les sea útil para sus proyectos. Si ven algún error o algo que se pudiera mejorar, por favor díganmelo en los comentarios.

¡Gracias y feliz swifteo!

Posted in: Desarrollo

Comments

Be the first to comment.

Deja un comentario

Simple Business by Nimbus Themes
Powered by WordPress