此系列文章均整理、精简自pluto-y大神的博客,感谢大神~

#一、随便聊聊
年前到现在大部分时间都在整理和抽象之前项目的代码,那酸爽,真是够够的。主要是公司产品是做定制版的本需求,而前期对定制的内容需求太不明确了,导致领导先说前期就用不同代码管理不同的定制版。最后我们这里中英文版就有6套代码,导致管理起来特别不方便。而之前在写代码的时候完整体的框架是写好的,可是在细节上的封装来说就差太远了。导致整个代码的耦合度太高了,这段时间抽象起来相当痛苦。所以现在就开始对项目进行模块化管理,保证各个模块之前可以重用和替换,并且之后根据客户需求只加载用户需求的模块。

最后我决定采用Cocoapods对各个模块进行管理,采用公有库和私有库共存的状态。然后在添加配置文件以及一些Runtime的机制进行管理。 而对于一个公司的核心代码来说,当然不可能采用公开的形似来进行管理对已的框架。所以在Cocoapods中,还有另一种方式提供给公司内部管理进行管理代码,那就是私有库(Private Pods)。

##二、知识点

1. 创建私有仓库
	a. 不管是私有库还是公有库,关注点都在于Podspec文件的书写。
	b. 在创建私有库之前,需要先创建一个仓库(Spec)存放私有库。 
		i. 先创建一个私有仓库 - pod repo add '仓库名' '仓库地址'  
		ii. 通过cd ~/.cocoapods/repos这个目录里面检查是否创建好具体的私有库
	c. 写代码->写Podspec文件了->检查项目和Podspec文件->打tag
	d. 提交项目到自己的仓库里面 - pod repo push '私有仓库名' 项目名.podspec
2. 私有仓库的其他操作
	a. 删除私有仓库:pod repo remove [name]。
	b. 在普通项目中如何使用私有仓库,可以在Podfile里面的开头声明所有包含的仓库名,即利用source参数
3. 开发模式
	a. 意义:不用每次更新私有库都提交tag + pod update更新
	b. 方法:将引用路径修改成本地路径 -> 将Podfile中的pod '库名', :path => '本地路径'
	c. 通常的修改代码中不需要执行pod update,但是如果修改了目录结构(添加、删除或者移动文件文件)、Podspec文件配置的话,最好是打个tag运行一下pod update
	d. pod 'iOS-Echarts', :path => '../iOS-Echarts'
4. 使用私有库两种情况
	a. 正常使用私有库:在Podfile中引用私有库
		i. # Podfile文件
                # 公有仓库
                source 'https://github.com/CocoaPods/Specs.git'  
                # 私有仓库
                source 'https://192.168.0.100/TestPrivate/Specs.git'  
	b. 私有库中使用私有库:在Podspec文件中依赖(dependency)私有库
		i. Podspec文件中没有指明所依赖私有仓库的存放地址
		ii. 需要在验证和上传私有库的时候进行指明,命令:
			1) (可以采用开发者模式方法)pod lib lint 项目名.podspec --sources=https://github.com/CocoaPods/Specs.git,192.168.0.100:Plutoy/Specs.git
			2) (不能采用开发者模式,只能通过打tag之后才能进行使用方法)pod repo push --source=https://github.com/CocoaPods/Specs.git,192.168.0.100:Plutoy/Specs.git

##三、CocoaPods用在模块化管理

关于模块化管理,其实对于一个人力资源特别紧缺的公司来说还是挺有必要的。特别是遇到我这种需要定制版本的管理的公司,如果对于模块管理比较妥善的情况下,其实会为公司的人力资源和时间资源节省非常多的时间。

本人确实有亲身经历,在经历了6个版本,可是核心功能相同的情况下,公司之前采用的是6套代码进行管理。从而产生了很多不必要的重复工作和人力资源的浪费,因此特别有必要对项目的各个模块化进行拆分和管理。

其实也有小伙伴跟我提过说用framework或者.a等框架形式不就好了么?可是对于framework要进行版本管理以及多地方引用的管理情况下,很多情况下都会忘记了当前大的包对应的是仓库管理里面的哪个版本,因为有可能我们经常打tag的时候,小修改还是会用同一个版本号,所以会出现很多误差性的情况。而通过Cocoapods进行管理的话,就可以追踪到仓库管理里面的具体提交号、版本号、branches等情况。

对于我们公司来说,由于有定制版的存在,所以我们基本上是封了很多小的私有库,如蓝牙模块,访问服务器模块,一些视图、第三登陆分享等。当然也有对于大的核心版本封装,如果整个App的核心功能的分装,当然通过模块也有可能分为秤的模块、手环的模块、血糖计血压仪的模块等等。

当然这些大的模块中也都会引用小的模块然后最后根据Cocoapods配置以及plist文件进行扫描之后产生需要对应模块的版本,最后在通过代码扫描机制进行初始化项目。

当然项目中还用到一些“黑魔法”和Runtime的一些知识,有兴趣的小伙伴可以去看看资料,或者联系我。

不过在进行模块化管理的过程中需要注意一些点:

• 模块中不能出现循环依赖,即A依赖B,B依赖C,C依赖A的情况
• 如果一个子模块引用,需要填写完整的模块名,如在Core模块下面有Controller模块下面有个Setting模块,并且整个库的名字为TestProj的话,则依赖的名称需要这样写s.dependency 'TestProj/Core/Controller/Setting'的形式
• 如果出现模块特别多的情况下,在验证过程中,竟然采用--subspec=子模块名来进行一个模块一个模块验证,特别是对于如果只改动了一个模块的情况下,这里所说的字模块名也和上面一点异样,要填写完整的模块名
• 在写私有库的过程中,竟然不用prefix header的形式,因为在分子模块的过程中很容易出现忘记引用header而出现的Error
• 最后一点,多google,少百度,太多资料只能通过google查到,而在百度里面完全查不到 ##写在最后   到此为止,关于Cocoapods的使用,从使用者到最后的自己开发自己的库的教程就到此为止了。里面包含了很多内容,有些内容可能写的不够清楚,不过大体上这个也是说说我使用Cocoapods的教程,如果中间出现什么疑问或者错误,欢迎小伙伴留言或者联系我。 当然除了Cocoapods外,还有另外两个Carthage以及Swift Package Manager依赖管理工具,有兴趣的小伙伴可以研究一下。这两个管理工具都是针对动态库,所以一般都是在iOS8以上,对于要兼容iOS7以上的小伙伴(包括我)来说是一个不利的地方,但是Carthage的使用比Cocoapods方便。你只需要保证你的代码能编译通过即可。至于Swif Package Manage本人没用过,不敢多说什么。不过竟然学了这么多的内容,希望小伙伴们还是可以学以致用,即使不能用在公司的项目,也可以考虑用在为开源的事业尽一份力的程度上,至少让中国的开发者能在开源的方面不落后其他国家的小伙伴。 >此系列文章均整理、精简自[pluto-y大神](http://www.pluto-y.com/cocoapods-getting-stared/)的博客