1. Code
  2. Mobile Development
  3. iOS Development

Consejo rápido de iOS: administra configuraciones con facilidad

Scroll to top
7 min read

Spanish (Español) translation by Juliana Carvajal (you can also view the original English article)

¿Alguna vez has sentido la necesidad de poder cambiar rápida y fácilmente entre configuraciones sin meterte con los indicadores del compilador o modificar manualmente las variables en tu proyecto? En este consejo rápido, me gustaría mostrarte una solución inteligente a este problema aprovechando los esquemas de Xcode y las configuraciones de proyectos personalizadas.


El problema

Para algunos proyectos de iOS, necesitas la capacidad de cambiar rápidamente entre diferentes configuraciones o entornos. Un escenario común es cuando una aplicación de iOS se comunica con una API o un servicio web. Durante el desarrollo, debes trabajar en un entorno de desarrollo o de ensayo. Sin embargo, antes de lanzar una actualización, lo más probable es que desees probar tu aplicación en un entorno de ensayo o de producción. Cambiar entre configuraciones o entornos puede ser engorroso, especialmente si necesitas realizar este cambio con frecuencia.

La solución

El método más sencillo es modificar manualmente la configuración cada vez que cambias de entorno. Esto significa modificar un indicador del compilador o modificar manualmente los valores en tu proyecto. Este enfoque es propenso a errores, tedioso y está lejos de ser ideal. Una mejor solución es crear una configuración personalizada para cada entorno. Esto implica la creación de un archivo de configuración que centralice las variables de entorno y los esquemas Xcode personalizados. Déjame mostrarte cómo funciona esto creando un proyecto de muestra.


1. Configuración del proyecto

Crea un nuevo proyecto en Xcode seleccionando la plantilla Aplicación vacía de la lista de plantillas (figura 1). Asigna un nombre a tu aplicación Configurable, ingresa un identificador de empresa, configura el iPhone para la familia de dispositivos y marca Usar recuento automático de referencias. El resto de las casillas de verificación se pueden dejar sin marcar para este proyecto (figura 2). Dile a Xcode dónde deseas guardar el proyecto y haz clic en Crear.

iOS Quick Tip: Managing Configurations With Ease - Choosing a Project Template iOS Quick Tip: Managing Configurations With Ease - Choosing a Project Template iOS Quick Tip: Managing Configurations With Ease - Choosing a Project Template
Figura 1: Elección de una plantilla de proyecto
iOS Quick Tip: Managing Configurations With Ease - Configuring the Project iOS Quick Tip: Managing Configurations With Ease - Configuring the Project iOS Quick Tip: Managing Configurations With Ease - Configuring the Project
Figura 2: Configuración del proyecto

2. Edita Info.plist

Paso 1: agrega configuraciones personalizadas

La idea clave de este enfoque es saber cuál es la configuración actual. ¿Qué es una configuración y dónde se definen? Puedes ver una lista de todas las configuraciones del proyecto seleccionando tu proyecto en el Navegador de proyectos y abriendo la pestaña Información en la parte superior. Asegúrate de haber seleccionado tu proyecto en la barra lateral izquierda y no un objetivo de la lista de objetivos (figura 3).

iOS Quick Tip: Managing Configurations With Ease - Project Configurations iOS Quick Tip: Managing Configurations With Ease - Project Configurations iOS Quick Tip: Managing Configurations With Ease - Project Configurations
Figura 3: Configuraciones del proyecto

En este tutorial, asumiremos que tenemos un entorno de desarrollo, preparación y producción con el que debemos trabajar. Comienza creando una nueva configuración para cada entorno haciendo clic en el botón más debajo de la lista de configuraciones. Selecciona la opción Duplicar configuración "Depurar" para cada nueva configuración (figura 4) y asigna un nombre apropiado a la configuración (figura 5).

iOS Quick Tip: Managing Configurations With Ease - Duplicate Debug Configuration iOS Quick Tip: Managing Configurations With Ease - Duplicate Debug Configuration iOS Quick Tip: Managing Configurations With Ease - Duplicate Debug Configuration
Figura 4: Configuración de depuración duplicada
iOS Quick Tip: Managing Configurations With Ease - Three Custom Configurations iOS Quick Tip: Managing Configurations With Ease - Three Custom Configurations iOS Quick Tip: Managing Configurations With Ease - Three Custom Configurations
Figura 5: Tres configuraciones personalizadas

Paso 2: edita Info.plist

