由于项目需要为一个APP生成不同环境下的版本,例如Debug版本、Release版本、Test版本,于是研究了一下Build Configuration
。
本文是对本人学习iOS multi-environment
configuration这篇文章的简单记录总结,原文内容可查看
http://appfoundry.be/blog/2014/07/04/Xcode-Env-Configuration/
接下来进入正文哈~~
以下这个小例子将展示如何在你的Xcode项目中进行多环境配置。
- 目标
在开发应用程序时,你可能需要在不同情况下做不同的事情。例如通过不同的URL连接到AdHoc分布与AppStore中发布。Xcode提供了一个非常容易使用的机制:Configurations
最终的目标是:
每个环境有一个单独的配置文件。如果我们每个环境中有一个或多个文件,例如我们可以改变URL从测试服务器到正式服务器。
每个环境中有不同的bundleID、bundleName和app图标。这样做可以确保您可以直接识别安装在设备上的不同版本。也许更重要的是,它能够使我们在设备上有多个不同的版本,因为在每个环境中都有自己的bundleID
有一个预处理宏以便能够根据不同的环境动态切换。当你需要切换环境的时候这可能是便利的。例如登录的开发版本,但是避免在AdHoc和AppStore中发布这些日志。
- 在Xcode中添加配置
你可能知道也可能不知道,当你创建了一个新的项目时,Xcode已经提供了两种配置:Debug
和Release
这种配置的好处是,你可以基于这些配置构建自己的配置,你还可以自定义脚本和自定义设置。通过这些技术我们可以提高我们的项目设置。我们在GitHub上的项目就是这种设置的结果。GitHub例子(https://github.com/appfoundry/ios-multi-env-configuration) ,接下来我们将引导您如何让这一切发生。
我们增加了一个额外的配置叫AdHoc
。
要添加这个配置,你需要选择你的Xcode项目,如下所示
然后点击+
,选择Duplication "Release" Configuration
,添加一个新的配置
接下来,你需要告诉Xcode如何来使用它。
- 设置配置构建方案
我们将创建一个新的方案能够发布在AdHoc中,要做到这一点,选择项目的Manage Schemes
选择当前的应用程序,点击左下角的小齿轮,然后点击Duplicate
,该应用程序构建方案具有相同的名称并且作为项目默认设置
在新的对话框中,更改方案的名称,例如你的App名称+AdHoc
,然后选择Archive
选项并且设置Configuration为AdHoc,完成之后点击close按钮
如果你正与其他人一同在此项目中,他们将不会看到你的新方案,因为你没有分享它。如果你选择你的方案,并且点击share复选框,然后提交到你的源代码管理系统,其他人将能够使用这些方案了。
- 为每个环境设置不同的配置文件
具体目录如下
请确保您是以下目录结构
source root folder
跟.xcodeproj
位于同一目录下。这些Configuration文件夹命名必须与你的项目配置名称匹配,显然这些是区分大小写的。
- 为了确保我们为每个环境使用了正确的配置,让我们从应用程序中移除刚刚添加的文件。有以下几种不同的方法:
1、你可以在文件目录选择文件,并在Target Membership
中取消勾选
2、你可以选择项目根目录,然后选择
Build Phases
,在
Copy Bundle Resources
中移除
3、你可以直接从目标中通过勾选复选框添加或移除文件
最后一步是当应用程序被编译的时候拷贝到应用程序中。要做到这一点,进入项目根目录,选择NewRun Script Phase,并命名为CopyConfiguration File(s)
RESOURCE_PATH=${SRCROOT}/${PRODUCT_NAME}/config/${CONFIGURATION}BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app echo "Copying all
files under ${RESOURCE_PATH} to ${BUILD_APP_DIR}"cp -v "${RESOURCE_PATH}/"* "${BUILD_APP_DIR}/"
将以上内容拷贝到script中,如下所示
该脚本将根据你的具体配置文件夹中的所有文件复制到构建应用程序包文件夹中。重要是保持CopyBundle Resources和添加文件的顺序。
继续构建你的项目,然后检查输出,应该能看到echo 消息和列表文件被打印出来
- 使用配置的值
例如,在应用程序中获取配置文件的路径
- (NSString*) readValueFromConfigurationFile {
NSBundle*bundle = [NSBundlemainBundle];
NSString *path =[bundle pathForResource:@"Configuration"ofType:@"plist"];
NSDictionary*config = [NSDictionarydictionaryWithContentsOfFile:path];
return config[@"configParameter"];
}
注:以上的代码片段是从示例代码中提供的,具体可查看DRYShowConfigurationViewController
请记住,你也可以从你的应用程序info.plist
文件中查看,尤其是界面化的显示。
NSDictionary *infoDictionary= [[NSBundle mainBundle]infoDictionary];
NSString *bundleId =infoDictionary[@"CFBundleIdentifier"];
NSString *bundleVersion =infoDictionary[@"CFBundleVersion"];
- 发布/构建不同的版本
虽然将每个环境的配置分离开是很好的,但真正有帮助的是同一时间发布多个版本。例如,它可以方便的让你的设备分别安装从AppStore下载的、AdHoc发布的和最近的开发版本。尤其是当有bug出现的时候,这是非常可喜的设置。
由于每个配置环境具有相同的AppID,新安装的应用将会覆盖当前安装的应用程序,我们需要为每个环境定义不同的AppID,这可以通过User-Defined
来设置。
具体操作如下:
选中targets
重命名CustomAppBundleld
为不同的环境设置如下
//AdHoc
com.yourcompany.${PRODUCT_NAME:rfc1034identifier}.${CONFIGURATION}
//Debug
com.yourcompany.${PRODUCT_NAME:rfc1034identifier}.${CONFIGURATION}
//Release
com.yourcompany.${PRODUCT_NAME:rfc1034identifier}
本项目的配置如下
Xcode中解决了使用变量的正确方式并展示了具体的使用值,我们为不同的配置添加了后缀为Debug和AdHoc,而Release则不使用Release后缀。
我们仍然需要为应用程序设置bundleId,将Bundle identifier
的值改为${CustomAppBundleId}
,设置如下
有了这个设置,你现在就可以在你的设备上安装多个版本。由于所有的版本仍具有相同的名称和图标,很难区分不同的版本。让我们继续寻求更完美的为不同的应用程序更改名称和图标。
- 为每个环境设置正式的名称
仍然通过User-Defined
进行设置,给新添加的usedefined命名为CustomProductName
//AdHoc
ConApp AH
//Debug
ConApp DE
//Release
${PRODUCT_NAME}
正如你看到的,我们为Release命名为应用程序的名称,其他两项使用自定义值。接下来修改Bundle name
和Bundle display name
的值为${CustomProductName}
- 为每个环境设置不同的图标
为了让每一个环境都有自己的图标,我们将使用的是默认情况下为每个项目创建的目录。Xcode默认会在应用程序下创建Images.xcassets
文件目录,里边包含了AppIcon
和LaunchImage
集。
注意:在Xcode5之前是没有此目录的,你可以通过info.plist
文件中改变Icon files
值。
我们将需要两个额外的App Icon。点击Editor->New App Icon
,分别重命名为AppStoreIcon-Debug
和AppIcon-AdHoc
,并将默认的AppIcon更改为AppIcon-Release
,为每个图标集拖拽合适的图标,如下所示
现在我们已经把所有的图标准备完毕,我们需要告诉Xcode来如何显示它们。具体操作如下:
命名规范如下
AppIcon-${CONFIGURATION}
至此,你的应用程序为不同的环境已经配置完毕,现在你要做的就是测试它们。运行在Xcode上,看看Debug配置。切换到AdHoc下看看,最后在切换到发布版本看看,如果均能正常工作,那么我们的配置即是成功的。
部署完应用程序,你也可以通过以下检查是否正常,如果正常,那么每个环境中BundleName 、Bundle Display Name、BundleID、AppIcon均显示正常
- 奖励:功能开关与宏
为了使代码根据当前环境的某些部分,可以使用预处理宏。或许你现在可能已经猜到了,你可以在Build
Settings中设置这些宏。
具体设置如下:
CONFIGURATION_${CONFIGURATION}
这样做后,你可以使用宏在你代码中监测某种环境,使用如下:
#if defined (CONFIGURATION_AdHoc) || defined (CONFIGURATION_Debug)
//Code placed here
will only be compiled and thus
//included at runtime in AdHoc and Debug releases.
#endif
备注:
本文主要是我本人记录使用的,由于英语水平及其有限,翻译内容有什么错误还请大家及时指出,将不胜感激~~