创建 iOS/OSX 框架:是否有必要在分发给其他开发人员之前对其进行协同设计?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30963294/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 06:31:51  来源:igfitidea点击:

Creating iOS/OSX Frameworks: is it necessary to codesign them before distributing to other developers?

ioscode-signingios-frameworks

提问by Stanislav Pankevich

I am learning how to create iOS and OSX frameworks. Let's take iOS for example, the following steps work for me so far:

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

  1. xcodebuild framework using -sdk iphonesimulator and Build action
  2. xcodebuild framework using -sdk iphoneos and Build action
  3. Use lipo tool to create universal binary so that lipo -infoproduces expected:
  1. 使用 -sdk iphonesimulator 和 Build 动作的 xcodebuild 框架
  2. 使用 -sdk iphoneos 和 Build 动作的 xcodebuild 框架
  3. 使用 lipo 工具创建通用二进制文件,以便lipo -info产生预期的:

Architectures in the fat file: Foo.framework/Foo are: i386 x86_64 armv7 arm64

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

The questions are:

问题是:

  1. I read that my framework can be re-signed by developer who is using it: "Code Sign on Copy" but I don't understand what are preconditions for it i.e. should I add codesign step to codesign that universal binary with my signing identity before distributing it to other developers?

  2. if previous is positive - should I use my "iPhone Distribution: ..." identity or "iPhone Developer: ..." is enough (so that my framework being a part of some iOS project passes all kinds of validations especially App Store validation)?.

  1. 我读到我的框架可以由正在使用它的开发人员重新签名:“复制时代码签名”但我不明白它的先决条件是什么,即我应该添加协同设计步骤来使用我的签名身份之前对通用二进制文件进行协同设计将其分发给其他开发人员?

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

Background for my answer is the "CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.3'" which I have seen on a number of third-party frameworks and Carthage#235or "code object is not signed at all" (one example: issue I reported on Realm#1998.

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

So I want to be sure that users of my frameworks will not encounter any codesigning issues when they use them.

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

P.S. This question gets even more interesting when applied not to a single developer but to an organization which is a framework vendor.

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

回答by Stanislav Pankevich

I opened the bounty: "Looking for an answer drawing from credible and/or official sources." but haven't receive such since then.

我打开了悬赏:“从可靠和/或官方来源寻找答案。” 但从那以后就没有收到过这样的东西。

While answer provided by @Hymanslash is correct, it tells only a part of story so I want to write my own in a way I would like to have seen it at the moment I was asking this question.

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

The actuality of this answer is: July 2015. It is most likely that things will change.

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

First of all let's assert that actions needed for correct code signing of framework should be divided into steps that framework's Developer has to takeand steps that framework's Consumer has to take.

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

TLDR;

TLDR;

For OSX framework: Developer is free to distribute OSX framework without codesigning it as Consumer will re-codesign it anyway.

对于 OSX 框架:开发人员可以自由分发 OSX 框架而无需对其进行编码,因为消费者无论如何都会对其进行重新编码。

For iOS framework: Developer is free to distribute iOS framework without codesigning it as Consumer will re-codesign it anyway, but Developer is forced by Xcode to codesign their framework when they build for iOS device.

对于 iOS 框架:开发人员可以自由分发 iOS 框架而无需对其进行编码,因为消费者无论如何都会对其进行重新编码,但开发人员在为 iOS 设备构建时会被 Xcode 强制对其框架进行编码。

