当公司的项目越来越大的时候,为了便于管理,组件库就成了一个很好的选择,便于我们开发维护以及在不同的项目中使用。下面我们来走一遍组件库的创建流程:
我们创建一个工具类的组件库,命名为ZKFoundation库。
git上传的功能方法和遇到的各种问题处理方法!!!!!!!!!!!
一、创建组件库
pod lib create ZKFoundation
接下来会弹出来几个问题:
1、What platform do you want to use?? [ iOS / macOS ] 选:iOS
2、What language do you want to use?? [ Swift / ObjC ] 根据需要选择语言
3、Would you like to include a demo application with your library? [ Yes / No ] //是否创建包含组件的demo
4、Which testing frameworks will you use? [ Specta / Kiwi / None ] 使用那些测试框架,选None
5、Would you like to do view based testing? [ Yes / No ] 你是否要执行基于view的测试
6、What is your class prefix? 你类的前缀是什么?
根据我们的设置生成的pod工程。
工程内容:
pod 'ZKFoundation', :path => '../' 本地库的引入方式
在ZKFoundation里面编写代码。
二、编写注意事项
1、在编写的时候,我们可以直接通过pod 'ZKFoundation', :path => '../' 的方式引用,把创建的组件库放到我们的工程里面,然后使用,提交代码的时候,只提交这个本地库的就可以。
2、每次创建或者删除组件库中的类之后,要在这个组件库里面pod install一下,然后在我们整个项目的pod install,防止找不到类的错误。
3、创建一个头文件,将所有的类的头文件放到里面,方便外部直接引用哦。
4、在ZKFoundation-prefix中可以定义宏方法,方便我们调用
三、添加依赖
项目中我们一般会引用其他库或者第三方库,就需要我们添加相应的依赖。
在ZHFoundation.podspec中,添加相关依赖:
s.dependency 'AFNetworking', '4.0.1'
s.dependency 'UMCommon'
s.dependency 'IKCrypt'
这样在我们pod引入ZHFoundation库的时候就会自动引入相关库,供我们的库使用。
四、打tag
引入的时候根据tag引入我们的工程中。
zhanyingzhu@zhanyingdeMacBook-Pro-3 TYTShareAndMobEvent % git add .
zhanyingzhu@zhanyingdeMacBook-Pro-3 TYTShareAndMobEvent % git commit -m "tag=0.0.2-beta"
[master 6f4c338] tag=0.0.2-beta
2 files changed, 1 insertion(+), 3 deletions(-)
zhanyingzhu@zhanyingdeMacBook-Pro-3 TYTShareAndMobEvent % git push
zhanyingzhu@zhanyingdeMacBook-Pro-3 TYTShareAndMobEvent % git tag -a "0.0.2-beta" -m "1、 此版本为0.1.0版本的beta版,上传相关类和依赖。"
zhanyingzhu@zhanyingdeMacBook-Pro-3 TYTShareAndMobEvent % git push origin --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 231 bytes | 231.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To 192.168.2.20:iOS-Components/TYTShareAndMobEvent.git
* [new tag] 0.0.2-beta -> 0.0.2-beta
zhanyingzhu@zhanyingdeMacBook-Pro-3 TYTShareAndMobEvent % git tag
0.0.1-beta
0.0.2-beta
这样tag就完成了。引入我们项目中如下:
pod 'TYTShareAndMobEvent', :git => 'git@192.168.2.18:iOS-Components/TYTShareAndMobEvent.git', :tag => '0.0.2-beta'
然后调用pod update TYTShareAndMobEvent --no-repo-update
更新最新的版本。
打tag遇到的问题:
To 192.168.2.20:iOS-Components/TYTFoundation.git
* [new tag] 0.1.6-beta -> 0.1.6-beta
! [rejected] 0.1.4-beta -> 0.1.4-beta (already exists)
! [rejected] 0.1.5-beta -> 0.1.5-beta (already exists)
error: failed to push some refs to '192.168.2.20:iOS-Components/TYTFoundation.git'
hint: Updates were rejected because the tag already exists in the remote.
更新被拒绝,因为tag在远端已经存在了。
1,执行命令 获取所有的标签
git pull --tags
2、执行命令 覆盖本地存在的标签冲突
git pull --tags -f
然后再git pul git push就可以了。
3、删除tag:
如果提交tag之后,返现这次提交的有问题,又不想增加tag,那么我们可以删除tag,修改代码完毕push之后,再次打tag提交。
zhanyingzhu@zhanyingdeMacBook-Pro-3 Example % git tag
0.0.1-beta
0.0.2-beta
0.0.3-beta
0.0.4-beta
0.1.0
0.1.5-beta
zhanyingzhu@zhanyingdeMacBook-Pro-3 Example % git tag -d 0.1.0
Deleted tag '0.1.0' (was 0c9b704)
zhanyingzhu@zhanyingdeMacBook-Pro-3 Example % git push origin :refs/tags/0.1.0
To 192.168.2.20:iOS-Components/TYTShareAndMobEvent.git
- [deleted] 0.1.0
五、组件库提交标准:
1、依赖的第三方库版本都要写上。
2、依赖的自己的组件库版本、tag不需要写,否则,组件库的版本号、tag一变动,那么依赖就会有问题。因为库没有更新。
3、podspace本地库的版本号s.version = ‘0.1.5-beta’,要随时变动。否则虽然代码拉的是最新的tag,但是版本号却依然是旧的版本号0.1.4。 虽然说用起来没问题,但是看着对不上版本号也是闹心。
4、组件库依赖的三方库,可以在主工程中删除掉。在pod install的时候会自动引入。
六、Pod 私有库创建&组件化的实践
传送门(https://www.jianshu.com/p/8219d29fea17)
七、git stash (暂存)
1、先git status获取当前的修改的状态。
2、然后使用git stash暂存现在所有的修改文件。
3、 git log获取以前提交的所有内容。
zhanyingzhu@zhanyingdeMacBook-Pro-3 client_program % git log
commit 549b8ebd5240089872d62831e71c977c594842b4 (HEAD -> dev_6270, origin/dev_6270)
Author: Bubble <huobingbing@teyuntong.com>
Date: Wed Nov 30 13:53:52 2022 +0800
Podfile udpate
commit 6c7da301cf6ca6a39619b9b5457b03ec97bedf7b //这个
Author: chaoyakai <chaoyakai@teyuntong.com>
Date: Wed Nov 30 10:44:00 2022 +0800
fix: 文案修改
commit 026e7d419f91233efdf6e6949fe1c21093012b63
Author: chaoyakai <chaoyakai@teyuntong.com>
Date: Wed Nov 30 10:30:39 2022 +0800
fix: 文案修改
4、然后选取我们要回退的版本id。
git reset --hard 6c7da301cf6ca6a39619b9b5457b03ec97bedf7b
使用hard会回到置顶的commit_id,但是也会清除掉我们提交的代码,如果要保留代码,那们就是用git reset --soft 6c7da301cf6ca6a39619b9b5457b03ec97bedf7b
,这样技能回退,又能保留我们修改的代码。
5、pod instlal
拉取这个提交的所有代码,运行代码(没问题)
6、git stash list
查看暂存的所有的内容
zhanyingzhu@zhanyingdeMacBook-Pro-3 client_program % git stash list
stash@{0}: WIP on dev_6270: 549b8ebd Podfile udpate
stash@{1}: On dev_6270: TYTGoodsDetailController冲突处理
7、恢复所有的代码
zhanyingzhu@zhanyingdeMacBook-Pro-3 client_program % git stash apply stash@{0}
On branch dev_6270
Your branch is up to date with 'origin/dev_6270'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Common/Launch/Task/TYTAgreedPrivacyTask.m
modified: Common/role/TYTSelectedRoleTools.m
modified: MBTytOne.xcodeproj/project.pbxproj
deleted: TytCars/Classes/Other/lib/Encapsulation/TYTDataManager.h
deleted: TytCars/Classes/Other/lib/Encapsulation/TYTDataManager.m
如果要查看相应的修改:git diff TytCars/PrefixHeader-Cars.pch
8、然后就是走提交代码那一套流程了。git add . 以及之后的代码
上面是git push的时候,发现有冲突,但是代码已经commit,我们需要回退。但如果是没有提交,在git pull的时候报冲突,我们就使用下面的方法:
git stash
git pull
git stash pop
git stash: 将改动藏起来
git pull:用新代码覆盖本地代码
git stash pop: 将刚藏起来的改动恢复
这样操作的效果是在最新的仓库代码的基础仍保留本地的改动。这个时候,就会有冲突,我们只需要一个个解决冲突就行了。如果不想保留本地的修改,那么就直接覆盖掉就行了。
git reset --hard
git pull
八、上传到pod远端中
这个是组件没有依赖别的私有组件导致需要校验相关源的情况,所以不需要添加相关源,校验的时候默认走cocoapod的默认源。
1、验证podspec索引文件
通过 pod spec lint --verbose --allow-warnings --use-libraries
命令验证 podspec 索引文件。
2、提交索引文件到远程索引库
验证通过之后,pod repo push 本地索引库 索引文件名 --verbose --allow-warnings --use-libraries
将索引文件提交的到远程索引库。
pod repo push WJHSpecs WJHBaseWidgets.podspec --verbose --allow-warnings --use-libraries
组件库的提交和静态库的提交略有不同,详见之前写的文章。
https://www.jianshu.com/p/f0a90a119b98
九、Pod有依赖的提交到远端
一般情况下项目会依赖外部source源,所以我们需要在校验的时候添加相应的依赖source源,尽量不要多写无关的source源避免节外生枝。
1、将代码提交到仓库。git push
2、打tag,注意和podspace文件中的s.tag = 0.1.0相同。
git tag -a "0.1.0" -m "1.此版本为0.1.0正式版本"
git push —-tags
3、提交完毕之后校验
pod lib lint --allow-warnings --verbose --sources=gitee-mirrors-cocoapods-specs,amh-group-iosymm-mb-specrepo,amh-group-cocoapods-mb-thirdpartyspecrepo,2-cocoapods-tyt-specs
这个校验如果报错,就使用下面这个,使用
pod spec lint --verbose --allow-warnings --use-libraries --no-clean --sources=gitee-mirrors-cocoapods-specs,amh-group-iosymm-mb-specrepo,amh-group-cocoapods-mb-thirdpartyspecrepo,2-cocoapods-tyt-specs --use-modular-headers
这四个源分别是我们工程中依赖到的相关源
其中相应的source就是我们工程中以来的source源。注意不要写https,通过pod repo list
来查看本地源。然后填写在--sources=后面。校验没问题之后,到最后一步提交。
4、提交
REPO_NAME:本地的文件名
加上提交的podspec文件
pod repo push 2-cocoapods-tyt-specs TYTShareAndMobEvent.podspec --verbose --allow-warnings
报错,提交过程中提示我要输入github的账号和密码,莫名其妙,工程中用的是gitlab,怎么也不会是github,一查才发现是podspec文件中的源s.source = 写的是github地址。需要改成我们项目的地址,使用ssh的地址即可。
还有一个Xcode版本的问题,在Xcode14中,podfile使用use_modular_headers!
,也就是使用代码的方式,不要使用use_frameworks!
,这样会使用framework,clean之后编译总会报找不到MBProgressUD三方库文件找不到的问题。
9.1 Repo是什么
repo是Google开发的用于管理项目版本库的一个工具,repo是使用Python对git进行了一定的封装,并不是用于取代git,它简化了对多个Git版本库的管理。用repo管理的版本库都需要使用git命令来进行操作。
简单理解:repo担任角色
- repo就是多个git库的管理工具。如果是多个git库同时管理,可以使用repo。
- 作用就是和主代码服务器交互
- 用manifest.xml管理多个git仓库
git repo工具详细使用教程——彻底学会Android repo的使用
Git、Gerrit、Repo三者的区别及使用
9.2 为什么用Repo
项目组件化模块化之后,各个模块也作为独立的git仓库从主项目中剥离了出来。各个模块各自管理自己的版本和分支,为了方便管理各个子项目的Git仓库,需要一个上层工具批量进行处理。因此使用了reop,repo也会建立一个Git仓库,用来记录当前项目下的各个子项目的git仓库分别属于哪一个分支。比如我们用pod repo list
查出来之后可以看到,有我们自己的仓库分支2-cocoapods-tyt-specs
,也有满帮amh-group-cocoapods-mb-thirdpartyspecrepo``amh-group-iosymm-mb-specrepo
,还有cocoapods的gitee-mirrors-cocoapods-specs
。
9.3 更新Repo
如果ZHFoundation从 0.1.0 升级到 0.2.0,需要执行两个命令:
pod repo update 2-cocoapods-tyt-specs
更新repo源,否则会报找不到版本的错误None of your spec sources contain a spec satisfying the dependency:
ZHFoundation (= 0.2.0).
并提示你out-of-date source repos which you can update with pod repo update or with pod install --repo-update.
然后再pod install或者pod update ZHFoundation --no-repo-update即可。
十、组件化的优化
1、图片的优化
把图片放到新创建的图片文件中,这样的好处就是图片的@2x,@3x,再被不同屏幕的手机加载的时候,会使用一种图片,减少包体积。
十一、本地校验遇到的报错问题
1、引用静态库报错
ERROR | [iOS] unknown: Encountered an unknown error (The 'Pods-App' target has transitive dependencies that include statically linked binaries:
在命令中加入 --use-libraries 允许使用静态库即可。
2、Xcode编译报错
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code.
添加 --use-modular-headers.
总的命令如下:
pod lib lint --allow-warnings --use-libraries --verbose --sources=amh-group-iosymm-mb-specrepo,amh-group-cocoapods-mb-thirdpartyspecrepo,gitee-mirrors-cocoapods-specs,2-cocoapods-tyt-specs --use-modular-headers
3、如果有报下面的错
Cannot code sign because the target does not have an Info.plist file and one is not being generated automatically. Apply an Info.plist file to the target using the INFOPLIST_FILE build setting or generate one automatically by setting the GENERATE_INFOPLIST_FILE build setting to YES (recommended). (in target 'App' from project 'App')
我们只改工程里面的GENERATE_INFOPLIST_FILE设置为YES时不行的,那样只是主工程有用,其余的组件库用不到。需要在podspec文件里面添加,这样就可以将所有依赖的组件库设置成YES。
s.user_target_xcconfig = {
'GENERATE_INFOPLIST_FILE' => 'YES'
}
这样会导致一个CFBundle文件找不到的问题,需要我们手动的添加build号,如下:
4、报错
LoadError - dlopen(/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.5/lib/ffi_c.bundle, 0x0009):
tried: '/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.5/lib/ffi_c.bundle'
(mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')),
'/usr/lib/ffi_c.bundle' (no such file) - /Library/Ruby/Gems/2.6.0/gems/
ffi-1.15.5/lib/ffi_c.bundle
这是由于M1芯片导致的在pod命令时报ffi相关的错误,解决办法如下:
sudo arch -x86_64 gem install ffi
arch -x86_64 $SHELL
就可以启动一个 X86 模式终端,使得之后运行的命令都在 X86 模式下运行。然后在执行上传podspec命令:
pod repo push 2-cocoapods-tyt-specs TYTGoodsOrderManagement.podspec --verbose --allow-warnings --use-modular-headers --use-libraries
在更新podspec文件:
pod repo update 2-cocoapods-tyt-specs
成功:
5、podspec修改错误
error: Cannot code sign because the target does not have an Info.plist file and one is not being
generated automatically. Apply an Info.plist file to the target using the INFOPLIST_FILE build setting
or generate one automatically by setting the GENERATE_INFOPLIST_FILE build setting to YES
(recommended). (in target 'App' from project 'App')
这个时候需要在podspec文件里面新增:
s.user_target_xcconfig = {
'GENERATE_INFOPLIST_FILE' => 'YES'
}
s.pod_target_xcconfig = {
'GENERATE_INFOPLIST_FILE' => 'YES'
}
十二、创建组件库遇到的问题
1、创建远程私有索引库MyLib
2、创建组件库
3、发布
发布遇到问题是MyLib的问题,如下图:
分支和你当前的分支要一样,不一样的话就会报这样的错误。
我们需要将隐藏的.git中的config文件中的对应分支改一下。