模块化实践以及私有库相关介绍

 

简单介绍一下这次模块化实践以及所遇到的一些问题

楔子

任何一个工程都会经历从无到有,从小到大的过程,这其中会遇到种种问题。譬如,工程成长到一定的阶段,势必想要进行模块化,一来可以让自己的工程看起来层次更清晰,不同模块独立性也更好,同时等工程到了一定规模,想要对外开放,实现开放平台,那么模块化就是必经之路。本文选择的模块化是cocoapods私有库+spec,同样也提供了二进制化方案,方便2中方式,一种是源码形式,一直是framework形式。 本文简洁明了,适合已近对cocoapods有一定基础的读者,如何安装,怎样使用,这边就不赘述了,直接进入主题,一切都是从简单实用为出发点,都是本人自己实践过的。

Podspec以及一些常用命令

pod lib lint –allow-warnings –verbose

链接验证命令,即验证路径,语法等是否合法,可达。 当然还可以加一些参数,比如:

–source “git@xxx.yyy.net,https://zzz.com”

有些库的验证可能用到外部的url资源,需要添加

–use-libraries

有静态库lint时

由于一般来说,我们制作私有库,还有可能希望编译快一点,所以就有了binary的要求,这里简单介绍下pod package这个命令, 这个命令是根据写好的podspec文件,生成framework或者library,节约编译时间,也可以做成看不见源码的私有库。

pod package yyyy.podspec –force –no-mangle –exclude-deps

--exclude-deps这个参数,是我试验了很久,老是报a的symbols和b的symbols重复定义的错,试出来的选项,很有用,可以注意下。

具体参数可以通过pod package –help查阅。 还有,默认是framework,如果需要library,则使用--library

一些小技巧

更新方式

  • 较快的方式更新(有可能会有spec更新,所以repo update需要,如果没有spec的更新,可以直接install,如果怕忘记,可以进行repo update操作,单个速度很快): pod repo update ~/.cocoapods/repos/xxx(xxx是你们本地私有库的spec)(只更新特定的repo) pod install

  • 稍微慢一点的方式: 直接pod update (因为pod1.1.1版本后,update命令会执行repo update命令,不过不是针对具体repo去更新的)

有时候删除了tag,修改了代码然后重新添加了跟之前一样的tag的时候,如果pod spec lint可能会报错: 因为它验证的时候会重远程下载下来新的代码,然后进行验证,但是如果~/Library/Caches/CocoaPods/里有对应tag的源代码缓存的话,是不会再重新下载覆盖这个缓存的,所以在验证的时候还是验证的老代码,导致可能的报错。 所以一般最好是不要删除tag,而要更新tag。如果要删除tag的话需要去删除~/Library/Caches/CocoaPods/里的缓存

pod install和pod update的注意点

这个cocoapods官网说的很清楚,我就不赘述了,请各位看官移步 https://guides.cocoapods.org/using/pod-install-vs-update.html

subspec的使用

这是个好东西,必须要单独来说,我们去看cocoapods官方源去看,可以发现很多podspec有这个subspec,比如SDWebimage,AFNetwork等等。这个是何方神圣呢?其实,可以简单理解,它就是一个分割器,当然这其中有一个默认值,以SDWebImage为例

    s.default_subspec = 'Core'

    s.subspec 'Core' do |core|
    core.source_files = 'SDWebImage/{NS,SD,UI}*.{h,m}'
    core.exclude_files = 'SDWebImage/UIImage+WebP.{h,m}', 'SDWebImage/SDWebImageWebPCoder.{h,m}'
    core.tvos.exclude_files = 'SDWebImage/MKAnnotationView+WebCache.*'
  end

其中default表明通常的写法,pod SDWebimage会获取到的代码,当然了,它还有其他的subspec,如GIF,WebP等,如果需要使用,需要pod SDWebimage/GIF就可以了。 subspec是可以指定依赖关系的,比如

s.subspec 'GIF' do |gif|
    gif.ios.deployment_target = '7.0'
    gif.source_files = 'SDWebImage/FLAnimatedImage/*.{h,m}'
    gif.dependency 'SDWebImage/Core'
    gif.dependency 'FLAnimatedImage', '~> 1.0'
    gif.xcconfig = {
      'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/FLAnimatedImage/FLAnimatedImage'
    }
  end

GIF模块依赖core模块,所以,即使你只写pod SDWebimage/GIF也依然会拉取到相应的代码的。

子模块还可以为不同的资源(plist,配置表,图片等)服务,也就是说,你可以定义一些子模块,source是一样的,但是resource不同,这样可以根据不同写法,选择不同的样式,目前我自己做的私有库也采用了这一套,还挺方便的。

参考

  • https://imfong.com/post/Talk-iOS-Library-Binary-Practice
  • https://www.jianshu.com/p/5338bc626eaf