Because of radar: "iOS frameworks containing simulator slices can't be submitted to the App Store"Consumer of iOS framework is forced to run special script like "copy_frameworks" or "strip_frameworks" which uses lipo -removeto strip off simulator slices from iOS framework and re-codesigns stripped framework because at this point its codesigning identity whatever it was (or wasn't) is removed as side effect of lipo -removemanipulation.

由于雷达:“包含模拟器切片的iOS框架无法提交到App Store”iOS框架的消费者被迫运行特殊脚本,如“copy_frameworks”或“strip_frameworks”,用于lipo -remove从iOS框架中剥离模拟器切片并重新-codesigns 剥离了框架,因为此时它的代码标识身份无论是(或不是)都作为lipo -remove操作的副作用被删除。

Longer answer follows.

更长的答案如下。



This answer is not a "drawing from credible and/or official sources" one but is rather based on a number of empiric observations.

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

Empiric observation #1: Consumer does not care because they will re-codesign framework they receive from Developer

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

Binary framework distributions of well-known open source projects on Github are not codesigned. Command codesign -d -vvvvgives: "code object is not signed at all" on all of the binary iOS and OSX frameworks I used to explore. Some examples: ReactiveCocoaand Mantle, Realm, PromiseKit.

Github知名开源项目的二进制框架分布没有经过协同设计。命令codesign -d -vvvv给出:在我曾经探索过的所有二进制 iOS 和 OSX 框架上,“代码对象根本没有签名”。一些例子: ReactiveCocoaMantleRealmPromiseKit

From this observation it is clear that authors of these frameworks intend them to be codesigned by Consumer, on their behalf i.e. a Consumer must use either "Code Sign on Copy" flag in "Embed frameworks" build phase provided by Xcode or use some custom shell script which does the same thing manually: codesigns framework on the Consumer's behalf.

从这个观察中可以明显看出,这些框架的作者希望它们由消费者代表他们进行代码签名,即消费者必须使用 Xcode 提供的“嵌入框架”构建阶段中的“复制时代码签名”标志或使用一些自定义外壳手动执行相同操作的脚本:代表消费者的协同设计框架。

I didn't find any single example of the opposite: open source framework that would be distributed with codesigning identity in it so in the rest of the answer I am assuming this widely adopted approach as correct one: there is no need for framework Developer to distribute their framework to other developers with codesigning identity in it because Consumer will anyway re-codesign it.

我没有找到任何相反的例子:开源框架将在其中分发代码签名标识,因此在答案的其余部分中,我假设这种广泛采用的方法是正确的:框架开发人员不需要将他们的框架分发给其他具有代码签名标识的开发人员,因为消费者无论如何都会重新设计它

Empiric observation #2 which applies to iOS only and which is entirely a Developer's concern

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

While Consumer does not care whether framework they receive from Developer is codesigned or not, Developer still needs to codesign their iOS framework as part of its build process when they build it for iOS devicebecause otherwise Xcode does not build: CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'. To quote Justin Spahr-Summers:

虽然消费者并不关心他们从开发人员那里收到的框架是否经过代码设计,但开发人员在为 iOS 设备构建它时仍然需要将他们的 iOS 框架作为其构建过程的一部分进行代码设计,否则 Xcode 不会构建:CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'。引用Justin Spahr-Summers 的话

OS X frameworks don't need to be codesigned at build... Unfortunately, Xcode does require that iOS frameworks be codesigned at build time.

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

This pretty well answers on my question #2: "iPhone Developer" identity is enough to cajole Xcode so that it would build iOS framework for device. This comment on Carthage#339says the same thing.

这很好地回答了我的问题 #2:“iPhone 开发人员”身份足以哄骗 Xcode,以便它为设备构建 iOS 框架。这个关于 Carthage#339 的评论说同样的话。

Empiric observation #3: lipo tool

经验观察 #3:脂质工具

Specific behavior of lipo tool: when applied to framework binary, it always recursively removes any codesign identities from it: lipo -create/-remove codesigned framework ... -> not codesigned framework.

lipo 工具的特定行为:当应用于框架二进制文件时,它总是递归地从中删除任何协同设计标识lipo -create/-remove codesigned framework ... -> not codesigned framework

This could be an answer why all of the examples in observation #1 are not codesigned at all: their codesigning identity is blown away after lipo is applied but since according to observation #1 Consumer does not care it is fine.

这可能是为什么观察 #1 中的所有示例根本没有进行协同设计的答案:在应用 lipo 后,它们的协同设计身份被吹走,但因为根据观察 #1 消费者并不关心这很好。

This observation is especially relevant to the next observation #4 about AppStore.

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

Empiric observation #4: iOS frameworks containing simulator slices can't be submitted to the App Store

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

This is widely discussed in: Realm#1163and Carthage#188and radar is opened: rdar://19209161.

这在:Realm#1163Carthage#188 中得到了广泛的讨论,并打开了雷达:rdar://19209161

This is entirely Consumer's concern: for iOS universal framework that Consumer includes in their application, when application is being built, they must run special script (custom Run Script Phase) that removes simulator slice from that framework's binary so that app could pass AppStore validation.

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

The good example for binary frameworks I found in Realm: strip-frameworks.sh.

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

It uses lipoto remove all slices of architectures other than ${VALID_ARCHS}and then re-codesigns it with Consumer's identity- this is where observation #3 kicks in: framework is to be re-codesigned because of lipo manipulations on it.

它用于lipo移除架构的所有部分${VALID_ARCHS},然后使用消费者的身份对其进行重新编码- 这就是观察 #3 开始的地方:由于对框架进行了脂质操作,因此将重新编码框架。

Carthage has CopyFrameworks.swiftscript which does the same thing to all the frameworks included by Consumer: it strips off the simulator slices and re-codesigns framework on behalf on Consumer.

Carthage 有CopyFrameworks.swift脚本,它对 Consumer 包含的所有框架执行相同的操作:它剥离模拟器切片并代表 Consumer 重新编码框架。

Also there is good article: Stripping Unwanted Architectures From Dynamic Libraries In Xcode.

还有一篇好文章:从 Xcode 中的动态库中剥离不需要的架构



Now the overview of steps required to produce both iOS and OSX from both Developer's and Consumer's perspectives. First the easier one:

现在从开发人员和消费者的角度概述生成 iOS 和 OSX 所需的步骤。第一个更简单的:

OSX

操作系统

Developer:

开发商:

  1. Builds OSX framework
  2. Gives it to Consumer
  1. 构建 OSX 框架
  2. 给消费者

No codesigning activities are required from Developer.

开发人员不需要任何代码设计活动。

Consumer:

消费者:

  1. Receives OSX framework from Developer
  2. Copies framework to Frameworks/ directory and codesigns it automatically on their, Consumer's, behalf as part of "Code Sign on Copy" process.
  1. 从开发人员接收 OSX 框架
  2. 将框架复制到 Frameworks/ 目录并代表他们的消费者自动对其进行代码签名,作为“复制代码签名”过程的一部分。

iOS

IOS

Developer:

开发商:

  1. Builds iOS framework for device. Codesigning is required by Xcode, "iPhone Developer" identity is enough.
  2. Builds iOS framework for simulator.
  3. Uses lipo that produces universal iOS framework from previous two. At this point the codesigning identity of 1 step is lost: universal framework binary "is not signed at all" but that is fine since "Consumer does not care".
  4. Gives it to Consumer
  1. 为设备构建 iOS 框架。Xcode 需要编码,“iPhone 开发者”身份就足够了。
  2. 为模拟器构建iOS框架。
  3. 使用从前两个生成通用 iOS 框架的 lipo。此时,第 1 步的代码签名标识丢失了:通用框架二进制文件“根本没有签名”,但这很好,因为“消费者不在乎”。
  4. 给消费者

Consumer:

消费者:

  1. Receives iOS framework from Developer
  2. Copies framework to Frameworks/ directory (this step may be redundant depending on what script in step 3 is.)
  3. Uses special script as a part of build process: this script strips simulator slices off the iOS framework and then re-codesigns it on their, Consumer's, behalf.
  1. 从开发人员接收 iOS 框架
  2. 将框架复制到 Frameworks/ 目录(此步骤可能是多余的,具体取决于步骤 3 中的脚本是什么。)
  3. 使用特殊脚本作为构建过程的一部分:此脚本从 iOS 框架中剥离模拟器切片,然后代表他们的消费者重新编码。

回答by Hymanslash

From reading the linked thread on the Carthage repo it seems relatively simple. If you are distributing the binary framework you need to code sign it and if you are distributing the source via carthage or cocoa pods you do not as those tools take care of this via different methods.

通过阅读 Carthage 存储库上的链接线程,它似乎相对简单。如果您分发二进制框架,则需要对其进行代码签名,如果您通过 carthage 或可可豆荚分发源代码,则不需要,因为这些工具通过不同的方法处理此问题。

The reason you need to code sign it when you distribute the binary framework is that Xcode won't produce a framework binary without code signing it. If you attempt to not code sign the binary framework you get this error:

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

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

It doesn't matter which identity you code sign the framework with (iPhone Developer or iPhone Distribution) because, as you point out, the framework will be re-codesigned with the "code sign on copy" setting. This means that your framework will be re-codesigned by the appropriate certificate from the framework consumer's developer profile when your framework is copied into their application. This means there will be no issues with the App Store as it will only see the final code signature from the framework consumer.

您使用哪种身份对框架进行编码(iPhone 开发人员或 iPhone 发行版)并不重要,因为正如您所指出的,框架将使用“复制时的代码签名”设置重新编码。这意味着当您的框架被复制到他们的应用程序中时,您的框架将通过框架使用者的开发人员配置文件中的适当证书重新设计。这意味着 App Store 不会有任何问题,因为它只会看到来自框架使用者的最终代码签名。

In the end of the day, you might as well code sign your .framework binary as you don't want to have to maintain an exotic build process, and as Xcode will only output signed frameworks you shouldn't move too far away from the defaults. It doesn't really matter anyway because the end consumer will be re-signing it.

归根结底,您最好对您的 .framework 二进制文件进行编码,因为您不想维护一个异国情调的构建过程,并且由于 Xcode 只会输出已签名的框架,因此您不应该远离默认值。反正这并不重要,因为最终消费者将重新签署它。

回答by Dino Alves

Stanislav Pankevich's answer above is very valid and correct. But please note that as of Xcode 9.4, the IDE will ask you to disable code signing for iOS Cocoa Touch Frameworks. Apple here now says it is not recommended that you code sign your .framework.

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

I hope this helps.

我希望这有帮助。