我正在学习如何创建iOS和OSX框架.以iOS为例,到目前为止,以下步骤适用于我:

  1. xcodebuild框架使用-sdk iphoneSimulation ator和build操作
  2. xcodebuild框架使用-sdk iphoneos和build操作
  3. 使用lipo工具创建通用二进制文件,以便lipo -info生成预期的:

FAT文件:foo.framework/foo中的体系 struct 为:i386x86_64ARMv7arm64

问题是:

  1. 我读到我的框架可以由使用它的开发人员重新签名:"Code Sign on Copy",但我不明白它的前提条件是什么,即should I add codesign step to codesign that universal binary with my signing identity before distributing it to other developers?

  2. 如果之前是肯定的-我应该使用我的"iPhone分发:."身份或"iPhone开发者:."足够了吗(让我的框架作为某个iOS项目的一部分通过各种验证,特别是App Store验证)?

我回答的背景是"CoDesign错误:SDK‘iOS 8.3’中的产品类型‘Framework’需要代码签名",这是我在许多第三方框架和Carthage#235或"代码对象根本没有签名"(例如:我在Realm#1998报告的问题)上看到的.

因此,我希望确保我的框架的用户在使用它们时不会遇到任何代码设计问题.

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

推荐答案

我开启了悬赏:"寻找可靠和/或官方来源的答案."但从那以后就再也没有收到过.

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

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

首先,让我们断言,框架的正确代码签名所需的操作应该分为steps that framework's Developer has to takesteps that framework's Consumer has to take.

TLDR;

对于OSX框架:Developer is free to distribute OSX framework without codesigning it as Consumer will re-codesign it anyway.

对于IOS框架: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.

Because of radar: 100 Consumer of iOS framework is forced to run special script like "copy_frameworks" or "strip_frameworks" which uses 101 to 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 101 manipulation.

下面是更长的答案.


这个答案不是"从可信的和/或官方来源得出的",而是基于一些经验观察得出的.

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

Githubare not codesigned上著名开源项目的二进制框架发行版.在我用来研究的所有二进制IOS和OSX框架上,命令codesign -d -vvvv给出了:"代码对象根本没有签名".一些示例:ReactiveCocoaMantleRealmPromiseKit.

从这一观察结果可以清楚地看出,这些框架的作者打算让消费者代表他们进行代码签名,即消费者必须在Xcode提供的"嵌入框架"构建阶段使用"复制时代码签名"标志,或者使用一些定制的shell脚本手动执行相同的操作:代表消费者进行代码签名框架.

我没有找到任何相反的例子:开放源码框架分发时带有协同设计身份,所以在答案的睡觉中,我假设这个被广泛采用的方法是正确的: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

虽然消费者并不关心他们从开发者那里收到的框架是否是共同设计的,但是开发者still needs to codesign their iOS framework as part of its build process when they build it for iOS device,因为否则Xcode不会构建:CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'.引用Justin Spahr-Summers句话:

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

这很好地回答了我的第二个问题:"iPhone开发者"的身份足以诱使Xcode为设备构建iOS框架.This comment on Carthage#339也是一样的意思.

Empiric observation #3: lipo tool

lipo工具的具体行为:when applied to framework binary, it always recursively removes any codesign identities from it:lipo -create/-remove codesigned framework ... -> not codesigned framework.

这可能是为什么观察#1中的所有例子根本没有共同设计的原因:他们的共同设计身份在使用脂肪后就消失了,但根据观察#1,消费者并不关心这是好的.

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

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

这在:Realm#1163Carthage#188中被广泛讨论,雷达在rdar://19209161中打开.

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

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

It uses 100 to remove all slices of architectures other than 101 and then re-codesigns it with Consumer's identity-这就是观察#3的用武之地:由于对框架进行了LIPO操作,框架将被重新联合设计.

Carthage有CopyFrameworks.swift个脚本,它对Consumer包含的所有框架都做同样的事情:它剥离模拟器切片,代表Consumer重新设计框架.

还有一篇好文章:Stripping Unwanted Architectures From Dynamic Libraries In Xcode篇.


现在从开发者和消费者的Angular 概述生产iOS和OSX所需的步骤.首先是比较容易的那个:

OSX

开发商:

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

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

消费者:

  1. 从开发者那里接收OSX框架
  2. 将框架复制到Frameworks/目录,并作为"复制时代码签名"过程的一部分,在消费者的代表上自动对其进行协同设计.

iOS

开发商:

  1. 为设备构建IOS框架.Xcode要求Codesign,"iPhone开发者"身份就足够了.
  2. 构建了仿真器的IOS框架.
  3. 使用lipo生成前两个版本的通用iOS框架.此时,1步的代码签名身份消失了:通用框架二进制文件"根本没有签名",但这很好,因为"消费者不在乎".
  4. 给消费者

消费者:

  1. 从开发人员处接收IOS框架
  2. 将框架复制到Frameworks/目录(此步骤可能是多余的,具体取决于步骤3中的脚本).
  3. 使用特殊脚本作为构建过程的一部分:该脚本将模拟器从iOS框架中剥离,然后代表其消费者重新编码.

Ios相关问答推荐

为什么controlSize属性在SwiftUI中不起作用?

在将Cocoapods更新到1.13.0之后,它抛出错误

执行devicectl:ProcessException时出错:进程异常退出:错误:命令超时超过5.0秒

BezierPath 中绘制图像形状轮廓的算法(Canny 边缘检测器)

使用 WebKit 加载 YouTube 视频时控制台中打印警告

如何在SwiftUI中实现淡入淡出加粘标题屏幕效果

由于缺少 libarclite_iphonesimulator.a 文件,将 XCode 升级到 14.3 后无法在模拟器上运行 Flutter 应用程序

iOS 16 中的状态栏 colored颜色

iOS应用程序崩溃,必需条件为false:isformatsamplerateandchannelcountvalid(format)

视觉扫描无法识别 iOS16 上的 GS1 条码特殊字符

在 SwiftUI 中重构提取到子视图的 GeometryReader 代码

SwiftUI Select 器值在超过最大值时重置

SwiftUI:添加核心数据项时更新选项卡栏徽章

在 Swift 中合并子数组

Xcode - 错误 ITMS-90635 - Bundle 包中的 Mach-O 无效 - 提交到 App Store

界面生成器 - 无法从路径加载设计对象(空)

为什么 Safari 在使用 iOS 6 设备进行远程调试时显示No Inspectable Applications?

UIView 和 initWithFrame 以及一个 NIB 文件.如何加载 NIB 文件?

使用 swift 从应用程序委托打开视图控制器

CoreBluetooth 应用程序到底能在后台做什么?