如何在 App Store 发布的 iOS 应用程序项目中正确嵌入第 3 方 .dylib 文件?

How to properly embed 3rd party .dylib files in iOS app project for App Store release?

我正在使用支持 H264 的 PJSIP 库构建一个 iOS 应用程序。构建 H264 时,我得到 1 个 .a 文件和 2 个 .dylib 文件。我尝试通过添加 "Embedded Libraries" 以及创建一个单独的框架然后将其添加到 "Embedded Libraries" 来在我的项目中使用 .dylibs。但是在将构建上传到 App Store 时,出现错误 "ERROR ITMS-90206:..."、"ERROR ITMS-90171:.."。所有指向在项目中使用外部动态库。我关注了https://developer.apple.com/library/content/technotes/tn2435/_index.html#//apple_ref/doc/uid/DTS40017543-CH1-TROUBLESHOOTING_BUNDLE_ERRORS-EMBEDDED__DYLIB_FILES

但他们要求遵循 "Adding A Framework Target" 中的步骤。我不知道如何创建一个只有 2 个 .dylib 文件而没有其他源代码或头文件的框架。请显示将 .dylib 文件嵌入到 iOS 应用程序以供 App Store 提交的步骤。

您必须以与框架相同的方式将所有共享库(.dylib 文件)直接添加并嵌入到顶层应用程序中。你不能把动态库放在一个框架内,因为 Apple 强烈建议不要使用这样的框架(称为 Umbrella 框架)并且 AppStore 不接受带有这样框架的应用程序(这是一个原因错误 ITMS-90171).

正如Apple documentation所说:

An umbrella framework is a framework bundle that contains other frameworks. While it is possible to create umbrella frameworks for macOS apps, doing so is unnecessary for most developers and is not recommended. Umbrella frameworks are not supported on iOS, watchOS, or tvOS.

我能够通过首先创建一个框架来提交一个带有 .dylib 的应用程序。 我尝试了苹果文档中描述的方法,但在提交到商店时出现错误(“无效的包。xyz.framework 处的包包含不允许的文件 'Frameworks')

我使用lipo工具手动将我的.dylib打包成一个框架。

$ lipo -create mylib.dylib -output mylib

现在你得到一个名为 'mylib' 的二进制文件 创建一个名为 mylib.framework 的文件夹并将二进制文件放入其中。 然后添加一个 Info.plist(您可以从现有框架中复制和修改一个。)在 Info.plist 中,填写您的框架的字段。要更新或添加的主要是“可执行文件”,它应该是该二进制文件的名称。

我遇到了另一个问题,我正在使用的另一个框架正在引用我原来的 .dylib,它已经不存在了,现在在框架中。为了解决这个问题,我使用了“install_name_tool”来修改其他框架以寻找我的新框架。

$ cd OtherLib.framework 
$ install_name_tool -change @rpath/mylib.dylib @rpath/mylib.framework/mylib OtherLib

您可以在这个不错的博客 post 中阅读有关该工具和修改库中各种路径的更多信息: https://medium.com/@donblas/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172

声誉不足,无法发表评论,但莫蒂的回答对我有用。

我最终为 post 构建阶段编写了一个 shell 脚本来自动执行此操作。

rpath 的有用提示:

如果您从源代码构建 .dylib 文件,您可以将项目设置中的 rpath 值更改为 MyFramework.framework/MyFramework 可执行文件,它将被lipo工具打包成。

这将为您节省一个额外的步骤 post-build