我有一个我已经创建的xcode框架项目,我可以将其编译成myframework.framework
文件。编译之后,我将这个框架拖到我的应用程序的Frameworks项目文件夹中,然后利用框架中的类,我将适当的import
语句添加到任何需要它的类中;这允许我的应用程序成功编译,并引用框架中定义的类。为了让应用程序部署成功到我的设备,我还将我的自定义框架添加到"嵌入式二进制文件"我的目标部分。完成所有这些后,我可以从xcode构建我的应用程序并在我的设备上运行它。
当我尝试存档应用商店的应用程序时出现问题。当我尝试这样做时,我得到了大量的编译器错误,其中xcode表示无法找到我的自定义框架中定义的任何类的声明。
如何在xcode中设置存档以便正确引用和嵌入我的自定义框架?
答案 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操作系统中。但是,对于自定义框架或第三方框架,您必须将它们嵌入到应用程序包中,这样当您在设备上部署应用程序时,应用程序才能真正找到它。这就是为什么如果您使用Cocoapods
或Carthage
,他们都有额外的构建阶段将框架复制到应用程序包。 (对于Cocoapods
,它被称为嵌入窗格框架,对于Carthage
,它是一个运行copy-frameworks
脚本的操作。所以对于您的自定义框架,您将使用现有的Embed Frameworks
构建阶段或创建新运行脚本阶段将框架复制到您的应用包。
- 关于2017-05-17的更新 -
对于嵌入框架的东西,我最近发现了另一个重要的事实:
您可以使用file PATH/TO/Framework
检查框架是静态的还是动态的。查看this stackoverflow question了解详情。
只需要将动态框架嵌入到应用程序中。其中包括Carthage
和Cocoapods
创建的内容。如果您在构建项目后打开应用程序包,那么包含所有嵌入式框架的Frameworks
文件夹,您将找到由Carthage和Cocoapods创建的文件夹以及您指定的框架。在嵌入框架阶段。
所以现在您可能想知道那些静态框架在哪里?如果应用程序包中缺少它,我们如何仍然使用它?你是对的。它们位于捆绑包中,但不在Frameworks
文件夹中。它们已合并到您的应用程序的可执行文件中。如果检查可执行文件的大小,那么每次向目标添加静态框架时都会意识到,它会增加。
静态框架不必嵌入(只需链接它们),它就像.swift
或.xib
文件,将被编译到您的可执行文件中。
然后,在您使用任何框架之前还有一个步骤。目标内的Framework Search Paths
构建设置。同样,如果您查看Carthage
或Cocoapods
,它们都会在此设置中添加额外的路径。这告诉Xcode(或底层编译器)在哪里找到这些链接的或嵌入式框架。
因此,每当您想要使用框架时,请务必考虑上述设置并完成所有设置。我已经使用这种方法一段时间了,当我遇到任何链接问题时会感到更自信。
最后,Apple有一篇非常重要的文章,您应该阅读https://developer.apple.com/library/content/technotes/tn2435/_index.html
答案 2 :(得分:0)
答案 3 :(得分:0)
希望这对您有帮助