创建iOS / OSX框架:在分发给其他开发人员之前是否需要对其进行代码签名?


90

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

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

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

问题是:

  1. 我读到我的框架可以由正在使用它的开发人员重新签名:“复制时进行代码签名”,但我不知道其先决条件,即我应该添加代码签名步骤以使用我的签名身份对该通用二进制文件进行代码签名分发给其他开发人员?

  2. 如果以前是肯定的-我应该使用我的“ iPhone Distribution:...”身份还是“ iPhone Developer:...”就足够了(这样我的框架作为某些iOS项目的一部分就可以通过各种验证,尤其是App Store验证)?。

我回答的背景是“ CodeSign错误:SDK'iOS 8.3'中产品类型'Framework'需要代码签名”,我在许多第三方框架和Carthage#235上都看到过,或者“代码对象未签名”根本”(一个例子:我在Realm#1998上报道的问题。

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

PS:这个问题不仅仅适用于单个开发人员,而适用于作为框架供应商的组织,则变得更加有趣。


此注释建议使用“ CODE_SIGN_IDENTITY = iPhone Developer”,但不清楚为什么使用“ Developer”而不是“ iPhone Distribution”。
Stanislav Pankevich 2015年

相关主题:导出具有嵌入式框架但没有明确答案的应用程序
Stanislav Pankevich 2015年

我还在Apple开发者论坛上提出了这个问题:forums.developer.apple.com/thread/6400
Stanislav Pankevich 2015年

当您分发框架,分发调试版本或发布版本时,我有一个问题?如果您在发行版本中分发它,该怎么做?
niczm25

@ niczm25,这是我的操作方式之一:stanislaw.github.io/2015/11/23/…
Stanislav Pankevich '17

Answers:


137

我打开悬赏金:“寻找可靠和/或官方来源的答案。” 但此后再也没有收到过。

虽然@jackslash提供的答案是正确的,但它只讲述了故事的一部分,因此我想以自己想问这个问题的方式来编写自己的故事。

答案的现实是:2015年7月。情况很可能会改变。

首先让我们断言的是需要框架的正确的代码签名行动应该分为步骤该框架的开发者已采取步骤该框架的消费者必须采取。

TLDR;

对于OSX框架:开发者可以自由分发OSX框架,而无需对其进行代码签名,因为Consumer仍将对其进行重新设计。

对于iOS框架:开发者可以自由分发iOS框架而无需对其进行代码签名,因为Consumer仍然会重新设计它,但是Xcode迫使Developer在为iOS设备构建时对其框架进行代码签名。

由于雷达的原因:“无法将包含模拟器切片的iOS框架提交给App Store” iOS框架的使用者被迫运行特殊脚本,例如“ copy_frameworks”或“ strip_frameworks”,该脚本会lipo -remove从iOS框架中剥离模拟器切片并重新-codesigns剥离了框架,因为此时它的代码签名身份(无论是否曾经)都被删除,这是lipo -remove操纵的副作用。

答案更长。


这个答案不是“从可靠的和/或官方的来源中汲取”,而是基于许多经验性的观察。

经验观察#1:消费者不在乎,因为他们将重新设计从开发人员那里收到的框架

Github著名的开源项目的二进制框架发行版未进行代码签名。命令codesign -d -vvvv给出:在我以前研究过的所有二进制iOS和OSX框架上,“代码对象根本没有签名”。一些示例: ReactiveCocoaMantleRealmPromiseKit

从这个观察结果可以明显看出,这些框架的作者希望它们由Consumer进行代码签名,即消费者必须在Xcode提供的“ Embed frameworks”构建阶段中使用“ Code Sign on Copy”标志或使用某些自定义shell手动执行相同操作的脚本:代表使用者对框架进行符号签名。

我没有发现相反的任何例子:开源框架将在其中带有代码签名身份进行分发,因此在其余的答案中,我假设这种被广泛采用的方法是正确的:无需框架开发人员将其框架分发给具有代码签名身份的其他开发人员,因为消费者仍然会重新设计它

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

尽管Consumer不在乎是否从Developer接收到的框架是否经过代码签名,但在为iOS设备构建iOS框架时,Developer仍需要对其iOS框架进行代码签名,因为否则Xcode不会构建:CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'。引用贾斯汀·斯帕夏(Justin Spahr-Summers)

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

这很好地回答了我的问题2:“ iPhone开发者”身份足以哄骗Xcode,以便它将为设备构建iOS框架。关于迦太基#339的评论也是如此。

经验观察#3:脂工具

lipo工具的特定行为:应用于框架二进制文件时,它总是以递归方式从中删除任何代码符号标识lipo -create/-remove codesigned framework ... -> not codesigned framework

这可能是一个答案,为什么观察点1中的所有示例都根本没有进行代码签名:在应用脂质之后,它们的代码签名身份被吹走了,但是由于根据观察点1,消费者并不在意它是好的。

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

经验观察之四:无法将包含模拟器切片的iOS框架提交到App Store

Realm#1163Carthage#188中广泛讨论了此问题,并且打开了雷达:rdar:// 19209161

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

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

