前期准备
1 安装 cocoapods
先安装好 cocoapods
团队可统一使用1.5.3版本。
如果下载 master
索引库 速度很慢,可以直接从同事那里复制过来(我们已经做了第三方库私有库化,master
的索引库也可以不下载)
2 安装 cocoapods - svn
插件
cocoapods
默认的 spec repo
,是基于 git
的,可创建基于 git
管理的私有库 spec repo
。而我们使用的是 svn
,所以还需要安装 cocoapods - svn
插件
终端输入 sudo gem install cocoapods-repo-svn
3 添加私有库索引
在终端里输入(在任意文件下目录下)pod repo-svn add my-svn-repo [http://svn-repo-url](http://svn-repo-url/)
比如添加我们的XX索引库就是 pod repo-svn add XXSpecs xxx
如果提示没有权限就看下,在 svn
能不能看到这个路径。如果没有就申请下。
如果遇到有权限但是私有库索引还是无法下载,可能是终端中还未输入账号密码,svo co xxx
会提示你输入密码的
输入defaults write com.apple.finder AppleShowAllFiles YES
打开隐藏文件
重启 finder
后可以看到效果
这个时候你会发现文件夹路径 你的用户名/cocoapods/repos
下多了一个 XXSpecs
。
这个就是我们私有库的索引,我们之所以能在podfile写上版本号就能找到对应的代码地址和文件组织结构方式,就是因为索引库里存放了版本号对应的 podspec
(podspec
待会具体分析,我们自己要写)
接下来就可以创建自己的私有库了
1 私有库标准模板还是裸奔?
开始具体操作流程前先理解一下库是如何被 cocoapods
找到的。其实必要的只有一个文件那就是 podspec
,他包含了所有必要和不必要的信息。
而像 cocoapods master
索引库里数以万计的索引查找,作者自己写了 Molinillo
算法,提高效率。
在做一些私有库的时候,如果不需要单独跑起来的,比如基础库等,就没必要选择创建一个 私有库标准模板。
一个 classes
文件夹存放 类文件,一个 assets
文件夹存放 资源即可 再加一个 podsepc
即可。
业务组件必须创建标准模板!(方便验证和单独Debug,后期壳工程拆的好的话,似乎也没必要)
2创建标准模板步骤
1 cd
到想要存放的目录下 执行 pod lib create XXEGOImageLoading
(库的名字) 这一步会下载标准模板(如果遇到网络卡主,就复制一个吧,正常情况应该是分分钟)
显示6个问题:
1. 在哪个平台上使用(iOS)
2. 你想使用哪种语言(ObjC)
3. 是否需要一个Demo应用(Yes)
4. 选择一个测试框架(None)
5. 是否基于View测试(No)
6. 类的前缀(XX)
回答完6个问题他会自动执行pod install命令创建项目并生成依赖,项目结构如下:
XXEGOImageLoading
├── Example #demo APP
│ ├── XXEGOImageLoading
│ ├── XXEGOImageLoading.xcodeproj
│ ├── XXEGOImageLoading.xcworkspace
│ ├── Podfile #demo APP 的依赖描述文件
│ ├── Podfile.lock
│ ├── Pods #demo APP 的依赖文件
│ └── Tests
├── LICENSE #开源协议 默认MIT
├── XXEGOImageLoading #组件的目录
│ ├── Assets #资源文件
│ └── Classes #类文件
├── XXEGOImageLoading.podspec #第三步要创建的podspec文件
2 编辑 podspec
编辑 podspec
前先说明一下各个参数的意义
Pod::Spec.new do |s|
#名称
s.name = "XXXXX"
#版本号
s.version = "0.1.0"
#简短介绍
s.summary = "Just Testing."
#详细介绍
s.description = <<-DESC
XXXXX description
DESC
#主页,这里要填写可以访问到的地址,不然验证不通过
s.homepage = "http://www.baidu.com"
#截图
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
#开源协议
s.license = 'MIT'
#作者信息
s.author = { 'feiyuchao' => 'xxx' }
s.source = { :svn => 'XXX)', :tag => s.version.to_s }
#多媒体介绍地址
# s.social_media_url = 'https://twitter.com/<twitter_username>'
#支持的平台及版本
s.platform = :ios, '8.0'
#是否使用ARC,如果指定具体文件,则具体的问题使用ARC
s.requires_arc = true
#代码源文件地址,**/*表示Classes目录及其子目录下所有文件,如果有多个目录下则用逗号分开,如果需要在项目中分组显示,这里也要做相应的设置
s.source_files = 'XXEGOImageLoading/Classes/**/*'
#资源文件地址
s.resource_bundles = {
'XXEGOImageLoading' => ['XXEGOImageLoading/Assets/*.{storyboard,xib,xcassets,json,imageset,png}'] 这里不加 png 加**等的话就是寻找所有文件
}
#公开头文件地址
s.public_header_files = 'XXEGOImageLoading/Classes/**/*.h'
#该pod依赖的系统framework,多个用逗号隔开
s.frameworks = 'UIKit','CoreGraphics'
#该pod依赖的系统library,多个用逗号隔开
s.libraries = 'iconv','sqlite3','stdc++','z'
#第三方.a文件
s.vendored_libraries = 'XXEGOImageLoading/Classes/ThirdParty/*.{a}'
#第三方frameworks文件
s.vendored_frameworks = ['XXEGOImageLoading/Classes/xx.framework',
'XXEGOImageLoading/Classes/xxx.framework']
#依赖关系,该项目所依赖的其他库,如果有多个需要填写多个s.dependency
s.dependency 'AFNetworking', '~> 2.3'
end
3 推送索引
1 关联到具体的svn
地址。在 git
里 是git remote add origin xxx svn
我一般是先建仓库,再下载下来。svn 仓库创建的时候需要分文件夹branch tags trunk
2 推送成功之后打好 tag
,tag
要保证和podfile
里的 tag
一致
3 再回到本地,cd
到 文件夹 包含 podsepc
的目录下,执行以下命令:$ pod repo-svn push XXSpecs xxx.podspec --allow-warnings --sources=xxx--use-libraries --verbose
sources
是表示需要寻找的依赖从哪里寻找,如果没有依赖,pod repo-svn push XXSpecs xxx.podspec
即可
这一步如果执行完毕没有 Error,那么可以进入~/.cocoapods/repos/XXSpecs
中,可以看到xxx
组件了,并且内部有一个 0.1.0
文件夹,内部有一个xxx.podspec
文件。
有问题的话,请确认本地是否已添加 XXSpecs
私有库,并且你在该私有库下拥有足够的权限
如果私有库里面引用静态库会导致验证是无法通过的,报错 include of non-modular header inside framework module ··· [-Werror,-Wnon-modular-include-in-framework-module]
,加上--use-libraries
。
如果验证失败,请查找 - error
或者 - note
查看失败信息,进行相应更改。
如果你是第一次初始化项目,应该是没有 Error 的,毕竟你的组件中啥都没有。
空的私有库创建结束之后如何组织文件
标准的私有库如下
所需要做的工作就是在相应的Pods/Developemnt Pods/
组件 /Classes
下编码,
就是向Development Pods
文件夹中添加库文件和资源,
将编写的组件相关的class
放入xxx/Classes
中、资源图片文件放入xxx/Assets
中,
并配置podspec
文件,然后进入Example
文件夹执行pod install
命令,
再打开项目工程可以看到,刚刚添加的组件已经在Pods
子工程下Development Pods/xxx
中了。
如果遇到.a mrc
或者framework
的可以参考对 podspec
的解析
其他的问题会有2个
1 资源文件如何被添加,如何被获取。
1 spec.resources = ["Images/*.png", "Sounds/*"]
可以看到很多第三方库都是这么写,我做私有库本地化的时候也是这么写的。但是不建议。 这些资源文件在 build
时会被直接拷贝到 client target
的 mainBundle
里。带来了一个问题,
那就是 client target
的资源和各种pod
所带来的资源都在同一bundle
的同一层目录下,很容易产生命名冲突。
例如,我的 app
里有张按钮图片叫 “button.png"
,而你的 pod
里也有张图片叫 "button.png"
,拷贝资源时,我很担心 pod
里的文件会不会把我 app
里的同名文件给覆盖掉?即使没覆盖掉,程序运行时到底用哪张?很显然,我们不希望上述事情发生。
2 s.resource_bundles = { 'xxx' => ['xxx/Assets/**/*'] }
最好是这么写
这种方法利用 framework
的命名空间,有效防止了资源冲突。pod
会把添加的资源文件编译成 bundle
,使用方法是先拿到最外面的 bundle
,然后再去找下面指定名字 的 bundle
对象,再搜索具体资源,其中需要注意的方法[NSBundle bundleForClass:<#ClassFromPodspec#>]
返回某个 class
对应的 bundle
对象。具体的:
具体可以参考这篇文章 链接
2 拆库的发现有的文件不在自己的模块里,在其他模块里。这个时候严格来讲应该是找人一起评估下,这个共有的文件是否需要下沉到下一层,依赖他。
或者直接复制一个文件,改一下前缀名。可以自己把握。一般建议商量一下,由负责基础组件的同事去下沉。
实际开发中可能会出现负责基础组件的同事在忙其他业务开发,不能及时帮忙拆库。
子pods
一般业务组件用不到。暂时不写了。
私有库开发流程如何开发才能高效
私有库的版本控制肯定是用 tag
来做的。和 master
的做法一样,版本号和实际代码分开,版本号有专门的一个库,就是我们的索引库 XXSpecs
。
但是实际开发中,测试提一个bug
,我们就要去更新一个tag
吗,工作量很大(推代码 - 打tag
- 推索引)。
cocoapods
肯定早就想到了,解决了我们的困境。
pods
有 三种写法,第一种和第二种一样,我们可以直接在developpods
修改代码。
第三种写定具体的版本号,一般上线前 才去打死 tag
号。最后一定要用 版本号代替第一种和第二种,不然私有库就没有意义,也无法做好版本控制。
其他开发流程和 之前git flow
流一样操作。
pod 'XXErrorLayer', :path => '/Users/feiyuchao/Desktop/XXErrorLayer/trunk' 指向本地,只要文件里有 podspec 即可,出现在 developpods 里。
pod 'XXErrorLayer', :svn => xxx') 指向远程,其他和第一种一样
pod 'XXErrorLayer', "1.0.0" 出现在锁住的 pods 里。
添加第三方库的策略
原则上不要随意添加私有库,尤其一个功能不要添加多个库。
如果我们用的是git 直接fork 一下,修改一下podspec即可。 我们现在可能需要自己编写spec,和组织文件,再推到我们的 svn 地址上。
不知道有没有更好的方案,重复操作的事情脚本化(不会写)
有些踩过的坑
1 如果在更新工程pod
后,发现 组件版本 和 最新发布 的组件版本 一致,但是代码貌似不是最新的代码,那么可能是由于 cocoaPods
的本地缓存导致的问题,可以执行如下代码清除缓存:
pod cache clean --all
2 头文件<xxx/xxx>
无法找到。但是“” 能找到,那是因为没有分子pods
3 验证无法通过怎么办? 如果明明是没有问题的,但是各种客观原因无法推上去,可以采取野路子,索引库也是一个库,直接手动推送你的podsepc
上去即可
4 .a文件找不到。由于我们的svn
自动忽略了.a
文件,改一下忽略文件即可
5 如果 run
主工程的时候提示链接错误, 有可能是主工程存在着你私有库的文件,还没有删除
6 如果 pod install
提示索引找不到该私有库,可能是别的同事推了索引库新的版本,但是你还没更新,执行 pod repo-svn update
如果不行,你也可以自己手动加的
7 如果推的时候提示- ERROR | [iOS] unknown: Encountered an unknown error (/usr/bin/xcrun simctl list -j devices
,可能是 xcode
路径不正确
sudo xcode-select -s /Applications/xcode.app
搞定 后面是你的xcode
路径 有可能 xcode
不在程序里,我的就是在桌面
还能做些什么
1 不知道 svn
能不能分读写权限, 原则上 每个库的实际负责人员也有写的权利。 比如我想修改一下别人负责的库,应该提PR
,而不是直接papapa
改了
2 Pods
文件 加入忽略文件,因为clone
下来之后 会有一些问题。 需要删除 pods
重新pod install
3 理想的平滑二进制化
4 更好结合CI
5 更好的路由方案
6 资源命名规范化 看到有的图片就叫show@2x
..容易覆盖