iOS制作Framework依赖第三方Framework
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS制作Framework依赖第三方Framework相关的知识,希望对你有一定的参考价值。
参考技术A 记录下把第三方Framework打包到自己的SDK过程中遇到的问题。一般情况下我们不需要把第三方SDK打包到自己的SDK里,如果自己的SDK里引用了第三方SDK,主工程里也同时依赖自己的SDK和第三方SDK即可。有一些特殊情况,我们需要给客户出SDK,但是我们自己SDK又引用了合作方的SDK,这时候如果不把合作方的SDK打包到我们自己的SDK里则需要提供给客户多个SDK。1.File -> New -> Project -> ios -> Framework 创建Framework;
2.TARGETS -> Build Settings 设置SDK配置;
(1)搜索Mach,Mach-O Type设置为Static Library;
(2)搜索Dead Code Stripping 设置为NO;
(3)Build Libraries for Distribution 设置为Yes,swift 5.0后ABI稳定,设置为Yes后当swift语言更新后不影响输出SDK的使用,如不设置此项,swift语言版本更新后主工程会报错;
3.SDK业务层处理,这里假设我们的SDK依赖Bugly;
4.创建主测试工程,拖动MyLib到测试工程中,MyApp测试工程可以调用MySDK.start()方法;
上述编译SDK过程没有把Bugly打进SDK里,主工程需要依赖Bugly。
经过测试Embed方式打包的静态SDK,可以把Bugly.framework包含进去,但是主工程还是需要引用Bugly.framework,我们可以从自己的SDK里面添加Bugly.framework的依赖。
TARGETS -> Build Settings,Mach-O Type设置为Dynamic Library
经过测试Embed方式打包的动态SDK,可以把Bugly.framework包含进去,而且主工程不需要再添加Bugly.framework引用;
Embed方式编译的依赖第三方Framework的静态SDK,主工程在使用时也需要添加第三方Framework依赖,可以从输出的SDK下Framework目录直接添加第三方Framework依赖。
Embed方式编译的依赖第三方Framework的动态SDK,主工程在使用时不需要添加第三方Framework依赖,系统会自动添加引用链接。
使用非嵌入方式编译的依赖第三方Framework的静态SDK,需要给客户提供自己输出的SDK及自己SDK里引用的第三方的SDK。
iOS 打包.framework(包括第三方图片xibplist文件)详细步骤及需要注意的地方
https://www.cnblogs.com/yk123/p/9340268.html
最近在研究如何制作自己的.framework,在网上看了好多文章,但是写的都不是很全,里面也不包括资源图片、第三方(如Masonry,AFN)和plist文件,所以只能自己动手了。下面详细介绍一下如何生带有第三方、图片、plist文件的.framework
一、制作.framework
1.首先,我们新建工程,选择Coco Touch Framework
![技术图片](https://image.cha138.com/20210820/f1bbc85ddc0e4e4195ef42eaa311b1cd.jpg)
2.使用CocoaPods导入Masonry和SVProgressHUD(这里以Masonry和SVProgressHUD为例),打开WQFramework.xcworkspace,可以看到我们的第三方已导入成功,接下来就要进行一些配置了。(以上都是废话,下面的才是重点!)
![技术图片](https://image.cha138.com/20210820/06a81867df7e42f8bb94337f162e5e82.jpg)
3.我们先创建两个类,WQClass :NSObject和WQView : UIView(我这里只是demo,在实际中可以把自己想要打包的文件都拉进来),我们在WQClass和WQView的.h中分别写一个初始化方法,并在.m中实现方法。这里我们在WQView中导入我要使用的第三方,并使用他们,我创建了两个UIImageView,并给其中一个附上了图片。并且我拉进来一个plist文件,读取并打印了它(这里是方便我们看一下打包framework时,图片和plist文件直接使用会出现什么问题)
![技术图片](https://image.cha138.com/20210820/22b6b99012b0434fb81b3ef12177f73b.jpg)
![技术图片](https://image.cha138.com/20210820/cb1e4f9c81eb4378b28a8f2ad5cba095.jpg)
4.更改参数配置:
(1)选中 Target ,选择 Build Settings ,在 Architectures 下增加 armv7s 。
![技术图片](https://image.cha138.com/20210820/81c8d39a6e0c40059c65a64af31a3baf.jpg)
(2)Build Active Architecture Only修改为NO,否则生成的静态库就只支持当前选择设备的架构。
![技术图片](https://image.cha138.com/20210820/63b4e5a939694cf3bfc4721712602376.jpg)
(3)在搜索栏搜索 Mach-O Type ,将 Mach-O Type修改为 Static Library(静态库)类型。
![技术图片](https://image.cha138.com/20210820/6d555fee7f1e42dca9234a963755d4b6.jpg)
(4)选中 Target ,选择 Build Phases - Headers ,可以看出有三个选项,分别是 Public 、Private 、Project ,把需要公开给别人的 .h 文件拖到 Public 中,把不想公开的,即为隐藏的 .h 文件拖到 Project 中。
![技术图片](https://image.cha138.com/20210820/45a1bc370f4b4158a1382ab79a8140f7.jpg)
5.完成上述步骤之后,在默认生成的.h文件中,我的是WQFramework.h,把所有需要暴露的.h文件都用#import 引入,记住一定要将所有需要暴露的.h文件都引入,也就是上面Headers-Public中加的所有.h文件,不然编译后生成的.framework在引用的时候会有警告。
![技术图片](https://image.cha138.com/20210820/134dcb083f594f99b50179bd4080835b.jpg)
6.打包framework:分为真机和模拟器,这两个生成的framework是不一样的。这里只进行生成真机framework,个人感觉生成模拟器的.framework并没什么卵用。(如果说你需要生成一个既可以真机使用又可以模拟器使用的,那就分别生成,最后在合并在一起)。按照下图将编译的 Device 选择为真机 ,然后按下 Command + B 开始编译,编译成功后右键 Products 文件夹下的 .framework 文件,点击 Show in Finder。
![技术图片](https://image.cha138.com/20210820/ad603b6a50a4443ab5954fd91bb9042f.jpg)
![技术图片](https://image.cha138.com/20210820/8567c661d6ad439d9ad0e3c6fdc9adc4.jpg)
![技术图片](https://image.cha138.com/20210820/f405348f33a44d7d97bce3fdd9ce4f37.jpg)
重点:我这时我编译会报错,把Build Active Architecture Only修改为YES,编译就会成功,这时再切换为NO编译,还是会成功。经过总结Build Active Architecture Only为YES或者NO,导出framework后都正常使用,亲测!
7.测试打包完成的.framework,把生成的.framework导入测试项目json中,测试framework中的WQClass类和WQView类。(注意:我们在framework中使用了Masonry和SVP,所以在测试项目json中,我们需要使用cocoapods导入这两个第三方,不然会报错!)
![技术图片](https://image.cha138.com/20210820/4decb35773d6405482d83b70e1f54574.jpg)
![技术图片](https://image.cha138.com/20210820/306ba7c72c8f416f8f79f7185e285e1f.jpg)
可以看到,我们制作的.framework成功了!可是别高兴太早,我们在framework中使用的图片并没有显示,读取的plist文件打印也为空!接下来我们就需要处理framework中的图片和plist文件了。
二、制作bundle
1.新建项目,选择macOS ---> Bundle
![技术图片](https://image.cha138.com/20210820/235828a3fb16489fa402e3f42197da7c.jpg)
2.因为Bundle默认是macOS系统的,所以我们要修改他的属性。
![技术图片](https://image.cha138.com/20210820/7665f3d43fcf4f72ac3f769d4aab7772.jpg)
3.修改Build Setting中COMBINE_HIDPI_IMAGES属性为NO。否则Bundle图片格式就会为tiff格式。
![技术图片](https://image.cha138.com/20210820/4606d6c6c2ea49399f15924c10e6f19d.jpg)
4.作为资源包只需要编译就好,不需要安装相关配置,设置Skip Install的值为YES,同时删除Installation Directory的键值
![技术图片](https://image.cha138.com/20210820/15c27636da5041dbb128040e5a3243d0.jpg)
5.把图片拉进Bundle中,选择真机模式,command + B,右键Show in Finder,可以看到我们生成的Bundle文件。
![技术图片](https://image.cha138.com/20210820/d27238aeabf9458ca290bbc53d37b804.jpg)
6.把Bundle文件导入到我们的framework中,我们用到图片的时候,就取Bundle中的图片来用。使用时注意,具体用法??
![技术图片](https://image.cha138.com/20210820/433a9ef6dce848fea697668a8a2cdb38.jpg)
7.command + B,把新生成的framework重新导入demo中,并把Bundle也导入demo,运行demo。(注意:如果demo中不导入Bundle,图片是不会显示出来的)
![技术图片](https://image.cha138.com/20210820/d9f97e01897c47ac9d8abbf7b7450bd1.jpg)
这时可以看到,图片可以显示出来了,说明我们的Bundle制作成功了,图片的问题我们解决了,下面要解决plist文件了。其实根据我们Bundle的制作过程,不难想到plist文件的使用原理。
三、plist文件的使用
1.其实plist文件的使用原理和图片一样,只不过图片需要制作Bundle,而plist文件不需要。把plist文件拖进framework中,重新编译framework,把重新编译的framework和plist文件都拖到demo中,这样我们就可以打印出plist文件了。
![技术图片](https://image.cha138.com/20210820/f4daaa7e24e14ad69ab6df5a2a36a234.jpg)
![技术图片](https://image.cha138.com/20210820/bd695d8bb4f843ab9e4c2ad6b43593a7.jpg)
四、xib
如果你要打包的framework中包含xib,我们在初始化xib时要这样写??,带上你framework的名字。然后在我们的·测试demo中的Copy Bundle Resources中添加这个framework。
![技术图片](https://image.cha138.com/20210820/ab1c5bd2e7e54b8d9de6dc39018692c5.jpg)
![技术图片](https://image.cha138.com/20210820/7364298752e04c96902dc8489b14028e.jpg)
![技术图片](https://image.cha138.com/20210820/63d674b2b4fe4bacb600b1a19676a953.jpg)
错误原因很好理解就是说在nib里找不到图片,我觉得这肯定是一个低级错误,是路径的配置问题,所以就把问题定位到初始化nib文件:
单单从代码看找不出问题,单经过尝试后一下方法是可以的:
注意??:
1. -ObjC:加了这个参数后,链接器就会把静态库中所有的 Objective-C 类和分类都加载到最后的可执行文件中。
2. -all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到 ld: duplicate symbol 错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到 -ObjC 失效的情况下使用 -force_load 参数。
3. -force_load:所做的事情跟 -all_load 其实是一样的,但是 -force_load 需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。
![技术图片](https://image.cha138.com/20210820/1f145825aa6144e198ffb3b2aa10025f.jpg)
出现错误!
今天在引入一个静态framework库时候,编译遇到了“Can‘t map file, errno=22 file ‘xxx‘ for architecture arm64(armv7)”问题!
起因是我在主项目中,build setting-----》other linker flags 中-force_load了该framework库
1,找到引用项目的build setting----》build active architecture only ----》设置成NO
我原本就是no,所以结果没啥用
2,最后尝试了这一种办法
将主项目中other linker flages 中的-force_load "XXX.framework"改成“-force_load "XXX.framework/XXX”其中XXX是静态库名。
以上是关于iOS制作Framework依赖第三方Framework的主要内容,如果未能解决你的问题,请参考以下文章
iOS 打包.framework(包括第三方图片xibplist文件)详细步骤及需要注意的地方
Uncaught InvalidArgumentException: Please provide a valid cache path. in /apps/vendor/laravel/framew