做SDK开发很久了,一直没有时间写一篇关于封装SDK的文章,今天抽出时间来做一下这方面的整理。
在介绍封装SDK的方法之前,我们先来了解一下iOS里的库。
1、什么是库
库是一种共享程序代码的方式。库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。在开发过程中,一些核心技术或者常用框架,出于安全性和稳定性的考虑,不想被外界知道和修改核心代码,所以会把核心代码打包成库,只暴露出头文件以供使用。
2、库的分类
iOS里的库分为静态库和动态库。
静态库
静态库在链接时会被完整地拷贝进可执行文件中,被多次使用就会有多份冗余拷贝。静态库有两种形式:.a
和 .framework
。 .a
是一个纯二进制文件,不能直接使用,要有头文件配合。而 .framework
中除了有二进制文件之外还包含头文件等各种资源,可以直接使用。
动态库
动态库在链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。动态库也有两种形式:.framework
和 .tbd
( Xcode 7 之前为 .dylib
) 。在 iOS 8 之前,苹果不允许第三方框架使用动态方式加载。 iOS 8 之后开始允许开发者有条件地创建和使用动态框架,这种框架叫做 Cocoa Touch Framework。虽然同样是动态框架,但是和系统 .framework
不同,哪怕我们封装的 .framework
是动态的,最后也还是要拷贝到 App 中去使用。也就是说,不同的 App 就算使用了同样的 .framework
,但还是会有多份的框架被分别签名,打包和加载。因为沙盒会去验证动态库的签名,如果是动态从服务器更新的动态库,是签名不了的,所以想要通过这种方法实现应用插件化、软件版本实时模块升级估计很难实现。
3、库的封装
.a 静态库的封装
1、创建一个 .a
静态库项目,如下图所示:
2、我们先以一个简单的例子来做介绍,在工程中新建类并添加如下方法
3、接下来我们需要设置要暴露出来的头文件。如图,进入 Build Phases ,点击左上角的加号,创建 Headers
4、点击 Headers 左下角的加号,将头文件导入到 Project 中,如图
5、随后选择需要暴露出来的头文件,将其从 Project 拖拽到 Public 当中。这里需要注意的是,我们想要隐藏的头文件需要放到 Project 当中,而不是 Private 当中。
6、点击 Target,选取 Edit Scheme ,如图
7、选择Run,将 Build Configuration 改为 Release,如图
8、选择 PROJECT 中的 Info,更改 iOS Deployment Target 为 7.0 或其他版本,如图
9、至此,我们工程的基本设置已经做完了,下面开始生成.a
文件。分别选择模拟器和Generic iOS Device,command+B 各编译一次,生成两个.a
文件,选择 Products 中的 .a
文件,右键 Show in Finder ,如图
10、为了保证我们的静态库能够在真机和模拟器上同时运行,我们需要对两个.a
文件进行合成。打开终端,输入如下指令
11、做完以上操作之后合成的.a
文件就出现在我们的桌面上了。至于需要暴露的头文件也可以在上边的文件夹中轻松找到,如图
12、.a
文件再加上.h
文件,就组成了一个完整的静态库。当然,在制作SDK的过程中,我们也可能会用到资源文件,通常都是制作.bundle
来解决,这个我们会在接下来讲。
.framework 静态库的封装
1、创建一个 .framework
静态库项目,如下图所示:
2、接下来的步骤与.a
静态库封装中的步骤 2 ~ 8 相同。
3、在 Targets -> Build Setting 里搜索 Dynamic ,将 Mach-O Type 设置为为 Static Library ,如图
4、至此,我们工程的基本设置已经做完了,下面开始生成.framework
文件。分别选择模拟器和Generic iOS Device,command+R 各运行一次,生成两个.framework
文件,选择 Products 中的 .framework
文件,右键 Show in Finder ,如图
5、为了保证我们的静态库能够在真机和模拟器上同时运行,我们需要对两个.framework
文件进行合成。这里需要注意的是,我们要合成的仅仅是.framework
中的二进制文件。我们可以先拷贝出一份.framework
放在桌面,以保存最终合并的二进制文件。随后打开终端,输入如下指令
6、至此,.framework
静态库就制作完成了。
.framework 动态库的封装
1、.framework
动态库的封装与.framework
静态库的封装基本相同,唯一的不同点在于步骤3,需要将 Mach-O Type 设置为 Static Library。
2、动态库的加载与静态库有些不同之处,我们需要在 Targets -> General -> Embedded Binaries 中将动态库嵌入到工程中才可以正常使用。
.bundle 资源束的制作
.bundle
,就是资源文件包。我们将许多图片、XIB、文本文件组织在一起,打包成一个Bundle文件。方便在其他项目中引用包内的资源。Bundle是静态的,也就是说,我们包含到包中的资源文件作为一个资源包是不参加项目编译的。也就意味着,bundle包中不能包含可执行的文件。它仅仅是作为资源,被解析成为特定的2进制数据。
.bundle
的制作步骤如下:
1、在 macOS 中选择 Bundle 模板创建新工程,如图
2、Targets -> Build Settings里搜索hidp,将属性设成 NO 即可,如图
3、command+B 编译后,选择 Products 中的 .bundle
文件,右键 Show in Finder ,如图
4、至此,我们就完成了Bundle 文件的制作。
4、封装SDK注意点
1、当我们封装的SDK中含有category时,在使用时要特别注意,需要在 Target -> Build Setting -> Linking -> Other Linker Flags 中添加 -ObjC 、-all_load 或 -force_load 标识。
2、封装SDK时,为了避免日后使用时类名、静态变量名等重复,通常需要在命名时加上前缀。