58

我的 iPhone 应用程序连接到三个不同的服务器,例如:productionstagingtesting。应用程序使用的配置值取决于它连接到的服务器,例如 Facebook 应用程序 ID、TestFlight 团队密钥等。

我想拥有 GIT 中的所有设置,并且只选择应用程序在编译或发布时应该使用的配置。For example, when testing is selected, Product -> Run in Xcode runs the debug version of the app connecting to testing , and Product -> Archive creates the IPA file with the release version that also connects to testing .

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

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

4

4 回答 4

112

一个很好的方法是使用构建配置和 C 宏。这避免了必须为每个配置创建单独的目标,这并不是真正正确使用目标。

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

在此处输入图像描述

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

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

在此处输入图像描述

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

在此处输入图像描述

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

#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"'.

您还可以使用方案编辑器配置在调试和存档期间使用的配置。如果您在方案编辑器中选择“运行”或“存档”,您可以选择适当的配置。

在此处输入图像描述

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

在此处输入图像描述

然后为您的不同配置赋予适当的值:

在此处输入图像描述

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

在此处输入图像描述

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

  • Settings.bundle

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

  • 图标.png
  • 默认.png

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

希望这可以帮助。

于 2012-05-08T12:09:29.553 回答
10

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

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

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

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

于 2012-05-08T11:28:23.550 回答
2

如果相关库允许在代码中设置键,这是一个更简单的解决方案,这意味着您可以在 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 版,我不确定是否可以使用更高版本。

于 2015-04-17T06:42:31.527 回答
0

这可能是非常低的技术,但我只有一个调用的方法apiURL(),它返回我想要的 API 的 URL。我有 localhost、stage 和 production,我只是取消注释我想要的那个。到目前为止,它对我来说效果很好。我只是忘记了几次切换回来。哎呀。

于 2018-02-27T18:34:15.300 回答