创buildiOS / OSX框架:在分发给其他开发者之前,是否需要对它们进行编码?

我正在学习如何创buildiOS和OSX框架。 以iOS为例,到目前为止,以下步骤对我有用:

  1. xcodebuild框架使用-sdk iphonesimulator和Build操作
  2. xcodebuild框架使用-sdk iphoneos和Build操作
  3. 使用lipo工具来创build通用二进制文件,以使lipo -info产生预期的结果:

胖文件中的体系结构:Foo.framework / Foo是:i386 x86_64 armv7 arm64

问题是:

  1. 我读到我的框架可以由开发人员使用它重新签名:“代码签名复制”,但我不明白什么是先决条件,即我应该添加配合步骤与我的签名身份协调一致的通用二进制文件分发给其他开发者?

  2. 如果以前是积极的 – 我应该使用我的“iPhone分布:…”身份或“iPhone开发人员:…”就足够了(这样我的框架是一些iOS项目的一部分,通过各种validation,尤其是App Storevalidation)?

我的答案的背景是“CodeSign错误:代码签名是在SDK'iOS 8.3'”中的产品types'框架'中需要的,这是我在许多第三方框架和Carthage#235或“代码对象未签名(一个例子:我在Realm#1998上报告的问题。

所以我想确保我的框架的用户在使用它们时不会遇到任何代码签名问题。

PS这个问题在应用于一个开发人员而不是一个框架供应商的组织时会变得更加有趣。

我打开赏金:“寻找来自可信和/或官方来源的答案。” 但从那以后还没有收到。

虽然@jackslash提供的答案是正确的,但它只讲述了一部分故事,所以我想以我想问这个问题的时候想看到的方式写自己的方法。

这个答案的实际情况是:2015年7月。事情很可能会改变。

首先,让我们断言框架的正确代码签名所需的操作应该被分成框架的开发者必须采取的 步骤以及框架的消费者必须采取的步骤。

TLDR;

对于OSX框架: 开发人员可以自由地分发OSX框架而不需要对其进行编码,因为消费者将重新对其进行重新编码。

对于iOS框架: 开发人员可以自由地分发iOS框架,而不需要对其进行编码,因为消费者将重新对其进行重新编码,但是Xcode强制开发人员在为iOS设备构build时为其框架进行编码。

由于雷达: “包含模拟器切片的iOS框架不能提交到App Store” iOS框架的消费者被迫运行特殊的脚本,如“copy_frameworks”或“strip_frameworks”,它使用lipo -remove从iOS中剥离模拟器切片框架和重新编码剥离的框架,因为在这一点上,无论它是否是(或不是),它的编码标识都被删除,作为去除lipo -remove操作的副作用。

较长的答案如下。


这个答案不是一个“从可信和/或官方来源”,而是基于一些经验观察。

经验观察#1:消费者不关心,因为他们将重新协调从开发商收到的框架

Github 众所周知的开源项目的二进制框架分布没有经过密码devise 。 命令codesign -d -vvvv给出了在我用来探索的所有二进制iOS和OSX框架中的“代码对象根本没有签名”。 一些例子: ReactiveCocoa和Mantle , Realm , PromiseKit 。

从这个观察中可以明显看出,这些框架的作者希望他们代表消费者代表他们,即消费者必须在Xcode提供的“embedded框架”构build阶段使用“代码签名复制”标志,或者使用一些自定义shell脚本,手动做同样的事情:代表消费者代码框架。

我没有find任何相反的例子:开放源代码框架,将在其中分配身份代码,所以在其余的答案我假设这种广泛采用的方法是正确的: 没有必要框架开发人员将其框架分发给其他开发人员,并在其中设置密码标识,因为消费者会重新对其进行重新编码

经验观察#2仅适用于iOS,完全是开发人员的关注

虽然消费者并不关心他们从Developer收到的框架是否被签名,但是当开发者为iOS设备构build它时 ,开发者仍然需要将他们的iOS框架 CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1' 为其构build过程的一部分,否则Xcode不会构build: CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1' 。 引用Justin Spahr-Summers :

