【iOS】如何封装代码,打包静态库(包含第三方库)
第一步:
工程文件.png创建个静态库工程
创建静态库.png
删除库引用.png注意如果有使用到第三方的SDK的,再手动导入时,勾选复制,但记住一定要在下图标注的删除:
然后接下来就是,按照第三方文档集成第三库,直至没有报错!并可以在自己需要封装的代码中可以使用!
第二步:
点击加号,添加headers标签,并将需要公开的头文件放到Pubilc中:如下图
添加headers.png
需要封装什么代码只需要工程里面添加.h.m进行实现,跟我们平时完成项目一样的,把需要暴露的.h加入到下图就行!
如果你需要打成静态库的文件中有拓展(Categort),那么这个地方other
-ObjC.png
Linker Flags要写入** -ObjC **,如图
第三步
开始打包静态库
Paste_Image.png
设置为NO,为了使我们打出来的库在,真机和模拟器上都能编译,
(切记,在真机和任意选择一个模拟器 使用Command + B 都进行预编译一次!)
合并.a
右键显示在finder,
查找.a.png
如图,有真机和模拟器的.a文件
真机模拟器.png
使用终端命令合并.a ,请根据实际操作路径输入下列终端命令!
lipo -create 真机的.a的路径 模拟器的.a的路径 -output 输出位置路径.a
输出的.a 和暴露的.h拿出来,拷贝到同一个一个文件夹,并将使用到的第三方库一起在新的工程中进行导入,和根据文档配置,至此我们的包含第三方库的静态库就算制作成功了,不足之处,敬请指导!
=================== 库的介绍 ==================
一. 静态库和动态库的详细介绍
我们平时的工程中或多或少都要引入第三方的SDK,就算你没有引入第三方的,至少引用过系统的Framework吧?其实这些SDK和Framework都属于库,库又分为静态库和动态库,我们平时导入的第三方SDK有的是Framework,有的是.a,到底哪些是动态库,哪些是静态库呢?下面分别介绍静态库、动态库,Framework和.a以及.dylib/.tbd区别
一. 静态库与动态库
首先要解释一下什么是库,库(Library)其实就是一段编译好的二进制代码,加上头文件就可以供别人使用,一般会有两种情况要用到库:
某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件。
对于某些不会进行大的改动的代码,比方说很多大公司常用且很少变动的模块都会编译成库,这样做的好处一是可以节省编译时间,二来对于代码的管理也非常方便。
因为库是已经编译好的二进制文件了,编译的时候只需要link一下,既然提到了link那就有不同的形式了,静态和动态,与之相对应的就是静态库和动态库。
1. 静态库
平时我们用的第三方SDK基本上都是静态库,静态库的几个特点:
在App项目编译的时候会被拷贝一份编译到目标程序中,相当于将静态库嵌入了,所以得到的App二进制文件会变大。
在使用的时候,需要手动导入静态库所依赖的其他类库。(比如说某个SDK中使用到了CoreMotion.framework,在使用的时候需要手动导入。有的SDK需要link十几个系统库,这个时候非常恶心,只能一个一个手动加,这是静态库一个很大的不便之处。)
导入静态库的应用可以减少对外界的依赖,如果导入的是第三方动态库,动态库找不到的话应用就会崩掉,例如Linux上经常出现的lib not found。
静态库很大的一个优点是减少耦合性,因为静态库中是不可以包含其他静态库的,使用的时候要另外导入它的依赖库,最大限度的保证了每一个静态库都是独立的,不会重复引用。
2. 动态库
这个是我们最常用的一类库,使用频率最高的UIKit.framework和Fundation.framework都属于动态库,所有.dylib和.tbd结尾的都属于动态库。动态库的几个特点:
平时使用的系统库都放在iOS系统中,在你打包应用程序的时候这些库不会拷贝到你的程序中,当需要使用的时候会动态从iOS系统中加载它们,因为这个原因,动态库也被称作共享库。编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。
这些库是所有应用公用的,换一种说法就是节省了应用安装包的体积,这是区别静态库很重要的一个特点,因为静态库使用一次就要拷贝一次,非常浪费资源。
动态库在制作的时候可以直接包含静态库,也能自动link所需要的依赖库。
使用动态库的时候不需要再次link依赖库,即导即用,这个就厉害了。唯一需要注意的是在导入自己制作的动态库时,需要在Embedded Binaries中导入,不然会报错:image not found。此时这个动态库会跟静态库一样被拷贝到目标程序中进行编译,苹果又把这种Framework叫做Embedded Framework
关于动态库要搞清楚一点,我们自己制作的动态库与系统动态库的区别,我们自己制作的动态库引入App项目的时候需要embed进项目,也就是要拷贝到目标程序中,这就有点不像动态库的特性了,苹果这么做也是考虑安全问题吧!至于能不能正常上架,我也不清楚,查了大量资料都是抄来抄去没说清楚,我猜测是不能上架的,因为一般的第三方SDK也都是静态库的形式,我猜测一个重要原因是iOS的应用本来就是运行在沙盒里面的,不同应用之间不能共享代码,同时动态下载代码苹果肯定也是明令禁止的,所以动态库也就失去意义了。当然可能还有其他因素,欢迎交流学习!
二. Framework、.a、.dylib/.tbd
1. Framework
Framework的英文释意是框架,主要由Headers、binary文件、.bundle这三部分构成,除此之外还有Info.plist和Modules,后两者主要记录Framework的版本之类的信息,一般都会删掉,不做讨论
Headers包含我们在制作Framework的时候暴露的头文件,所有被暴露的.h都放在这里。
binary文件整个Framework的核心,所有代码都被编译成了这样一坨二进制文件,这里要注意的是添加的依赖库不会被编译进来,用的时候还需要重新link其他依赖库。
.bundle资源文件都打包放在这里。在制作Framework的时候不可以把图片直接放在项目中,否则制作好之后图片是一张一张的出现在项目中非常乱,需要新建一个bundle将图片放进去,这里的bundle提供整个SDK的图片资源。注意:图片放进bundle之后不可以用[UIImage ImageWithName:]
读取图片。要先找到bundle包再拿图片。
这里要纠正一个误区
很多人认为系统的Framework就是动态库,我们自己制作的Framework就是静态库。
其实Framework既可以是静态库也可以是动态库,这取决于编译成的Mach-O(就是那个二进制文件)是动态库还是静态库,Framework本质上并不是一个库,它是苹果为了方便开发者提供了一种库的打包方式,Framework会将Mach-O文件、头文件和资源包全都包含进来,不需要你再手动整理,我们也可以通过Xcode来制作framework动态库使用。所以总结: Framework是库的打包形式,既可以是动态库也是静态库。
2. .a静态库
这类静态库与Framework基本类似,不同的是在打包成.a文件的同时,还需要提供头文件,使用时相较于Framework比较麻烦,(例如微信支付SDK使用的是.a,不同的是支付宝SDK是以framework的形式打包的)。.a这样打包不够方便,而Framework编译完成暴露的头文件都已经放好了。
3. .dylib/.tbd 动态库
这类动态库我们也经常用,基本上都是系统提供的,一般不能自己制作,就算你通过其他方式制作使用,也肯定不能上架的,这里没什么好讲的。
二. Framework(静态库+动态库)的制作
动态库与静态库的制作流程基本一样,包括头文件的暴露等,唯一不同的是Mach-O文件的编译形式。本节将介绍Xcode制作Framework的过程,本次制作的Framework静态库依赖其他第三方静态库(Framework和.a)。