当前位置: 首页 > 科技观察

如何使用Xcode的Targets来管理开发和生产构建

时间:2023-03-14 13:08:26 科技观察

这篇文章是由EugeneTrapeznikov贡献的。想象一下,您已经完成了应用程序的开发和测试,现在准备好将其提交生产。问题是,一些web服务url指向测试服务器,同时为测试环境配置了API密钥。在将您的应用程序提交给Apple审核之前,您需要为生产版本修改所有这些API密钥和URL。听起来不错,对吧?但是,有没有比在开发和生产之间来回切换更好的方法来处理开发和生产构建呢?这正是Eugene接下来要与您讨论的内容。进入Eugene的教程对于初学者,有些人可能想知道为什么在App开发过程中需要使用两个独立的数据库和环境。原因是当您继续构建新功能或继续开发您的应用程序时,您希望将现有的公共版本与生产版本分开。标准的软件开发实践是在不同的开发环境下开发不同版本的软件,比如我们案例中提到的iphone应用的开发。应用程序的开发版本通常使用与生产环境不同的数据库(或其他系统,如分析)。这就是为什么我们应该为不同的环境使用单独的服务器和数据库。开发人员经常在测试期间使用虚拟图像或虚拟数据。在测试环境中,使用“testcomment”、“argharghargh”和“onemoretestcomment”等测试数据并不少见。显然,您不希望您的真实用户看到这样的消息。如果您的应用程序使用分析系统,您甚至可能在测试阶段发送数千个事件。同样,您也不要将测试数据与生产数据放在同一个数据库中。这就是为什么总是建议将开发和生产环境分开。当使用两个独立的环境时,您的应用程序需要有一种方法来找出它应该连接到哪个环境。一种常见的方法是在您的主应用程序代理中定义一个全局变量,它将在开发或生产模式下初始化您的应用程序。enumenvironmentType{casedevelopment,production}letenvironment:environmentType=.productionswitchenvironment{case.development://setwebserviceURLtodevelopment//setAPIkeystodevelopmentprint("It'sfordevelopment")case.production://setwebURLtoproduction//setAPIkeystoproductionprint("It'sfordevelopment")}生产方法每次切换环境时都需要更改全局变量。虽然这种方法可能快速方便,但它有一些重要的局限性。首先,因为我们在开发和生产环境中都使用一个BundleID,所以您不能在一台设备上安装一个应用程序的两个版本。当您需要测试应用程序的开发版本同时仍在该设备上使用该应用程序的生产版本时,这会变得很不方便。此外,这种方法有可能将应用程序的开发版本上传到应用程序商店。如果您忘记更改此全局变量,您将向您的用户上传错误的应用程序。我记得有一次我在将应用程序提交到应用程序商店之前忘记更改全局变量,结果用户下载了该应用程序的开发版本,这很糟糕。在这篇文章中,我将展示一种更好的方法来区分开发和生产构建。具体来说,我们将在Xcode中创建一个开发目标。此方法适用于新的和现有的大型项目,因此您可以按照本教程使用现有的应用程序。通过应用这种方法,应用程序的开发和生产版本将使用相同的基本代码,但可以有不同的图标、包ID并指向不同的数据库。发布和提交过程将非常简单。最重要的是,您的测试人员和经理可以在同一台设备上安装两个版本的应用程序,因此他们确切地知道他们正在体验哪个版本。如何创建新的Target那么如何在Xcode中创建开发目标呢?我使用示例项目“todo”来逐步引导您完成该过程。.您也可以使用自己的项目并按照以下步骤操作:1.转到项目导航面板中的项目设置。在“目标”区域下,右键单击现有目标并选择“复制”以复制现有目标。2.Xcode会询问你新的target是否是为iPad开发的。对于本教程,我们将只选择“仅复制”。提示:如果你的项目支持通用设备,Xcode不会提示以上信息。3.现在我们有了一个新的目标和构建方案,称为“todocopy”。重命名并更易于理解。在“目标”列表中选择新目标。按Enter键编辑文本并添加更合适的名称。我更倾向于“todoDev”。您可以自由选择您喜欢的任何名称。接下来,找到“ManageSchemes...”,选择你在第1步中创建的shceme,然后回车,让scheme的名字和新目标的名字一样(这个就是你选择的名字)新目标)4.步骤4是可选的,但强烈推荐。如果你想轻松区分开发版本和生产版本,你应该为每个使用单独的图标和启动页面。这将使测试人员更清楚地知道正在使用哪个应用程序,从而防止上传开发版本。跳转到`Assets.xcassets`添加一个新图标。右键单击该图标>应用程序图标和启动图像>新的iOS应用程序图标。将新图标重命名为“AppIcon-Dev”并添加您自己的图像。5.现在回到项目设置,选择您的开发目标,并更改BundleIdentifier。您可以简单地将“Dev”附加到原始ID。如果您执行了第4步,请确保将应用程序图标更改为您在上一步中创建的图标。6.Xcode会自动为你的target添加一个plist文件(比如todocopy-Info.plist)。您可以在项目的根文件夹中找到它。将其从“copy”重命名为“Dev”并将其放在原始plist文件下。在这里您将更轻松地管理文件。7.现在打开开发目标的“BuildSettings”,滚动到“Packaging”,并将值更改为开发plist文件(todoDev.plist)。8.最后,我们将为生产和开发目标配置预处理宏/编译器标志。然后我们可以在我们的代码中使用这个标志来检测应用程序正在运行的版本。对于Objective-C项目,请转到“构建设置”下的“AppleLLVM7.0-预处理”。扩展“预处理器宏”以在“调试”和“发布”区域中添加一个变量。对于开发目标(即todoDev),将值设置为“DEVELOPMENT=1”。另外,将值设置为“DEVELOPMENT=0”以指示产品发布。对于swift项目,编译器不再支持预处理指令。相反,它使用编译时属性和构建配置。选择开发目标,并添加一个标志来表示开发版本。找到“BuildSetting”并向下滚动到“SwiftCompiler-CustomFlags”部分。将值设置为“-DDEVELOPMENT”表示目标是开发版本。现在您已经创建并配置了您的开发目标,下一步是什么?使用Target和宏根据配置的宏DEV_VERSION,我们可以在代码中使用它来动态编译工程。这是一个简单的例子:/api/"#defineAPI_TOKEN@"71a629j0f090232"#endif在Objective-C中,您可以使用`#if`来检查`DEVELOPMENT`环境并相应地设置URLs/API密钥。斯威夫特:#ifDEVELOPMENTletSERVER_URL="http://dev.server.com/api/"letAPI_TOKEN="DI2023409jf90ew"#elseletSERVER_URL="http://prod.server.com/api/"letAPI_TOKEN="71a629j0f090232"#endifSwift你可以仍然使用#if来确定build的参数来动态编译。不过,除了使用`#define`来定义基本常量,在swift中我们还可以使用`let`来定义全局常量。提示:通常,您会将上述代码放在应用委托中。但最终取决于您在哪里初始化应用程序设置。现在,当您使用“todoDev”方案运行项目时,您创建了一个开发构建,自动将服务器的配置设置为开发环境。现在,您可以将开发版本上传到TestFlight或HockeyApp,供测试人员和管理人员进行测试。然后如果你需要创建一个生产版本,你可以简单地选择“todo”方案。无需更改代码。管理多个目标的一些注意事项1.当您向项目添加新文件时,不要忘记选择两个目标以使您的代码在两个版本之间保持同步。2.如果您使用CocoaPods,请不要忘记将新目标添加到您的podfile。您可以使用link_with指定多个目标。您可以查阅CocoaPods文档以获取更多详细信息。您的podfile如下所示:source'https://github.com/CocoaPods/Specs.git'platform:ios,'7.0'workspace'todo'link_with'todo','todoDev'pod'Mixpanel'pod'AFNetworking'3.如果你使用持续集成系统,比如TravisCI或Jenkins,不要忘记配置两个目标的构建和交付。您对本教程有何看法?如何管理您的开发和生产版本?给我留言分享你的想法。