OS X框架不需要在构build时进行代码签名。不幸的是,Xcode确实需要在构build时对iOS框架进行编码。

这很好的回答了我的问题#2:“iPhone Developer”的身份足以哄骗Xcode,以便为设备构buildiOS框架。 对迦太基#339的评论也是一样的。

经验观察#3:lipo工具

lipo工具的具体行为: 当应用到框架二进制文件时,它总是recursion地从它移除任何的编码标识lipo -create/-remove codesigned framework ... -> not codesigned framework

这可能是为什么观察#1中的所有例子完全没有被标记的答案:它们的代码标识在应用脂肪之后被吹走,但是从根据观察#1消费者不关心它是好的。

这一观察结果与关于AppStore的下一个观察#4特别相关。

经验观察#4:包含模拟器切片的iOS框架不能提交给App Store

这是广泛讨论: 领域#1163和迦太基#188和雷达打开: rdar:// 19209161 。

这完全是消费者关心的问题:对于消费者在其应用程序中包含的iOS通用框架,在构build应用程序时,他们必须运行特殊的脚本(自定义运行脚本阶段),从该框架的二进制文件中删除模拟器切片,以便应用程序可以通过AppStorevalidation。

我在Realm中find的二进制框架的好例子: strip-frameworks.sh 。

它使用lipo去除除${VALID_ARCHS}之外的所有体系结构片段,然后用消费者的身份对其进行重新${VALID_ARCHS} – 这是观察#3开始的地方:由于对其的lipo操纵,框架将被重新签名。

迦太基有CopyFrameworks.swift脚本,对消费者所包含的所有框架都做同样的事情:它代表消费者剥离模拟器片和重新编码框架。

另外还有一篇好文章: 从Xcode中的dynamic库中剥离不需要的体系结构 。


现在,从开发人员和消费者的angular度来概述产生iOS和OSX所需的步骤。 首先更容易的一个:

OSX

开发商:

  1. 构buildOSX框架
  2. 给消费者

开发人员不需要进行代码签名活动。

消费者:

  1. 从Developer接收OSX框架
  2. 将框架复制到框架/目录,并作为“代码签名复制”过程的一部分自动代表消费者代码。

iOS版

开发商:

  1. 为设备构buildiOS框架。 Xcode需要Codesigning,“iPhone Developer”的身份就足够了。
  2. 为模拟器构buildiOS框架。
  3. 使用从前两个产生通用iOS框架的lipo。 此时丢失了1步的密码标识:通用框架二进制“根本没有签名”,但是“消费者不关心”就没有问题。
  4. 给消费者

消费者:

  1. 从Developer接收iOS框架
  2. 将框架复制到Frameworks /目录(根据步骤3中的脚本,此步骤可能是多余的)。
  3. 使用特殊的脚本作为构build过程的一部分:这个脚本将模拟器切片从iOS框架上剥离下来,然后代表消费者对其进行重新编码。

从阅读迦太基回购链接的线程看起来相对简单。 如果你正在分发二进制框架,你需要代码签名,如果你通过Carthage或cocoa豆荚分发源代码,你不需要通过不同的方法来处理这个问题。

当你分发二进制框架时,你需要对它进行代码签名的原因是Xcode不会在没有代码签名的情况下生成一个框架二进制文件。 如果您尝试不对二进制框架进行编码,则会出现以下错误:

 CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1' 

(iPhone开发人员或iPhone发行版)签署框架的身份无关紧要,因为正如您所指出的那样,框架将使用“复制代码签名”设置进行重新签名。 这意味着当您的框架被复制到他们的应用程序中时,您的框架将被来自框架消费者的开发者configuration文件的适当证书重新签名。 这意味着App Store将不会出现问题,因为它只会看到框架使用者的最终代码签名。

在这一天结束的时候,你可能还需要签署你的.framework二进制文件,因为你不想维护一个奇特的构build过程,而Xcode只会输出已签名的框架,所以你不应该离开默认值。 无论如何,这并不重要,因为最终消费者会重新签名。