Xcode 8中代码签名的乐趣

Apple在Xcode 8中引入了自动代码签名功能。该功能旨在解决开发人员以前在管理证书和预配应用程序时遇到的许多问题,并使签名应用程序以及在应用程序和开发人员门户中的功能同步变得更加容易。 在WWDC 2016中,有一个关于此主题的整个会议,Xcode App Signing的新增功能。 此功能有助于节省大量时间用于供应应用程序的证书管理。 但是,由于自动代码签名功能开始使用开发证书来存档应用程序,因此这破坏了大多数构建脚本。 正如在此答案中讨论的那样,有几种解决方法。 在本文中,我们将研究如何针对需要在构建脚本中使用单独的证书的情况,切换到构建脚本中的手动代码签名。

尽管具有自动代码签名的所有优点,但是它也带来了一些危害。 自动代码签名的主要问题之一是,当您的CI脚本需要覆盖CODE_SIGN_IDENTITY ei Enterprise和App Store的不同团队构建具有不同证书的应用程序时。 可能您的构建脚本如下所示:

  xcodebuild -project MyAmazingApp.xcodeproj -target MyTarget干净存档-sdk iphoneos PRODUCT_BUNDLE_IDENTIFIER = edu.myamazingcompany.myamazingapp -archivePath MyArchive.xcarchive PROVISIONING_PROFILE_SPECIFIER = {Provisioning_Profile_Uuid} CODE_SIGN_IDENTITY =”

运行会在Xcode 8中给您以下错误:

检查依赖项

{目标/方案}的配置设置冲突。 {Target / Scheme}将自动签名以进行开发,但是已经手动指定了冲突的代码签名标识iPhone Distribution。 在构建设置编辑器中将代码签名标识值设置为“ iPhone Developer”,或在项目编辑器中切换为手动签名。

SDK’iOS 10.X’中的产品类型’Application’需要代码签名

如果您不熟悉xcodebuild命令,则可以通过运行以下命令来了解它: xcodebuild -help或查看xcodebuild上的Apple文档页面。

如前所述,此问题有几种解决方法。 在这里,我们将研究如何在项目中保留“自动代码签名”功能,并在调用xcodebuild命令之前将其禁用,以便我们仍然可以手动指定代码签名证书并覆盖默认值。

首先,让我们看看Xcode如何指示是否使用自动代码签名设置了目标。 正如此处讨论的那样, ProvisioningStyle是用于标识目标是否应使用自动代码签名的属性名称,具体取决于其值Atuomatic / Manual

为了在您的项目中看到它,首先需要右键单击您的项目文件,然后选择Show Package Contents

我们感兴趣的文件名为project.pbxproj 。 该文件包含有关您的项目和目标的信息。 继续并在您喜欢的文本编辑器中打开此文件。 通过搜索Begin PBXProject section ,可以找到我们感兴趣的Begin PBXProject section

此部分保存有关目标的信息以及有关目标的一些属性。 项目中定义的所有目标均列在targets下方,并在其前面添加注释以指出哪个是哪个。 每个目标均由其UUID引用:

您可以在此链接或此链接中找到有关pbxproj结构以及文件各部分内容的更多信息。

如上所示,您可以在目标下找到目标UUID,然后在TargetAttributes下找到分配给目标的属性。 DevelopmentTeam团队ID,您的Apple团队ID和ProvisioningStyle用来保存下面的属性之一,该ID指示代码签名方式为Automatic / Manual 。 现在,您将看到上述错误来自何处:

pbxproj文件的这一部分也需要替换为Apple Team ID和供应配置文件,以从“ Automatic更改为“ Manual

原因是xcodebuild命令的主要部分更改了CODE_SIGN_IDENTITYPROVISIONING_PROFILE_SPECIFIER ,它与pbxproj设置的内容冲突,因为DevelopmentTeam中设置的团队ID没有新的代码签名证书。

要解决此问题,您需要按照Apple的建议将DevelopmentTeam更新为空字符串,并将ProvisioningStyle更改为Manual

现在,是时候将所有这些都放入脚本中以完成工作了:

  sed -i'''s / ProvisioningStyle =自动; / ProvisioningStyle =手动; /'MyProj.xcodeproj / project.pbxproj
 sed -i''“ s / DevelopmentTeam = $ {DevelopmentTeamID}; / DevelopmentTeam = \” \”; /” MyProj.xcodeproj / project.pbxproj
 sed -i''“ s / DEVELOPMENT_TEAM = $ {DevelopmentTeamID}; / DEVELOPMENT_TEAM = \” $ {TEAM_ID} \“; /” MyProj.xcodeproj / project.pbxproj 

请注意,在自动化中,还有一个脚本也可以替换DEVELOPMENT_TEAM值。 这部分也需要替换为正确的团队ID。 这可以作为xcodebuild命令的一部分或通过此脚本来完成。 如果您的项目有其他项目作为依赖项,则前者无效:

  xcodebuild -project MyAmazingApp.xcodeproj -target MyTarget干净存档-sdk iphoneos PRODUCT_BUNDLE_IDENTIFIER = edu.myamazingcompany.myamazingapp -archivePath MyArchive.xcarchive PROVISIONING_PROFILE_SPECIFIER = {Provisioning_Profile_Uuid} CODE_SIGN_IDENTITY =”

这种方法的最后一个技巧是在Xcode 8或更高版本下向项目添加新目标。 默认情况下,Xcode不会将ProvisioningStyle = Automatic;的部分放置ProvisioningStyle = Automatic; 那里:

在这种情况下,您需要为创建的每个目标手动添加它:

现在,自动完成代码签名和跨多个设备共享证书的工作,并通过自动代码签名功能在Xcode 8中提供了支持。 此外,现在,Xcode还提供了一些有关应用程序签名和配置问题的有用错误/警告。 但是,这种方法破坏了许多构建脚本,这些构建脚本依赖于交换团队ID并使用不同的证书和供应配置文件。 在这篇文章中,审查并解释了一种解决此问题的方法。