Cuando la aplicación se está ejecutando, necesitamos saber cuál es la configuración actual. Podemos hacer esto agregando una nueva entrada al archivo Info.plist del objetivo. Selecciona el archivo Info.plist del destino y crea un nuevo par clave-valor. Establece la clave en Configuración y el valor en ${CONFIGURACIÓN} (figura 6). El identificador de CONFIGURACIÓN identifica la configuración de compilación (por ejemplo, Desarrollo o Puesta en escena) que el objetivo usa para generar el producto.

iOS Quick Tip: Managing Configurations With Ease - Adding a New Entry to Info.plist iOS Quick Tip: Managing Configurations With Ease - Adding a New Entry to Info.plist iOS Quick Tip: Managing Configurations With Ease - Adding a New Entry to Info.plist
Figura 6: Agrega una nueva entrada a Info.plist

Paso 3: obtén la configuración actual

Con estos cambios realizados, ahora podemos recuperar la configuración actual en nuestra aplicación. Para probar esto, abre MTAppDelegate.m y actualiza la application:didFinishLaunchingWithOptions: como se muestra a continuación. Para acceder a la información en Info.plist, le pedimos al paquete de aplicaciones principal su infoDiccionario. Del diccionario de información, tomamos el valor de la clave de configuración que agregamos y lo registramos en la consola de Xcode. Crea y ejecuta tu aplicación para ver qué está registrado en la consola de Xcode.

1
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
2
    NSString *configuration = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"Configuration"];
3
4
    NSLog(@"Current Configuration > %@", configuration);
5
6
    // Initialize Window

7
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
8
9
    // Configure Window

10
    self.window.backgroundColor = [UIColor whiteColor];
11
    [self.window makeKeyAndVisible];
12
    return YES;
13
}

A pesar de que creamos tres configuraciones personalizadas, la configuración actual todavía está establecida en Debug. Reparemos eso en la siguiente sección.


2. Esquemas personalizados de Xcode

Al crear una aplicación, se utiliza un esquema de Xcode. Un esquema de Xcode define una serie de variables que se utilizarán al crear el producto. Una de esas variables es la configuración que se debe utilizar.

El esquema actual de Xcode se muestra en la parte superior izquierda de la barra de herramientas de Xcode. Para cambiar fácilmente entre las configuraciones (Desarrollo, Puesta en escena, etc.) que creamos anteriormente, recomiendo crear un esquema de Xcode para cada configuración. Haz clic en el esquema actual, selecciona Nuevo esquema en el menú que aparece y asigna el nombre Desarrollo al nuevo esquema. Con el nuevo esquema seleccionado, haz clic en el esquema y selecciona Editar esquema en el menú. Selecciona Ejecutar configurable en el panel izquierdo, abre la pestaña Información en la parte superior y establece la Configuración de compilación en Desarrollo (figura 7). Crea un esquema de Xcode para las configuraciones de puesta en escena y producción repitiendo los pasos anteriores.

iOS Quick Tip: Managing Configurations With Ease - Creating a Custom Xcode Scheme iOS Quick Tip: Managing Configurations With Ease - Creating a Custom Xcode Scheme iOS Quick Tip: Managing Configurations With Ease - Creating a Custom Xcode Scheme
Figura 7: Creación de un esquema Xcode personalizado

3. Crea un archivo de configuración

Para facilitar la gestión de los ajustes de configuración, crearemos una lista de propiedades personalizada que agrupa los distintos ajustes de configuración. Crea una nueva lista de propiedades y asígnale el nombre Configurations.plist (figura 8). La lista de propiedades es un diccionario con una entrada para cada configuración. Cada entrada en la lista de propiedades contiene otro diccionario con información específica para esa configuración (figura 9).

iOS Quick Tip: Managing Configurations With Ease - Creating a Property List for the Configuration Settings iOS Quick Tip: Managing Configurations With Ease - Creating a Property List for the Configuration Settings iOS Quick Tip: Managing Configurations With Ease - Creating a Property List for the Configuration Settings
Figura 8: Crea una nueva lista de propiedades
iOS Quick Tip: Managing Configurations With Ease - Configuration Property List iOS Quick Tip: Managing Configurations With Ease - Configuration Property List iOS Quick Tip: Managing Configurations With Ease - Configuration Property List
Figura 9: Lista de propiedades de configuración

Como puedes ver, puedes agregar las variables que desees a Configurations.plist. Solo necesitas asegurarte de que cada entrada en la lista de propiedades contenga las mismas variables (claves).


4. Clase de configuración

