在设备上构建和运行时,仅将嵌入式框架与其他动态框架链接失败

Posted

技术标签:

【中文标题】在设备上构建和运行时,仅将嵌入式框架与其他动态框架链接失败【英文标题】:Linking only embedded framework with other dynamic framework fails when build & run on device 【发布时间】:2016-07-22 13:21:35 【问题描述】:

tl;博士

将您的嵌入式框架与其他框架链接,并且不要将其他框架与您的应用程序链接,因为在设备上构建和运行时required code signature missing

说明:

设置:

我的设置非常简单(Swift 2.3 和 Xcode Xcode 8.0;构建版本 8S162m):

使用 Carthage (0.17.2) 我用 xcodebuild 8.0 和 TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 carthage build --platform ios 构建了 Other.framework MyApp 已嵌入 My.framework。 应用程序和框架项目位于一个 Xcode 工作区下。 我只将 Other.framework 链接到 My.framework(这意味着,MyApp 未链接到 Other.framework )。这里的重点是,MyApp 不需要使用 Other.framework API。

问题:

一切似乎都运行良好,直到我在设备上构建并运行应用程序。应用程序启动,然后进程因以下 Xcode 错误而中止:

dyld: Library not loaded: @rpath/Other.framework/Other  
  Referenced from: /private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/My  
  Reason: no suitable image found.  Did find:  
  /private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/Frameworks/Other.framework/Other: required code signature missing for '/private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/Frameworks/Other.framework/Other'  

我检查了 Other.framework 的签名,我觉得它没问题。此外,

解决方案(解决方法)

MyAppOther.framework 链接。太可怕了……这感觉很糟糕。

将完全相同的二进制文件 Other.framework 链接到 MyApp 并以这种方式解决问题,指出,Other.framework 已构建好的并且能够正确地重新签名。可能与迦太基无关。

注意: iOS 8+ framework with nested embedded framework也有类似的问题,不过,我的还有一点别的原因。

【问题讨论】:

我遇到了同样的错误,但我正在使用 Xcode 7.3.1 (7D1014) 构建在 iOS 10 设备上运行的应用程序。 【参考方案1】:

这个问题与嵌套框架无关。这完全是关于签名验证。 dyld 报告 Other.framework 缺少代码签名。您需要签署框架。这应该由 Xcode 为您完成,所以我很好奇 Other.framework 是如何构建的。

您可以通过签名自己解决这个问题。

codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign - /path/to/Other.framework

或只是彻底退出您的应用程序:

codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign - /path/to/My.app

【讨论】:

【参考方案2】:

我通过关注guidance解决了我的确切问题 您无需将“Other.framework”链接到您的 MyApp。只需添加运行脚本即可对需要缺少代码签名的任何嵌入框架进行签名

【讨论】:

这正是我的问题。我有几个框架,其中一些嵌入到其他框架中【参考方案3】:

在Carthage github page 上讨论这个问题,很明显问题中提到的解决方法实际上是预期的行为

Carthage 不支持嵌套框架。

嵌套框架不允许您重用这些框架。例如,如果A.frameworkB.framework 都依赖于Other.framework,那么它们都不能嵌套Other.framework——否则你最终可能会得到两个不同的版本,并且在运行时可能不会选择正确的版本。

这样做的正确方法是将其列为依赖项,但将其链接到应用程序目标。

完整讨论:Linking only embedded framework with other dynamic framework fails when build & run on device: "required code signature missing"

这在 README 中不清楚,所以我提出了另一个问题,要求更新文档:

Update to README: Linking dynamic frameworks to embedded frameworks requires as well linking them to the app target #1427

这在PR的范围内解决并关闭:

#1427 README upd: link dependencies from embedded frameworks to the app target

【讨论】:

以上是关于在设备上构建和运行时,仅将嵌入式框架与其他动态框架链接失败的主要内容,如果未能解决你的问题,请参考以下文章

iOS9:在模拟器和设备上使用动态框架

xcodebuild 命令无法与动态可可触摸框架一起正常工作

如何查看动态框架中使用的 NSLogs 打印的日志?

在闭源 Swift 框架中嵌入框架

iOS 8 动态框架:未加载库

胖静态库和框架节省?