Cocoopods,项目库的管理工具!
cocoapods官方文档
1.cocoapods的常规操作
首先我们需要学习一些cocoapods的常规操作
例如:
1.1.CocoaPods通过ruby命令进行安装下载,所以先在终端中查看是否装有ruby环境 ruby -v
1.2.安装/卸载 sudo gem install cocoapods/gem uninstall cocoapods
1.3.安装没反应,查看ruby源的所在地址: gem sources -l
切换源:gem sources --remove rubygems.org/
增加墙内源:gem sources -a rubygems-china.oss.aliyuncs.com
1.4.安装成功,通过pod search AFNetworking,搜索验证是否cocoapods有效
如果一直不能用,那么需要更新pod,下载依赖包 :pod setup
如果还是出现红色错误,那么就要进行gem版本更新:sudo gem update --system
1.5.查看cocoapods文件信息 pod repo list,如果现实0 repos,那么重新执行更新 pod setup
2.cocoapods的下载原理和集成原理
2.1.cocoapods的 下载原理:
-
当使用 cocoapods 导入第三方库时,cocoapods先是根据 库的地址 git => github.com/AFNetworkin… 找到对应的 git 仓库
-
然后根据对应的版本号 tag => ‘1.0.0’ 定位到对应的 tag 提交(如果没有指定版本号则下载最新的)
-
然后在这次提交中找到后缀为 .podspec 的文件
-
找到 .podspec 文件后先要验证 s.name 是否与 Podfile文件中一致,如果不一致报错没找到
-
验证成功后,会根据 .podspec 中的 s.source_files 找到需要导入的代码文件,并通过其他数据找到对应的配置文件和资源文件
-
最后,将其下载到本地项目中
2.2.cocoapods的集成原理
当所有的依赖库都下载完成后
-
Cocoapods 会将所有的依赖库都放到另一个名为 Pods的项目中
-
然后让主项目依赖 Pods项目这样源码管理工作都从主项目转移到了 Pods 项目,
-
Pods项目 最终会编译成一个名为 libPods.a 的文件,主项目只需要依赖这个 .a文件即可
-
对于资源文件, Cocoapods 提供了一个名为 Pods-resources.sh 的 bash 脚本,该脚本在 每次项目编译的时候都会被执行,将 Pods 依赖库的各种资源文件复制到目标目录中
-
Cocoapods 还通过一个名为 Pods.xcconfig 的文件在编译时设置所有的依赖和参数
3.cocoapods的源码解析
DSL:领域特定语言
myseven.github.io/2018-04-25/…
cocoapods源码调试
pod install 步骤,具体的源码解析
4.Cocoapods模块化开发组件化管理
因此在创建私有仓库,要创建两个仓库。一个仓库管理.podspec文件。一个管理代码文件。.podspec文件就是代码文件的索引。
4.1创建代码仓库
1.首先创建一个远程的spec索引仓库
2.将私有的远程索引仓库copy到本地
pod repo add 本地仓库名称 + 远程索引库地址
3.pod repo list 本地用到的索引仓库
删除 pod repo remove [name]
制作本地库
4.pod lib create [组件库名称]
5.删除replaceMe,然后添加需要的类文件
6.pod install
7.编辑.podpsec文件(特别要注意的是source源就是私有库创建的远程路径)
8.校验本地索引文件 cd 到&&.podspec所在的文件夹,执行
pod lib lint —allow-warnings
9.把本地组建代码推到前端,并打个标签,这里的tag一定要和之前的版本号统一
git add .
git commit -m '第一次提交'
git remote add origin 组件代码库地址
git push origin master
//注意tag和podspec文件里的s.version一样
git tag "0.1.0"
git push —-tags
10.接下来就是验证podspec索引文件是否正确或者直接本地远程一起验证。
pod lib lint HJSwiftExtension.podspec --verbose --allow-warnings(pod spec lint --verbose --allow-warnings )
11.将HJSwiftExtension.podspec索引文件到我们最早创建的私有远程索引库 HJSwiftExtension.podspec 命令如下
要cd 到当前组件库的文件下
格式:pod repo push <本地索引库> <索引文件名> - -verbose - -allow-warnings
12.至此私有库的创建完成,接下来就是在项目中引用即可。
问题1: The repo MySpecs
at ../../../.cocoapods/repos/MySpecs
is not clean
回答: cd ~/.cocoapods/repos/MySpecs,git clean -f
5.注意一些场景使用
1.除了post_install这个钩子函数,cocoapods中还有一个钩子函数,pre_install,这个钩子函数在允许我们在pod库已经下载了,但是还没有安装之前做一些事情,而post_install这个钩子函数允许我们在项目被写入硬盘之前做一些事情。
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['COMPILER_INDEX_STORE_ENABLE'] = "NO"
end
end
end
6.组件化混编的头文件引用问题
在组件化管理项目工程的时候,需要考虑到当模块中存在swift+OC的混编模式的时候,framework或者.a就会存在头文件引用的问题,这个时候我们就需要创建 ****** *framework.modulemap文件,然后设置我们需要调用的OC文件访问权限为public,然后设置一下Module Map File文件路径,那么这个framework就能够编译成功,并且在外部工程中可以使用对外开放的类,当然,如果希望该类是私有的,那么就将module 改为private module;
同一个framework中swift想要调用oc的话,需要将该文件引入其umbrella-header.h中,还需要将该target的DEFINES_MODULE配置改为YES即可
module.modulemap文件
umbrella: 项目主头文件,主要是要暴露出去的类
6.1.Framework 创建Modules
当我们创建framework工程的时候,build framework以后Xcode会自动给你生成一个包含umbrella头文件的module 文件;格式突下
framework module SwiftFramework {
umbrella header "SwiftFramework.h"
export *
module * { export * }
}
2.Static Library创建Modules
默认情况下,Xcode不会为Static Library创建Modules;为了支持Modules,你需要手动创建;
在Static Library中,我们需要创建一个Umbrella 头文件,然后将我们需要对外暴露的头文件在这个Umbrella中暴露:
使用workspace引用项目framework,将类暴露出来最重要!
组件化混编的头文件引用问题:
重点!!!www.jianshu.com/p/4dab60055…
疑问:这个文件创建出来后即为swift调用oc文件的header文件,可以将工程内用到的所有oc文件引入其中,编译器则会将引入的所有oc文件进行module化,即在swift的角度而言,引入的每个oc文件即为引入的每个module,这样做的目的也主要是为了提高编译速度,在编译的过程中,编译过的module会放入一个编译好的modules数据结构中,当有重复的module引入时,dyld会将先前编译好的module进行link产生最终的mach-o文件
如果要在oc中引入swift文件的话,需要引入在编译时才能决议的文件可在Targets -> Build Settings中看到该文件名ProjectName-Swift.h,该文件会在编译的过程中产生,其主要的目的是为了将swift转译为oc,中间会有一层hash加密用于防止在LLVM dyld进行link时出现符号表冲突。其中的内容可在编译一次后看到,该文件中声明了工程内引入的所有swift文件,其中编译器在其中的实现过程就不一一阐述了
In -s 【源文件或目录]】【目标文件或目录】
软链接和硬链接
7.自定义pod插入shell脚本!
工程中安装自己的pod私有库之后,如果需要执行相应的操作,比如说在编译之后上传dsym文件,在运行之前修改项目资源等,我们会通过shell或者ruby脚本去执行。