一个“旧”工程的第三方依赖升级之路
其实,这个项目也就顶多一个月没有持续开发和维护,当时的开发环境是xcode7.2搭配iOS9.2的系统,到昨天的结果就是:在Xcode7.3.1下各种编译不通过。
首先简单介绍一下该项目的情况:工程通过Cocoapods 引入了FMDB,SDWebImage,MJRefresh还有其他一些第三方的lib,然后工程内部又放了第三方供应商提供的一个动态链接库(暂且叫它A.framework),在Xcode7.2 和Cocoapods v0.38.2下据说正常使用,但到我的Xcode7.3.1 + Cocoapods V1.0.1下,就报A.framework错误。
开始排查错误,第一步,记得前段时间遇到一个问题,是在Cocoapods V1.0.1下pod install后造成的编译错误,所以,先降级Cocoapods,降级到 V0.38.2:
$ gem uninstall cocoapods -v 1.0.1
$ gem install cocoapods -v 0.38.2
(注:这块如果你安装了多个版本的Cocoapods的话,可以通过 pod _0.38.2_ install
的方式使用特定版本进行install。)
完成后,使用pod install后还是错误,所以猜测应该跟A.framework本身有关了,然后就是与供应商联系,他们确认A.framework在Xcode7.3上有编译错误问题并且已经更新了framework,然后提供了新的下载链接,我就顺着链接去下载了,等到解压后,彻底傻眼了,大版本变化已经好几个版本,接口API都变了,而且A.framework又依赖了FMDB.framework,并且在新的UI GUI里边,竟然直接放置了一份SDWebImage和MJRefresh的.a静态库,修改的过程逐渐变得有意思起来。
引入新框架后的工程结构当把新的framework和它的GUI文件拷贝(虽然这种copy的方法很不爽,但是供应商没有Cocoapods的repo,只能呵呵了)到工程编译后,必然出现文件冲突的问题,下来需要一步步解决。
首先,查看代码后,去掉了A.framework GUI中的MJRefresh的lib,因为在我们的业务场景中,A的GUI没有下拉刷新的需求,直接去掉后,删除了GUI中下拉刷新逻辑。
然后,因为A中的FMDB.framework是必须的,所以,只能从Pods这边动手,删除了FMDB的声明,在代码中,将Native代码中的FMDB使用的地方的头文件修改成动态链接库的引用形式,即:#import <FMDB/FMDatabase.h>
,这样就解决了FMDB的问题。
最后,SDWebImage的情况类似,但是因为在A的GUI文件中,本来就是以代码形式集成,所以,直接删除了Pods中的SDWebimage即可。
整个修改后的工程文件变成了下边的依赖:
调整后的工程结构交叉依赖的问题,就被解决掉了,工程也能被运行起来。
但是问题并没完,在工程启动后,直接crash,log信息只有 XXX/XXXX/XXX/A.framework Reason: image not found
, google后是因为A.framework同时集成了OC和Swift两种动态链接库,需要在工程的Build Settings设置属性Embedded Content Contains Swift Code = YES
,至此,工程就妥妥的运行起来。
整个过程现在来讲比较清晰,但是刚开始接手代码时,没有准备思路的时候,就像苍蝇一样乱撞,等到真正排查出来问题的时候,思路才逐渐清晰起来,希望这篇文档对大家能够起到一些开阔思路的作用,还记得之前说道的A.framework GUI和API更新的问题么,我要欢快的去埋这个坑去了~