首页 > 解决方案 > 将 XCFrameworks 集成到开发和发布工作流程中

问题描述

我有一个 Xcode 工作区,其中包含一个 iOS 框架目标和一个依赖并嵌入框架的 iOS SampleApp 目标。该框架是闭源的,因此以二进制形式交付给客户,在一个发布包中与整个 SampleApp 项目的源代码副本一起提供,以便他们可以使用我们的应用程序对其进行测试并查看集成是如何完成的。

通过这种设置,在开发阶段,我可以在 Xcode 中打开工作区并构建 SampleApp 目标,并且由于它对框架有显式依赖,Xcode 会立即触发框架的构建,然后构建并链接应用程序正确。

现在我想利用新的XCFramework 格式将这个框架分发给客户,而不是使用 lipo'ed fat 框架。我更新了生成发布包的 shell 脚本,以在最后创建一个支持所有各种平台的 xcframework 包,并更新 SampleApp 项目以依赖此 xcframework,而不是像以前那样依赖于单个框架。

但是更新后的 SampleApp 出现了问题:移除了对框架的依赖后,上述工作空间设置不再起作用,即在构建 SampleApp 目标时,Xcode 将不再自动构建框架目标,因为显式依赖两者之间的联系现在被打破了。

我第一次尝试解决这个问题,也包括让 xcframework 成为我常规开发工作流程的一部分。为此,我向框架构建目标添加了一个运行脚本阶段,该阶段生成一个仅限当前平台的 xcframework 包并将其复制到 SampleApp 期望找到它的位置,然后将框架目标添加到 SampleApp 的目标中构建方案,以便在构建 SampleApp 时构建框架。不幸的是,这种方法不起作用,因为 Xcode 12 似乎总是并行构建两个目标,无论“Parallelize Build”设置是什么,因此应用程序将无法构建,因为 xcframework 还没有准备好它由构建系统处理,该系统在 SampleApp 的构建阶段非常早期。所以除非有'

如果这种方法不起作用,那么我必须在未修改 SampleApp 的情况下发布 xcframework,并指示想要运行该应用程序的客户手动删除对通用框架的引用,然后将 xcframework 添加/拖动到它。这会起作用,但它很丑陋,而且对我来说似乎不够友好。

我还在考虑一种不同的方法,即发布脚本以编程方式修改 SampleApp.xcodeproj 以依赖于 xcframework 而不是通用框架,但这似乎是一件非常脆弱的事情,所以宁愿避免它如果有更好的方法。

这种情况对我来说似乎并不独特,所以我猜其他人一定也遇到过这个问题。如果是这样,您是如何解决的?

标签: iosxcodebuildframeworksxcframework

解决方案


所以我最终通过在发布时以编程方式修改 SampleApp 的项目文件来链接和嵌入 xcframework 包而不是通用框架来解决这个问题。

最初尝试使用工具pbxproj但效果不佳,最初的胖框架删除阶段没有成功。

然后我想我可以project.pbxproj在用 xcframework 手动替换框架后尝试对文件进行比较,结果只需要进行一些小的编辑即可到达那里,因此可以使用如下简单的 shell 脚本以编程方式完成它们:

#!/bin/bash

PROJECT_FILE=SampleApp/SampleApp.xcodeproj/project.pbxproj
FRAMEWORK_NAME=MyFramework.framework
XCFRAMEWORK_NAME=MyFramework.xcframework

sed -i '' "s|FileType = wrapper.framework; path = ${FRAMEWORK_NAME}; sourceTree = BUILT_PRODUCTS_DIR;|FileType = wrapper.xcframework; path = ${XCFRAMEWORK_NAME}; sourceTree = \"<group>\";|" ${PROJECT_FILE}
sed -i '' "s|${FRAMEWORK_NAME}|${XCFRAMEWORK_NAME}|g" ${PROJECT_FILE}

其他项目设置可能存在细微差异,但主要归结为这一点。请注意,如果 xcframework 打算放置在项目根目录以外的某个位置,那么您需要在第一个命令中同时使用 aname和 a属性,例如:pathsed

name = "MyFramework.xcframework"; path = "relative/path/to/MyFramework.xcframework"

推荐阅读