如何归档包含自定义框架的应用程序?

时间:2016-02-26 15:32:25

标签: ios xcode

我有一个我已经创建的xcode框架项目,我可以将其编译成myframework.framework文件。编译之后,我将这个框架拖到我的应用程序的Frameworks项目文件夹中,然后利用框架中的类,我将适当的import语句添加到任何需要它的类中;这允许我的应用程序成功编译,并引用框架中定义的类。为了让应用程序部署成功到我的设备,我还将我的自定义框架添加到"嵌入式二进制文件"我的目标部分。完成所有这些后,我可以从xcode构建我的应用程序并在我的设备上运行它。

当我尝试存档应用商店的应用程序时出现问题。当我尝试这样做时,我得到了大量的编译器错误,其中xcode表示无法找到我的自定义框架中定义的任何类的声明。

如何在xcode中设置存档以便正确引用和嵌入我的自定义框架?

4 个答案:

答案 0 :(得分:23)

您实际上不需要将其放在“嵌入式​​二进制文件”部分中。您只需要在“链接的框架和库”部分中。确保您的框架是一个通用框架(意味着它可以为所有体系结构编译),并确保您设置了正确的编译器标志(-ObjC,如果您的框架有任何框架)类别等)如果你的框架包含任何c代码并且你想在你的客户端应用程序中启用bitcode然后你应该在你的“-fembed-bitcode”中添加你可能需要设置的其他东西,如“其他C标志”框架其他C标志。这些是我需要做的事情才能将我的框架应用程序带到商店。我认为这只是一种误解,你需要将它放在嵌入式二进制文件中,以便将它存档到商店。 / p>

这是我用来生成通用框架的构建脚本。它构建在我的桌面上。如果你的框架在Swift中,你可以取消注释第8节。您希望创建聚合目标,并在构建阶段将其添加为运行脚本。

# Merge Script

# 1
# Set bash script to exit immediately if any commands fail.
set -e

# 2
# Setup some constants for use later on.
FRAMEWORK_NAME="MyFramework"

# 3
# If remnants from a previous build exist, delete them.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi

# 4
# Build the framework for device and for simulator (using
# all needed architectures).
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch arm64 -arch armv7 -arch armv7s only_active_arch=no defines_module=yes -sdk "iphoneos"
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch x86_64 -arch i386 only_active_arch=no defines_module=yes -sdk "iphonesimulator"

# 5
# Remove .framework file if exists on Desktop from previous run.
if [ -d "${HOME}/Desktop/${FRAMEWORK_NAME}.framework" ]; then
rm -rf "${HOME}/Desktop/${FRAMEWORK_NAME}.framework"
fi

# 6
# Copy the device version of framework to Desktop.
cp -r "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework" "${HOME}/Desktop/${FRAMEWORK_NAME}.framework"

# 7
# Replace the framework executable within the framework with
# a new version created by merging the device and simulator
# frameworks' executables with lipo.
lipo -create -output "${HOME}/Desktop/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"

# 8
# Copy the Swift module mappings for the simulator into the
# framework.  The device mappings already exist from step 6.
#cp -r "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${HOME}/Desktop/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule"

# 9
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi

一旦您的框架在桌面上,如果您进入其中,将会有一个与您的框架同名的文本文档。如果你导航到那个并在终端上运行命令“lipo -info”,你应该得到以下输出:

Architectures in the fat file: MyFramework are: armv7 armv7s i386 x86_64 arm64 

答案 1 :(得分:10)

不确定现有答案是否对您有所帮助。我只是给出我的解决方案。首先,我想解释几个重要的构建阶段

目标依赖关系

如果您想在每次构建主机应用程序时重建自己的框架(链接到同一工作区)。您需要在此处添加框架目标。

链接二进制文件库

如果您想在代码中使用您的库(比如说您想要import MyFramework),那么您需要在此阶段将其链接。

嵌入框架

这是棘手的部分。 嵌入表示在分发时将框架与您的应用捆绑在一起。对于系统框架,例如AVFoundation,您不需要将其嵌入到您的应用中,因为它已经存在于iOS操作系统中。但是,对于自定义框架或第三方框架,您必须将它们嵌入到应用程序包中,这样当您在设备上部署应用程序时,应用程序才能真正找到它。这就是为什么如果您使用CocoapodsCarthage,他们都有额外的构建阶段将框架复制到应用程序包。 (对于Cocoapods,它被称为嵌入窗格框架,对于Carthage,它是一个运行copy-frameworks脚本的操作。所以对于您的自定义框架,您将使用现有的Embed Frameworks构建阶段或创建新运行脚本阶段将框架复制到您的应用包。

- 关于2017-05-17的更新 -

对于嵌入框架的东西,我最近发现了另一个重要的事实:

您可以使用file PATH/TO/Framework检查框架是静态的还是动态的。查看this stackoverflow question了解详情。

动态框架

只需要将动态框架嵌入到应用程序中。其中包括CarthageCocoapods创建的内容。如果您在构建项目后打开应用程序包,那么包含所有嵌入式框架的Frameworks文件夹,您将找到由Carthage和Cocoapods创建的文件夹以及您指定的框架。在嵌入框架阶段。

静态框架

所以现在您可能想知道那些静态框架在哪里?如果应用程序包中缺少它,我们如何仍然使用它?你是对的。它们位于捆绑包中,但不在Frameworks文件夹中。它们已合并到您的应用程序的可执行文件中。如果检查可执行文件的大小,那么每次向目标添加静态框架时都会意识到,它会增加。

静态框架不必嵌入(只需链接它们),它就像.swift.xib文件,将被编译到您的可执行文件中。

然后,在您使用任何框架之前还有一个步骤。目标内的Framework Search Paths 构建设置。同样,如果您查看CarthageCocoapods,它们都会在此设置中添加额外的路径。这告诉Xcode(或底层编译器)在哪里找到这些链接的嵌入式框架。

因此,每当您想要使用框架时,请务必考虑上述设置并完成所有设置。我已经使用这种方法一段时间了,当我遇到任何链接问题时会感到更自信。

最后,Apple有一篇非常重要的文章,您应该阅读https://developer.apple.com/library/content/technotes/tn2435/_index.html

答案 2 :(得分:0)

我有完全相同的问题。 如果您像我一样使用App Extension,则存档错误消息仅与App Extension相关。

请记住,您必须手动将自定义框架添加到应用程序扩展的“链接的框架和库”部分。 example pic

答案 3 :(得分:0)

希望这对您有帮助

  1. 在“目标”中选择您的项目。 2.然后搜索“跳过安装”。
  2. 将其更改为NO。
  3. 然后存档您的自定义框架。 (确保使用通用iOS设备)作为目标设备。
  4. 将其导出到哪里 你要。然后将其用于您的项目。