它用于lipo删除除架构之外的所有架构片段,${VALID_ARCHS}然后使用Consumer的身份进行重新设计-这就是观察#3的地方:由于对lipo的操纵,将对框架进行重新编码。

迦太基拥有CopyFrameworks.swift脚本,该脚本对Consumer所包含的所有框架都具有相同的作用:它剥离了模拟器片段,并代表Consumer进行重新设计框架。

也有一篇不错的文章:在Xcode中从动态库中删除不需要的体系结构


现在,从开发人员和消费者的角度概述生产iOS和OSX所需的步骤。首先比较简单:

OSX

开发商:

  1. 建立OSX框架
  2. 给消费者

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

消费者:

  1. 从开发人员那里接收OSX框架
  2. 将框架复制到Frameworks /目录,并在其使用方的代表下自动对其进行代码签名,作为“复制代码签名”过程的一部分。

的iOS

开发商:

  1. 为设备构建iOS框架。Xcode需要协同设计,“ iPhone Developer”的身份就足够了。
  2. 为模拟器构建iOS框架。
  3. 使用从前两个产生通用iOS框架的lipo。在这一点上,失去了第一步的代码签名身份:通用框架二进制文件“根本没有签名”,但这很好,因为“消费者不在乎”。
  4. 给消费者

消费者:

  1. 从开发人员那里接收iOS框架
  2. 将框架复制到Frameworks /目录(此步骤可能是多余的,具体取决于步骤3中的脚本。)
  3. 在构建过程中使用特殊脚本:此脚本从iOS框架中剥离模拟器片段,然后代表其使用者重新进行协同设计。

9
这是有价值的文章。好人
jackslash 2015年

@Stanislaw感谢您的见解和宝贵数据。我在编写自己为开发人员设计的框架时,希望他们能够按原样使用框架并使用它,而无需制作特殊脚本即可上传到应用商店。我认为GoogleMobileAd可以这样工作。但是您说他们必须运行某些脚本?您知道GoogleMobileAds不需要这样做吗?谢谢
Michael A

@MichaelA,确实很有趣。我看看
Stanislav Pankevich

您能否给我一个指向您正在使用的GoogleMobile广告的链接?
Stanislav Pankevich

1
谢谢您节省我的时间,这对我有用。Xcode 7.3,Mac OS X 10.11.4。
eugen

21

通过阅读迦太基回购上的链接线程,它似乎相对简单。如果您要分发二进制框架,则需要对其进行代码签名,并且如果您是通过迦太基或可可豆荚来分发源代码,那么您就不会这样做,因为那些工具会通过不同的方法来解决这一问题。

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

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

您使用哪个身份对框架(iPhone Developer或iPhone Distribution)进行代码签名都没有关系,因为如您所指出的那样,将使用“复制时代码签名”设置对框架进行重新代码签名。这意味着当将框架复制到应用程序中时,将使用来自框架使用者的开发人员资料的适当证书对框架进行重新编码。这意味着App Store不会有任何问题,因为它只会看到框架使用者的最终代码签名。

最终,您最好对.framework二进制代码进行代码签名,因为您不想维护异国情调的构建过程,而且由于Xcode仅输出已签名的框架,因此您不应该离开默认值。无论如何,这并不重要,因为最终用户将重新签名。


在您的回答中,在它的第二段中,您说的是无需进行代码签名框架,因为它将由消费者重新进行代码签名,我现在也95%确信它是正确的,但是我没有得到为什么同时在第一段中说:“如果要分发二进制框架,则需要对其进行代码签名”-有什么区别-如果我分发二进制框架(即,不是通过迦太基或cocoapods来源),为什么我需要进行代码签名吗?
Stanislav Pankevich

我认为无论使用哪种发行版(压缩的.framework文件,迦太基或可可足类),都不应对框架进行代码签名。示例:以下所有二进制框架发行版均未进行代码签名RealmReactiveCocoaOCMockito
Stanislav Pankevich

因此,我对您的“如果您正在分发二进制框架,需要对其进行代码签名”感到困惑,这(恕我直言)与您的其余答案相矛盾。请澄清。另外请注意,我以“从可靠和/或官方来源寻找答案”的身份来悬赏。
Stanislav Pankevich

1
是的,我也研究了Realm和OCMockito。领域具有“ iPhone Developer”身份,是的,OCMockito是静态库。我想我理解这个问题-当lipo结合了代码签名的iphoneos和未代码签名的iphonesimulator时,正是lipo从iphoneos上删除了代码签名。
Stanislav Pankevich

1
当您分发框架,分发调试版本或发布版本时,我有一个问题?如果您在发行版本中分发它,该怎么做?
niczm25

1

斯坦尼斯拉夫·潘克维奇(Stanislav Pankevich)的上述回答非常正确和正确。但是请注意,从Xcode 9.4开始,IDE将要求您禁用iOS Cocoa Touch Framework的代码签名。Apple现在在这里表示,不建议您对.framework进行代码签名。

我希望这有帮助。


1
您是否有Apple推荐反对签名框架的消息来源?
瑞克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.