iOS 将自己的内容打包成Framework

  • 摘要:Framework最近需要将公司项目中的公共代码给提取出来,打包成Framework来使用,这样可以使得我们的公共代码易于分享,并且可以在多个工程中易于复用,而且将这些代码给别人使用时,可以隐藏实现细节,控制公开的头文件,下面分享一下打包成Framework的步骤。
  • 1.打开xcode创建framework
  • iOS 将自己的内容打包成Framework

2.因为要打包所需的文件,所以这里我自己创建了一个测试类,在实际的打包过程中,直接把需要打包的所有文件拖到该工程中即可。 

iOS 将自己的内容打包成Framework

3. 添加公开头文件 

选中 Target ,选择 Build Phases - Headers ,可以看出有三个选项,分别是 Public 、Private 、Project ,把需要公开给别人的 .h 文件拖到 Public 中,把不想公开的,即为隐藏的 .h 文件拖到 Project 中。

iOS 将自己的内容打包成Framework

4.完成上述步骤之后,在默认生成的 .h 文件中,我的是 hello.h ,把所有需要暴露的 .h 文件都用 #import <hello/openViewController.h>引入,记住一定要将所有需要暴露的 .h 文件都引入,也就是上面 Headers - Public 中加的所有 .h 文件,不然编译后生成的 .framework 在引用的时候会有警告。

iOS 将自己的内容打包成Framework

5. 更改设置参数 

选中 Target ,选择 Build Settings ,修改以下 Linking 中的几个设置。 将 Build Active Architecture Only 设置为 NO 。

iOS 将自己的内容打包成Framework


iOS 将自己的内容打包成Framework

6.工程打包成 Framework 

6.1. 创建 Aggregate 

新建一个 Target ,选择 Cross-platform - Aggregate ,名字随便起一个。

 iOS 将自己的内容打包成Framework

6.2选中新建的 Target ,点击 Build Pharas 中的 + ,选择 New Run Script Phase 。

iOS 将自己的内容打包成Framework

6.3点开 Run Script ,添加以下的脚本代码。 

# Sets the target folders and the final framework product. 
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME 
# 例如: FMK_NAME = "MyFramework" 
FMK_NAME=${PROJECT_NAME} 
# Install dir will be the final output to the framework. 
# The following line create it in the root folder of the current project. 
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework 
# Working dir will be deleted after the framework creation. 
WRK_DIR=build 
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework 
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework 
# -configuration ${CONFIGURATION} 
# Clean and Building both architectures. 
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build 
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build 
# Cleaning the oldest. 
if [ -d "${INSTALL_DIR}" ] 
then 
rm -rf "${INSTALL_DIR}" 
fi 
mkdir -p "${INSTALL_DIR}" 
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/" 
# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product. 
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}" 
rm -r "${WRK_DIR}" 
open "${INSTALL_DIR}" 

iOS 将自己的内容打包成Framework

6.4. 编译所有文件 

按照下图将编译的 Target 选择为刚才创建的 Aggregate , Device 选择为 Generic iOS Device ,然后按下 Command + B 开始编译。iOS 将自己的内容打包成Framework

6.5编译完成后会自动弹出已经创建完成的 Framework 包内容,最终打包完的 .framework 会在项目下的 Products 文件夹下。 iOS 将自己的内容打包成Framework



7. 测试打包完的 Framework 
新建一个测试工程 TestDemo ,将打包完的 TestFramework.framework 拖到工程中,测试一下刚才创建的 TestClass 类,可以看到信息打印出来了,测试成功。iOS 将自己的内容打包成Framework

iOS 将自己的内容打包成Framework

iOS 将自己的内容打包成Framework

如果使用打包完的 Framework 有出现崩溃的情况,可以考虑在项目 Other linker flags 中加入一些参数,下面介绍三个常用参数: 
-ObjC:加了这个参数后,链接器就会把静态库中所有的 Objective-C 类和分类都加载到最后的可执行文件中。 
-all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到 ld: duplicate symbol 错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到 -ObjC 失效的情况下使用 -force_load 参数。 
-force_load:所做的事情跟 -all_load 其实是一样的,但是 -force_load 需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。

如何将自己资源打包为bundle:打包bundle