前言
作为一名iOS工程师,如果在平常开发的时候,对于页面数据交互的开发已经进入到了一个瓶颈的情况下,就需要进入一个高层次的研究了,比如第三方库的开发,底层性能优化。而组件化的开发也是针对一些大型项目分工开发的重要途径,而cocoapods私有库的搭建也是其中尤为重要的一个环节,而下面就主要介绍一下cocoapods私有库搭建的介绍。(基于码云Gitee),前提需要电脑安装好cocoapods,否则以下操作不能进行,具体如何安装可参考度娘
一、私有库仓库的搭建
1、在码云上面,新建一个仓库,如下图所示:
2、创建仓库的
创建成功之后,该仓库不需要做另外处理,因为相当于是作为一个文件夹的方式存在,来存放第三方库的json文件的地方。具体如下所示:
3、在本地添加自己搭建的私有库。可通过一下命令来新增私有库
pod repo add `specFileName(给spec仓库在本地的命名)` `spec(仓库的地址)`
示例:
pod repo add MZouSpec https://gitee.com/xxxx/MZouSpec.git
然后把远程库的数据拉取到本地来:
Cloning spec repo `MZouSpec ` from `https://gitee.com/xxxx/MZouSpec.git`
然后可以在电脑中的pod的路径可以看到刚刚搭建的私有库仓库路径的文件夹,和master同一个级别的目录下:
~/.cocoapods/repos
二、私有库的搭建
1、在码云创建一个私有库。(相当于第三方库)
创建成功之后,可以通过控制台来clone该库,或者通过sourceTree把这个库clone下来。
2、第三方库创建与配置
当库已经拉取成功之后,然后打开控制台,通过命令进入该库的路径下:
cd /Users/xxxx/Desktop/MZouPrivatieLibrary/MZouCategries
然后通过pod的命令来创建一个第三方库和demo:
pod lib create #{库的名称}
示例:
pod lib create MZouLibraries
然后会出现一些列信息的填报,如下
What platform do you want to use?? [ iOS / macOS ]
> iOS
What language do you want to use?? [ Swift / ObjC ]
> ObjC
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> No
What is your class prefix?
> MZou
填完以上的信息后,则初始化一个第三方库成功,xcode会自动打开该第三方库的demo的
然后在项目中修改podspec文件,该文件是配置第三方库重要的文件:
具体的podspec介绍如下:
s.name = "TestCode" # 项目名称
s.version = "0.0.1" # 版本号 与 你仓库的 标签号 对应
s.license = { :type => "MIT", :file => "LICENSE" } # 开源许可证
s.summary = "desc" # 项目简介
s.homepage = "http://git.com/xxx" # 仓库的主页
s.source = { :git => "http://git.com/xxx.git", :branch => 'master', :tag => "#{s.version}" } #你的仓库地址,不能用SSH地址
s.source_files = "TestCode/*.{h,m}" # 代码的位置
s.requires_arc = true # 是否启用ARC
s.platform = :ios, "7.0" #平台及支持的最低版本
# s.xcconfig = { 'OTHER_LDFLAGS' => '-Objc -all_load -fobjc-arc' ,'ENABLE_BITCODE' => 'NO'} # target的相关设置
s.author = { "author" => "xxx.com" } # 作者信息, 开源上线后可能发送邮件
# s.frameworks = "UIKit", "Foundation" #支持的框架
# s.resources = "*.bundle" # 资源文件
## 确定swift使用的版本 / OC不需要确定版本,因为OC目前只有一个版本
s.swift_version = '5.0'
s.pod_target_xcconfig = {'SWIFT_VERSION'=>'5.0'} #指定swift版本
# 引用资源文件
s.subspec 'MDBaseUILibrary.bundles' do |ss|
ss.resource_bundles = {
'MDBaseUILibrary' => ['MDBaseUILibrary/Classes/MD_BASE_UI_Lirary/MDBaseUILibrary.bundle/*.png']
}
end
# s.dependency = "AFNetworking" # 依赖库,有多少依赖库就写多少 s.dependency
# s.dependency 'AFNetworking', '~> 3.0' # 可以指定版本
# s.dependency '{私有库}', # 可以指定私有库
s.prefix_header_contents = 'import SnapKit','#import<WebKit/WebKit.h>' ## 在头文件新增导入的头文件
### 对库进行分块处理,就是分文件夹
s.subspec 'MDBaseUILibraryHeader' do |ss|
ss.source_files = 'MDBaseUILibrary/Classes/MD_BASE_UI_Lirary/MD_Base_UI_Header(头文件)/*.{h,swift}'
ss.dependency 'MDBaseUILibrary/XXX'
end
如需要添加resource 则取消 s.resources 注释,在Assets加入资源并执行 pod install
注:如果引用了自己私有库,在install之前,需要在项目中的Podfile文件中引用该私有库
比如:
pod 'MDBaseLibrary', :source => 'https://{私有库地址}.git'
3、当创建好第三方库的项目和文件后,则进行组件的开发。
4、把开发好的组件移植到改第三方库的classes目录下:
5、通过控制台进入到Example的目录下,通过pod的目录更新拉进来的第三方库,如下所示:
cd MZouLibraries/Example
pod install
当更新完pod的库后,则项目中会自动带入你在文件夹内加入的第三方库了,如下所示为pod install后的项目:
6、此时返回到第三方库的目录下,即demo的上一层目录,可以通过pod的命令来验证该库是否搭建成功了
pod lib lint --allow-warnings --verbose
如若出现了验证通过的信息,则该第三方库搭建成功了,如下如所示:
7、此时需要提交该库的到远程仓库中。(如果版本号有改动的,需要去修改podspec文件,否则验证不通过)。可以通过sourceTree进行文件提交和打上标签,或者在当前本地库的目录下,通过控制台的命令,把该库的文件提交上去远程库。所用到的命令如下:
#添加远程地址,即上面创建码云项目的地址,xxxx是码云的用户名,MyDemoPrintTest就是你创建的git仓库名称
git remote add origin https://gitee.com/xxxx/MyDemoPrintTest.git
#添加文件
git add .
#提交本地,并写描述
git commit -a -m "第一次提交 版本为0.0.1"
# --allow-unrelated-histories
# git pull origin maste会失败 ,提示:fatal: refusing to merge unrelated histories
#原因是远程仓库origin上的分支master和本地分支master被Git认为是不同的仓库,所以不能直接合并,需要添加 --allow-unrelated-histories
git pull origin master --allow-unrelated-histories
#推送到码云的项目的master分支上
git push origin master
#提交版本号
git tag 0.0.1
#push到远程分支
git push origin 0.0.1
注意:远程库的tag必须要和podspec中的版本号对上,比如:0.1.0
私有库相互关联
在私有库B需要依赖私有库A的时候,需要在xxx.podSpec文件中新增依赖,比如下图
s.dependency 'MDBaseLibrary'
在编译验证该库是否通过的时候,需要在验证指令上添加依赖的私有库的远程地址,比如:
pod lib lint --allow-warnings --verbose --sources='https://{私有库地址}/xxxx.git,https://cdn.cocoapods.org/'
三、远程私有仓库和私有第三方库的关联
1、在第三方私有库的目录下,通过pod命令进行关联:
查看本地仓库
pod repo list
然后根据本地的仓库进行关联
pod repo push `#{本地关联到远程仓库的名字}` `#{第三方私有库的podspec文件}` --verbose --allow-warnings
示例:
pod repo push MZouSpec MZouCategries.podspec --verbose --allow-warnings
然后经过一些列的编译,最后出现如下所示,则表示关联成功了:
注:如果有报错的需要根据报错去处理相关问题
此时可以再远程的私有仓库中看到第三方库的存在了,如下如所示:
,则目前cocoapod的私有库搭建成功了。
四、项目引入私有库中的第三方库,如下所示在pod的Podfile文件配置:
到此则导入了自己创建的第三方库成功了。
五、在搭建私有库的时候遇到的问题:
1、报错:description: The description is empty.
在 podspec 文件中 s.description 没有内容,如果不需要,那么注释掉
2、报错:file patterns: The 'source_files' pattern did not match any file.
在 podspec 文件中 s.source_files 文件路径有误,这个路径是相对 .podspec 文件的,如果是与 .podspec 同级别的, 那么只需要写文件夹名称即可
s.source_files = "文件夹"
如果有多级,要完全按照路径来写
s.source_files = "文件夹/.{h, m}"
s.source_files = "文件夹//.{h, m}"
或者直接使用
s.source_files = "文件夹"
3、报错:unknown: Encountered an unknown error (/usr/bin/xcrun simctl list -j devices xcrun: error: unable to find utility "simctl", not a developer tool or in PATH) during validation.
原因是 Xcode 模拟器找不到,需要获取 Xcode 路径。
sudo xcode -select -switch /Applications/Xcode.app/Contents/Developer
(常规路径是这个,即 Xcode 在应用程序中。如果不在或者有多个 xcode 需要根据修改 xcode 的路径)
4、报错:license: Unable to find a license file
创建私人仓库时, 在验证时可能会找不到 MIT LICENSE证书。将 s.license ="MIT" 修改为,指定文件s.license = { :type=>"MIT", :file=>"LICENSE"}
如果是本身就没有MIT LICENSE证书,可以创建一个文件,命名为LICENSE。内容为:
Copyright (c) 20XX-20XX TestCode Software Foundation (http://XXX)Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.
将文中的时间、项目名与地址替换掉即可。
5、报错:warning: Could not find remote branch 版本号 to clone. fatal: Remote branch 版本号 not found in upstream origin.
可能是s.version 与git tag版本号不一致、没有上传版本号或者git push 的时候没有添加--tags。
6、如果报警告错误又不想处理可以使用 $ pod lib lint --allow-warnings 验证
7、报错:[!] The repo MyRepo
at ../../../../.cocoapods/repos/MyRepo
is not clean
执行:
pod repo update MyRepo
再次执行更新命令,如果还不可以那么先删除原有的版本库再重新安装版本库,然后执行更新命令
pod repo remove MyRepo
pod repo add MyRepo https://xxx.git
pod repo push MyRepo XXX.podspec
8、报错:[!] The xxx.podspec
specification does not validate. 但是没有ERROR
执行:pod repo push MyRepo xxx.podspec --verbose --use-libraries --allow-warnings
9、报错: ERROR | [iOS] unknown: Encountered an unknown error (undefined method `path' for nil:NilClass) during validation.
将 .podspec 中 s.source_files = 'Pod/Classes//’ 改为 s.source_files = 'Pod/Classes//.{c,h,hh,m,mm}'
10、报错: fatal error: could not build module 'CoreFoundation'
见了鬼了,pod lib lint 检测到 pod spec lint 检测全都正确,结果到pod repo push MyRepo xx.podspec 时遇到了这个问题,还不是在正常的输入里显示,而是在很上面的日志中提示的,有很多,包括 Foundation。
将 .podspec 中 s.frameworks = 'UIKit', 'Foundation', 'CoreFoundation' 再次提交后上传。
11、podspec specification does not validate 问题解决
在做私有库的时候,执行 push 操作的时候,报如题的错误。
pod repo push [repo] [podspec]
但是执行pod lib lint的时候,本地验证却是可以通过的。
然后参考Stack Overflow和google的一些答案,都没能解决。这里就不贴尝试过的别的答案了。
最终经过反复调试,发现 是自己没有把本地版本、tag版本、远程提交版本同步好。也就是它们之间存在不一致。
我本地验证可以通过,但是没有通过git add .把发生修改的文件提交到缓冲区,也没有git commit -m "XX"提交到本地仓库。这个时候打的tag,是从本地仓库打的tag。所以就出现了和本地现在的代码不同步。
所以正确的步骤,是把代码都提交到本地仓库后,再重新打 tag 然后重新push就可以通过了。
因为之前都是用 source tree。现在直接上手git操作有点不太熟练,导致犯下了低级错误。这个问题确实挺难找的。如果没有意识到是代码不同步的话,很可能会被网上很多答案给带偏了。
希望我的这种解决能够帮助到有类似问题的人。
大千世界,求同存异;相遇是缘,相识是份,相知便是“猿粪”(缘分)
From MZou