Ahora tienes todos los elementos necesarios para cambiar rápidamente entre configuraciones. Sin embargo, nuestro trabajo aún no ha terminado. La implementación actual no es muy amigable para el usuario (o desarrollador). Al adoptar este enfoque, siempre creo una clase de configuración que me da fácil acceso a las variables definidas en Configurations.plist. La clase de configuración obtiene la configuración actual, carga Configurations.plist y proporciona un fácil acceso a las variables. Echa un vistazo a la clase MTConfiguration a continuación para ver a qué me refiero.

1
#import <Foundation/Foundation.h>

2
3
@interface MTConfiguration : NSObject
4
5
#pragma mark -

6
+ (NSString *)configuration;
7
8
#pragma mark -

9
+ (NSString *)APIEndpoint;
10
+ (BOOL)isLoggingEnabled;
11
12
@end
1
#import "MTConfiguration.h"

2
3
#define MTConfigurationAPIEndpoint @"MTAPIEndpoint"

4
#define MTConfigurationLoggingEnabled @"MTLoggingEnabled"

5
6
@interface MTConfiguration ()
7
8
@property (copy, nonatomic) NSString *configuration;
9
@property (nonatomic, strong) NSDictionary *variables;
10
11
@end
12
13
@implementation MTConfiguration
14
15
#pragma mark -

16
#pragma mark Shared Configuration

17
+ (MTConfiguration *)sharedConfiguration {
18
    static MTConfiguration *_sharedConfiguration = nil;
19
    static dispatch_once_t onceToken;
20
    dispatch_once(&onceToken, ^{
21
        _sharedConfiguration = [[self alloc] init];
22
    });
23
24
    return _sharedConfiguration;
25
}
26
27
#pragma mark -

28
#pragma mark Private Initialization

29
- (id)init {
30
    self = [super init];
31
32
    if (self) {
33
        // Fetch Current Configuration

34
        NSBundle *mainBundle = [NSBundle mainBundle];
35
        self.configuration = [[mainBundle infoDictionary] objectForKey:@"Configuration"];
36
37
        // Load Configurations

38
        NSString *path = [mainBundle pathForResource:@"Configurations" ofType:@"plist"];
39
        NSDictionary *configurations = [NSDictionary dictionaryWithContentsOfFile:path];
40
41
        // Load Variables for Current Configuration

42
        self.variables = [configurations objectForKey:self.configuration];
43
    }
44
45
    return self;
46
}
47
48
#pragma mark -

49
+ (NSString *)configuration {
50
    return [[MTConfiguration sharedConfiguration] configuration];
51
}
52
53
#pragma mark -

54
+ (NSString *)APIEndpoint {
55
    MTConfiguration *sharedConfiguration = [MTConfiguration sharedConfiguration];
56
57
    if (sharedConfiguration.variables) {
58
        return [sharedConfiguration.variables objectForKey:MTConfigurationAPIEndpoint];
59
    }
60
61
    return nil;
62
}
63
64
+ (BOOL)isLoggingEnabled {
65
    MTConfiguration *sharedConfiguration = [MTConfiguration sharedConfiguration];
66
67
    if (sharedConfiguration.variables) {
68
        return [[sharedConfiguration.variables objectForKey:MTConfigurationLoggingEnabled] boolValue];
69
    }
70
71
    return NO;
72
}
73
74
@end

La clase MTConfiguration proporciona un fácil acceso a las variables almacenadas en Configurations.plist. Cambiar entre configuraciones ahora es tan fácil como seleccionar el esquema Xcode correcto. A pesar de que puede parecer bastante trabajo desde el principio, puedo asegurarte que te ahorrarás una enorme cantidad de tiempo y frustración en el futuro.

Para probar nuestra solución, importa el archivo de encabezado de la clase MTConfiguration en MTAppDelegate.m y actualiza el método application:didFinishLaunchingWithOptions: como se muestra a continuación.

1
#import "MTAppDelegate.h"

2
3
#import "MTConfiguration.h"
1
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
2
    NSLog(@"Configuration > %@", [MTConfiguration configuration]);
3
4
    NSLog(@"API Endpoint > %@", [MTConfiguration APIEndpoint]);
5
    NSLog(@"Is Logging Enabled > %i", [MTConfiguration isLoggingEnabled]);
6
7
    // Initialize Window

8
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
9
10
    // Configure Window

11
    self.window.backgroundColor = [UIColor whiteColor];
12
    [self.window makeKeyAndVisible];
13
    return YES;
14
}

Conclusión

Las configuraciones personalizadas y los esquemas de Xcode realmente pueden ayudar a organizar un proyecto y agilizar tu flujo de trabajo de desarrollo. Espero haberte podido convencer del valor de esta solución, especialmente para proyectos complejos con múltiples entornos.