iOS8之后,iOS有了App Extesion特性,而且Swift也诞生了。由于iOS主App需要和Extension共享代码,Swift语言机制也需要动态库,于是苹果后来提出了Embedded Framework,这种动态库允许APP和APP Extension共享代码,但是这份动态库的生命被限定在一个APP进程内。简单点可以理解为被阉割的动态库。
但是这种动态库(Embedded Framework) 和系统的 UIKit.Framework 还是有很大区别,传统的动态库是给多个进程用的,而这里的动态库(Embedded Framework)是给单个进程里面多个可执行文件用的。系统的 Framework 不需要拷贝到目标程序中,我们自己做出来的 动态库(Embedded Framework) 哪怕是动态的,最后也还是要拷贝到 App 中(App 和 Extension 的 Bundle 是共享的)。所以苹果没有直接把这种Embedded Framework称作动态库而是叫Embedded Framework。
iOS中的Embedded Framework可以理解为独立的没有main函数的可执行文件。
静态库可以简单理解为一堆目标文件(.o/.obj)的打包体(并非二进制文件),而动态库可以简单理解为 一个没有main函数的可执行文件。
动态库的制作过程:
1.点击File-New-Project
2.修改工程文件配置
build setting ->搜索 Mach-O Type -> 修改 Mach-O Type ->Dynamic Library。
3.File->New->Target->Cross-platform->Aggregate,取名为CommonDylib。这个Target的目的是为了把模拟器和真机对应版本的动态库合并成一个。
4.在其Target Dependencies中`添加SDKDemo。
5.点击下图中的 + 号,选择run script,添加如下脚本
if [ "${ACTION}" = "build" ]
then
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"
lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"
#open "${DEVICE_DIR}"
#open "${SRCROOT}/Products"
fi
6.把你制作的SDKDemoBundle.bundle加载到工程中。把你的SDKDemoViewController.m,SDKDemoViewController.h加载到工程中。在项目的SDKDemo.h 导入你需要暴露出来的头文件。
代码如下:
#import <UIKit/UIKit.h>
//! Project version number for SDKDemo.
FOUNDATION_EXPORT double SDKDemoVersionNumber;
//! Project version string for SDKDemo.
FOUNDATION_EXPORT const unsigned char SDKDemoVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <SDKDemo/PublicHeader.h>
#import<SDKDemo/SDKDemoViewController.h>
7.设置公开头文件。点击下图的加号可以加入公开文件。若你是把原来的目录拖入工程的需要自己加文件。强力建议直接把文件或文件夹拷贝到工程目录下直接加载,那么他们的头文件自动加入到工程头文件中(Header下)。.m文件自动加入到Compile Sources下。
8 加入头文件后这个样子都在工程目录下需要,需要把它移动到公开头文件区域
9.编译SDK
分别将sdk在模拟器(随便选一款模拟器)和Generic iOS Device下编译 (选择该target,command + B)。这会编译生成2个SDK,一个适用于模拟器,一个适用于真机。可以看到Products下的SDKDemo.framework由红变黑。
Debug-iphoneos文件夹下的是真器使用的动态库文件,Debug-iphonesimulator文件夹下的是模拟器使用的动态库文件。
然后我们选择切换Target为CommonDylib,编译,在工程目录下生成Fat版本的动态库。
10.若需要生成发布的动态库,需要修改环境设置Release,在Generic iOS Device下编译 (选择该target,command + B)生成发布版本的动态库。