如何在XCode中配置独立的运行时设置集

时间:2012-05-08 11:17:09

标签: iphone ios xcode configuration runtime

我的iPhone应用程序连接到三个不同的服务器,例如:生产暂存测试。应用程序使用了一堆配置值,具体取决于它连接到哪个服务器,例如: Facebook App ID,TestFlight团队密钥等

我想在GIT中拥有所有设置,并且只选择应用程序在编译或发布时应该使用的配置。例如,选择测试时,产品 - >在XCode中运行运行连接到测试的应用的调试版本,以及产品 - >存档创建IPA文件,其版本也连接到测试

我不想创建比调试和发布更多的构建配置(因为这意味着构建配置/运行时配置的6种不同组合)。我认为理想的解决方案是,我有三个方案:生产测试暂存,每个方案选择一个三个与应用程序一起使用的Info.plist文件。这将允许我不仅定义不同的运行时设置,还根据后端服务器定义不同的应用程序版本或包标识符。但是,除了选择不同的构建配置之外,我看起来不能以任何其他方式配置存档操作。任何想法,如果可以以任何方式实现?

编辑为了使其更清晰,生产/登台/测试是后端服务器,而不是iOS应用程序的版本。 iOS应用程序有两个版本:调试/发布。换句话说,我可能想要运行连接到生产服务器的应用程序的 debug 版本,例如调试由该服务器返回的JSON导致的崩溃。为了清楚起见,我本可以将服务器命名为A,B和C.

4 个答案:

答案 0 :(得分:112)

执行此操作的好方法是使用构建配置和C宏。这样就不必为每个配置创建一个单独的目标,而这个目标实际上并没有正确使用目标。

首先,您要在项目级别设置配置:

enter image description here

您可以为调试,企业分发以及任何其他类型的特殊构建创建不同的配置。

接下来,您可以为将传递给编译器的每个配置定义一些宏标志。然后,您可以在编译时检查这些标志。在目标级别找到“预处理程序标志”构建设置:

enter image description here

如果展开三角形,则可以为每个配置定义不同的值。您可以在此处定义KEY=VALUE或仅KEY个宏。

enter image description here

在您的代码中,您可以检查这些宏的存在性或它们的值(如果有的话)。例如:

#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

您也可以传入字符串值,这些值必须在构建设置中用单引号括起来,例如DEFAULT_LOCALIZATION_NAME='@"en"'

您还可以使用Schemes编辑器配置在调试和存档时间内使用的配置。如果在Schemes编辑器中选择“Run”或“Archive”,则可以选择适当的配置。

enter image description here

如果需要参数化Info.plist文件中的条目,可以使用自定义构建设置定义其值。为目标添加自定义构建设置:

enter image description here

然后为您的不同配置提供适当的值:

enter image description here

然后在Info.plist文件中,您可以引用此设置:

enter image description here

请注意,此方法的一个限制是您无法更改以下项目:

  • Settings.bundle

此外,在没有资产目录支持的旧版Xcode中,您无法更改以下项目:

  • 的icon.png
  • 为Default.png

这些不能在Info.plist文件中或其他任何地方明确定义,这意味着您需要不同的目标来更改它们。

希望这有帮助。

答案 1 :(得分:10)

我建议为每个环境使用不同的构建目标。我以前成功使用过这个模型。在项目的设置中,您可以复制当前目标并根据需要更改构建设置。有Info.plist File属性可让您更改该目标的默认plist。

之后,您可以为将使用相应目标的每个环境创建一个方案。

您可以更进一步,为每个目标和不同的名称使用不同的包ID。这将允许您在同一设备上安装分段和生产版本。

唯一的缺点是,当您想要更新配置文件时,您还有更多工作要做。

答案 2 :(得分:2)

如果相关的lib允许在代码中设置密钥,这意味着您可以在plist文件中拥有生产价值,但在AppDelegate中更改它们(或者在它们首次使用的文件中) )。

目前与facebook,twitter和google sdk合作。

例如:

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

同样在Swift中,只需使用#if而不是#ifdef。

关于Facebook的说明这适用于其SDK的第3版,我不确定它是否适用于更高版本。

答案 3 :(得分:0)

技术可能非常低但我只有一个名为apiURL()的方法,它返回我想要的API的URL。我有本地主机,舞台和制作,我只是取消注释我想要的那个。到目前为止,它对我来说效果很好。我只是忘了把它换回几次。糟糕。