Cómo configurar sets independientes de configuraciones de time de ejecución en XCode

Mi aplicación de iPhone se conecta a tres serveres diferentes, por ejemplo: producción , puesta en escena y testing . Hay una gran cantidad de valores de configuration que la aplicación utiliza dependiendo de a qué server se conecta, por ejemplo, la ID de la aplicación de Facebook, la key del equipo de TestFlight, etc.

Me gustaría tener todas las configuraciones en GIT y solo seleccionar qué configuration se supone que la aplicación debe usar al comstackr o liberar. Por ejemplo, cuando se selecciona la testing , el Producto -> Ejecutar en XCode ejecuta la versión de debugging de la aplicación que se conecta a la testing y Product -> Archive crea el file IPA con la versión de lanzamiento que también se conecta a la testing .

No quiero crear más configuraciones de compilation que depurar y liberar (porque eso significaría 6 combinaciones diferentes de configuraciones de compilation / configuraciones de time de ejecución). La solución ideal, como lo veo, sería que tengo tres esquemas: producción , testing y puesta en escena , y cada esquema selecciona uno de los tres files Info.plist para usar con la aplicación. Eso me permitiría no solo definir diferentes configuraciones de time de ejecución, sino también diferentes versiones de las aplicaciones o identificadores de packages según el server de background. Pero no parece que pueda configurar la acción de file de ninguna otra manera, aparte de seleccionar una configuration de compilation diferente. ¿Alguna idea si pudiera lograrse de alguna manera?

Edición: para que sea un poco más claro, la producción / puesta en escena / testing es el server de background, no la versión de la aplicación iOS. La aplicación para iOS viene en dos versiones: debug / release . En otras palabras, es posible que desee ejecutar una versión de debugging de la aplicación que se conecta al server de producción, por ejemplo, para depurar un locking causado por JSON devuelto desde ese server. Pude haber nombrado a los serveres como A, B y C por razones de claridad.

Sugiero utilizar diferentes objectives de compilation para cada entorno. Utilicé este model con éxito antes. En la configuration de su proyecto, puede duplicar el objective actual y cambiar la configuration de compilation según sea necesario. Hay una propiedad de Info.plist File que le permitirá cambiar el plist pnetworkingeterminado para ese objective.

Después de eso, puede crear un esquema para cada entorno que utilizará el destino correspondiente.

Puede dar un paso más y usar diferentes ID de package para cada objective y diferentes nombres. Eso le permitirá instalar, por ejemplo, la puesta en escena y las comstackciones de producción en el mismo dispositivo.

El único inconveniente en esto es que tiene más trabajo cuando desea actualizar los perfiles de aprovisionamiento.

Una buena manera de hacerlo sería con las configuraciones de compilation y las macros C. Esto evita tener que crear un objective por separado para cada configuration que no sea realmente el uso correcto de los objectives.

Primero desea configurar las configuraciones en el nivel del proyecto:

introduzca la descripción de la imagen aquí

Puede crear diferentes configuraciones para debugging, distribución empresarial y cualquier otro tipo de compilation especial que desee.

A continuación, puede definir algunas macro banderas para cada configuration que se pasarán al comstackdor. A continuación, puede verificar estas banderas en time de compilation. Busque la configuration de compilation "Indicadores de preprocesador" en el nivel de destino:

introduzca la descripción de la imagen aquí

Si expande el triángulo, puede definir diferentes valores para cada una de sus configuraciones. Puede definir KEY=VALUE o simplemente macros KEY aquí.

introduzca la descripción de la imagen aquí

En su código, puede verificar la existencia de estas macros, o su valor (si lo hay). Por ejemplo:

 #ifdef DISABLE_FEATURE_X featureXButton.hidden = YES; #endif // ... #if FOOBAR_VISIBLE == 0 foobarView.hidden = YES; #elif FOOBAR_VISIBLE == 1 foorbarView.hidden = NO; #else #error Invalid value for FOOBAR_VISIBLE #endif 

También puede pasar valores de cadena, que deben envolverse con comillas simples en la configuration de compilation, por ejemplo, DEFAULT_LOCALIZATION_NAME='@"en"' .

También puede configurar qué configuration se utiliza durante la debugging y el time de file utilizando el editor de esquemas. Si elige "Ejecutar" o "Archivar" en el editor de Esquemas, puede seleccionar la configuration adecuada.

introduzca la descripción de la imagen aquí

Si necesita parametrizar inputs en el file Info.plist, puede definir su valor utilizando una configuration de compilation personalizada. Agregue una configuration de compilation personalizada para su objective:

introduzca la descripción de la imagen aquí

Y luego dale un valor apropiado para tus diferentes configuraciones:

introduzca la descripción de la imagen aquí

Luego, en el file Info.plist puedes hacer reference a esta configuration:

introduzca la descripción de la imagen aquí

Tenga en count que la única limitación de este enfoque es que no puede cambiar los siguientes elementos:

  • Settings.bundle

Además, en versiones anteriores de Xcode sin soporte de catálogo de activos, no puede cambiar los siguientes elementos:

  • Icon.png
  • Default.png

Estos no pueden definirse explícitamente en el file Info.plist ni en ningún otro lugar, lo que significa que necesita diferentes objectives para cambiarlos.

Espero que esto ayude.

Aquí hay una solución mucho más fácil si las libs implicadas permiten configurar las keys en código, lo que significa que puede tener valor de producción en su file Plist, pero cambie en su AppDelegate (o en el file en el que se usen por primera vez).

Funciona con Facebook, Twitter y Google SDK en este momento.

Ex:

 #ifdef DEBUG // Facebook [FBSettings setDefaultAppID:@"SandboxID"]; // Fabric / TwitterKit - must be called above [Fabric with:@[TwitterKit]]; [[Twitter shanetworkingInstance] startWithConsumerKey:@"SandboxKey" consumerSecret:@"SandboxIDSecret"]; #endif 

Lo mismo en Swift, simplemente use #if en lugar de #ifdef.

Nota sobre Facebook Esto funcionó con la versión 3 de su SDK, no estoy seguro de que sea posible con las versiones posteriores.