【iOS】SDK 的封装
做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、我们先以一个简单的例子来做介绍,在工程中新建类并添加如下方法
屏幕快照 2017-06-08 上午11.01.14.png3、接下来我们需要设置要暴露出来的头文件。如图,进入 Build Phases ,点击左上角的加号,创建 Headers
屏幕快照 2017-06-08 上午10.53.47.png4、点击 Headers 左下角的加号,将头文件导入到 Project 中,如图
屏幕快照 2017-06-12 下午4.44.38.png5、随后选择需要暴露出来的头文件,将其从 Project 拖拽到 Public 当中。这里需要注意的是,我们想要隐藏的头文件需要放到 Project 当中,而不是 Private 当中。
屏幕快照 2017-06-08 上午10.58.03.png6、点击 Target,选取 Edit Scheme ,如图
屏幕快照 2017-06-08 上午11.55.52.png7、选择Run,将 Build Configuration 改为 Release,如图
屏幕快照 2017-06-08 上午11.19.06.png8、选择 PROJECT 中的 Info,更改 iOS Deployment Target 为 7.0 或其他版本,如图
屏幕快照 2017-06-08 上午11.24.14.png9、至此,我们工程的基本设置已经做完了,下面开始生成.a
文件。分别选择模拟器和Generic iOS Device,command+R 各运行一次,生成两个.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 ,如图
屏幕快照 2017-06-12 下午2.54.42.png4、至此,我们工程的基本设置已经做完了,下面开始生成.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 模板创建新工程,如图
屏幕快照 2017-06-12 下午4.06.47.png2、Targets -> Build Settings里搜索hidp,将属性设成 NO 即可,如图
屏幕快照 2017-06-12 下午4.12.41.png3、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时,为了避免日后使用时类名、静态变量名等重复,通常需要在命名时加上前缀。