我正在开发一个iOS应用程序(A(,它嵌入了一个内部开发的框架(B(。在构建应用程序时,框架的依赖项嵌入到框架本身中,这导致应用商店验证过程拒绝应用程序,并返回错误:
ERROR ITMS-90206: "Invalid Bundle. The bundle at 'A.app/Frameworks/B.framework' contains disallowed file 'Frameworks'
检查已构建的.app
捆绑包可以确认这一点。
应用程序和内部框架的依赖关系都由Swift Package Manager管理,这是通过将所需的包依赖关系添加到每个项目和每个目标的";框架和库"将二进制与库链接";。框架B的所有依赖项都由应用程序共享,而B本身并不是Swift包。
我以前使用Carthage进行依赖关系管理,并通过将应用程序的依赖关系设置为"来避免这个问题;嵌入&符号";以及框架对";不要嵌入";在";框架和图书馆";。此设置确保所有框架依赖项都包含在A.app/Frameworks/
中,并且B.framework与这些依赖项相链接。然而,SPM没有提供任何可见的选项来以这种方式修改行为。
假设我没有以错误的方式处理这个问题,你如何确保Xcode不会将框架的SPM依赖项嵌入到框架本身中,而是动态地将它们链接到应用程序的版本?
我看到了完全相同的行为。使用Xcode<13.3,我们使用了以下脚本:
#!/bin/bash
# See https://bugs.swift.org/browse/SR-14292
set -euxo pipefail
cp -r "${BUILT_PRODUCTS_DIR}"/InternalFramework.framework/Frameworks/* "${TARGET_BUILD_DIR}"/"${FRAMEWORKS_FOLDER_PATH}"
rm -rf "${TARGET_BUILD_DIR}"/"${FRAMEWORKS_FOLDER_PATH}"/InternalFramework.framework/Frameworks/
这对Xcode 13.3不起作用,因为Xcode 13.3没有将框架嵌入InternalFramework.framework.的framework/文件夹中
另一种选择可能是这样做,明确列出要嵌入的框架:
frameworks=(
AWSCore.framework AWSS3.framework
…
)
for framework in "${frameworks[@]}"
do
rm -rf "${TARGET_BUILD_DIR:?}"/"${FRAMEWORKS_FOLDER_PATH}/$framework"
cp -r "${BUILT_PRODUCTS_DIR}"/$framework "${TARGET_BUILD_DIR}"/"${FRAMEWORKS_FOLDER_PATH}"
done
这将适用于模拟器,可能还适用于应用商店提交。对于在设备上运行,这将需要首先对框架进行重新签名。