公司有个需求需要把自己的项目打包成库,以供合作方使用,查找了些资料,花了些时间研究了下,晚上整理一下笔记。
1 . 创建一个 workspace
项目
a) 在桌面创建一文件夹 ChangeViewColorSDK
b) 打开 Xcode 创建一个 workspace
,放在 ChangeViewColorSDK
文件夹下
image.png
image.png
2. 创建SDK项目
a) 打开刚才创建的 workspace
文件,创建 project
(或者使用快捷键 command + shift + n
)。
image.png
选择第一个是framework库.png
image.png
image.png
3. 创建 Demo
a) 创建 project
(或者使用快捷键 command + shift + n
)。
image.png
image.png
当SDK工程和Demo工程创建完成之后的项目目录.png
4. 静态库封装和打包。
a) 新建一个 View 继承 UIView,重写init方法改变View的背景色。
image.pngb) 设置 Build Setting
,将 Build Active Architecture only
设置为 NO
。
image.png
image.png
c) 关于在 Build Setting
下设置 Architectures 增加 armv7s
的问题。
模拟器32位处理器测试需要i386架构,
模拟器64位处理器测试需要x86_64架构,
真机32位处理器需要armv7,或者armv7s架构,
真机64位处理器需要 arm64架构。
iOS 10.3公测版发布:封杀32位应用;
所以这里说的是大家可以根据自己的应用需要,和兼容iOS的最低版本根据需要添加 armv7s 。
image.png
d) 设置 Headers
,将要公开的头文件拖到 Public
下,要隐藏的放到 Private
或 Project
下,隐藏的头文件不能被引用。
image.png
e) 在 ChangeViewColorSDK.h
中引入刚才创建的View的 .h
文件。
image.png
f) 创建一个 Aggregare
image.png
image.png
g) 嵌入脚本,选中刚刚创建的 Aggregare
,然后选中 Build Phases
,点击左边的 +
号,选择 New Run Script Phases
image.png
h) 下面把这段脚本复制进去(这段脚本是用于模拟器framework和真机framework合并并导出,格式不要错,格式错编译不通过)
if [ "${ACTION}" = "build" ]
then
#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"
#build之后的文件夹路径
build_DIR=${SRCROOT}/build
echo "build_DIR=${build_DIR}"
#真机build生成的.framework文件路径
DEVICE_DIR_A=${build_DIR}/Release-iphoneos/${PROJECT_NAME}.framework
echo "DEVICE_DIR_A=${DEVICE_DIR_A}"
#模拟器build生成的.framework文件路径
SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/${PROJECT_NAME}.framework
echo "SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"
#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}
echo "INSTALL_DIR=${INSTALL_DIR}"
#目标.framework路径
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/${PROJECT_NAME}.framework
echo "INSTALL_DIR_A=${INSTALL_DIR_A}"
#判断build文件夹是否存在,存在则删除
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi
#判断目标文件夹是否存在,存在则删除该文件夹
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
#创建目标文件夹 -p会创建中间目录
mkdir -p "${INSTALL_DIR}"
#build之前clean一下
xcodebuild -target ${target_Name} clean
#模拟器build
xcodebuild -target ${target_Name} -configuration Release -sdk iphonesimulator
#真机build
xcodebuild -target ${target_Name} -configuration Release -sdk iphoneos
cp -R "${DEVICE_DIR_A}" "${INSTALL_DIR_A}"
#由于xcode12之后模拟器编译的SDK也有Arm64,不删除就合并的话会报”have the same architectures (arm64) and can't be in the same fat output file“的错误
#xcode12,模拟器删除Arm64架构
lipo "${SIMULATOR_DIR_A}/${PROJECT_NAME}" -remove arm64 -output "${SIMULATOR_DIR_A}/${PROJECT_NAME}"
#合成模拟器和真机.framework包
lipo -create "${DEVICE_DIR_A}/${PROJECT_NAME}" "${SIMULATOR_DIR_A}/${PROJECT_NAME}" -output "${INSTALL_DIR_A}/${PROJECT_NAME}"
#打开目标文件夹
open "${INSTALL_DIR}"
fi
image.png
i) 最后编译,command + B
,编译成功之后在 products
下右键 Show in finder
找到 framework
,这就是打包好的库,可以拷贝出来使用。
- 这里要说的是当选择模拟器进行编译的时候,当前
framework
库只能使用与模拟器,当选择Generic iOS Deveice
进行编译的时候则当前framework
仅适用于真机运行。
j) 打包好的SDK的使用(导入项目中相应的 framework
,模拟器打包的 framework
则仅适用于模拟器运行)
image.png
k) 关于刚刚加入的脚本是自动打包合并 framework
。 scheme
选择刚刚创建的脚本。运行,如果成功会弹出打包好的库文件。
运行成功之后的库文件可以使用下边的命令验证是否为合并之后的库文件.png
i) 注意:
- 如果 SDK 有用到 Category,注意项目设置 Other Linker Flags 添加 -ObjC 。
-ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中
-all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。
-force_load:所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。
5. SDK 调试。
a) 修改下面 SDK 中的代码,运行 demo 就是修改后的效果,然后就可以在这个工程里面开发调试 SDK 了,例如修改库中 View
的背景色。
image.png
6. 关于合并模拟器和真机的 framework。
-
也许很多人感觉模拟器的库文件和真机的库文件有点麻烦,怎么才能把两个合并成一个文件?也是可以的,这里只做参考,可以根据自己实际需要选择是否要合并SDK。
a) 找到刚才打包好的真机和模拟器的
framework
,以真机包为例。
// 输入命令查看 framework 信息
$ lipo -info 真机 framework 文件路径
image.png
b) 合并真机和模拟器的 framework
。
// 输入命令合并真机和模拟器 framework
$ lipo -create 真机framework文件路径 模拟器framework路径 -output 真机framework文件路径
image.png
- 为了验证是否合并成功,输入
a
中的命令查看framework
的信息。
一般我们打包的静态库中常常会使用一些图片等资源文件,那么就会有这么一种情况就是我们的库中的图片文件和项目中的文件名称一样导致冲突。这时候就可以使用.bundle文件来解决这个问题,关于打包. bundle资源包。
以上就是关于 framework
库的打包,真机库和模拟器库的合并。
特此笔记。
网友评论