0x01 前言
本次组件化实践的方式来自于casaty组件化方案,该方案是基于target-action模式和Mediator模式,通过Mediator利用runtime的机制来调用对应的target-action。并且在上层通过category的方式暴露对外调用的接口,这样调用者在调用的时候就知道需要传递哪些参数。
具体的调用方式就是:
实际上是可以不使用category的形式而是直接调用CTMediactor的
- (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget
方法直接调用对应target的action,但是那样对于调用方来说极其不友好,最直观的感受就是不知道params应该传哪些参数。
利用catogory的方式暴露方法的好处在于
1、一个组件对应一个category,每个category提供了组件所有的调用方法,调用方直接调用,可以直观的看到需要传递哪些参数。
2、提供统一的调用入口,所有的组件的被调用都是通过category
3、可以做异常处理,将参数的校验提前,并且可以做请求转发。
0x02 组件化实践
在简单的介绍了组件化的实际逻辑之后下面开始真正的开始动手实现组件化实践流程。
一个私有pod的创建具体分为以下几步:
- 创建工程
- 创建私有库,修改podSpec文件,将本地代码库和远程代码库关联起来,上传代码到远程仓库。
- 创建远程索引库和本地索引库,也就是用于放置podspec的地方,每个podspec文件可以索引到我们远程不同的代码私有库
- 本地测试podspec文件是否可用
- 向索引库Spec Repo中提交podspec
- 测试Spec Repo中的的 podspec 是否可用
1、 首先到github里面创建一个空的工程,例如我要创建一个FirstViewController
2、 创建私有库,终端运行pod lib create FirstViewController
Lemons-MacBookPro:Module lemon$ pod lib create FirstViewController
Cloning `https://github.com/CocoaPods/pod-template.git` into `FirstViewController`.
Configuring FirstViewController template.
------------------------------
To get you started we need to ask a few questions, this should only take a minute.
If this is your first time we recommend running through with the guide:
- https://guides.cocoapods.org/making/using-pod-lib-create.html
( hold cmd and click links to open in a browser. )
What platform do you want to use?? [ iOS / macOS ]
> iOS //pod平台
What language do you want to use?? [ Swift / ObjC ]
> ObjC //pod语言
Would you like to include a demo application with your library? [ Yes / No ]
> No //是否需要提供demo
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?
> LM //demo类前缀
Running pod install on your new library.
Analyzing dependencies
Fetching podspec for `FirstViewController` from `../`
Downloading dependencies
Installing FirstViewController (0.1.0)
Generating Pods project
Integrating client project
上述命令执行完成之后会本地帮我们生成一个pod的模板文件,我们在这里首先需要改动的就是FirstViewController.podspec文件,用xcode打开该文件。
目前我们需要注意下面几处地方:
s.version = '1.0.0'
//pod的版本,后面将podSpec文件提交到私有repo的时候会验证远程的仓库中是否已经存在对应的tag,所以这个要与后面提交代码的时候的tag相同,我们先修改为1.0.0,可以按照你们自己的标准修改。s.homepage = 'https://github.com/codemonkeybulucck/FirstViewController'
//homepage这里填写在第一步中再github创建的远程仓库的地址即可。s.source = { :git => 'https://github.com/codemonkeybulucck/FirstViewController.git', :tag => s.version.to_s }
//这里填写远程仓库的地址,记得后面要加上.git的后缀s.ios.deployment_target = '8.0'
//该pod的最低运行环境s.source_files = 'FirstViewController/Classes/**/*'
//pod中源代码的路径,后面会将实际的代码放在Classes文件夹下面
一些其他设置的说明:
s.summary = 'A short description of FirstViewController.' //pod的简述
s.description = <<-DESC //具体描述
s.license = { :type => 'MIT', :file => 'LICENSE' } //许可证
s.author = { '[email protected]' => '[email protected]' } //作者信息
s.dependency 'AFNetworking', '~> 2.3' //依赖库,如果该pod依赖其他pod,可以在此处加上。
完成podspec文件修改之后我们可以将对应的组件代码放到Classes文件夹路径下面。下面将本地代码库和远程代码库关联起来,然后将本地代码推送到远程仓库。
Lemons-MacBookPro:FirstViewController lemon$ git remote add origin https://github.com/codemonkeybulucck/FirstViewController.git
Lemons-MacBookPro:FirstViewController lemon$ git add .
Lemons-MacBookPro:FirstViewController lemon$ git commit -m "初始化"
[master 8ac032c] 初始化
25 files changed, 1209 insertions(+)
create mode 100644 Example/FirstViewController.xcworkspace/contents.xcworkspacedata
create mode 100644 Example/FirstViewController.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
create mode 100644 Example/Podfile.lock
create mode 100644 Example/Pods/Local Podspecs/FirstViewController.podspec.json
create mode 100644 Example/Pods/Manifest.lock
create mode 100644 Example/Pods/Pods.xcodeproj/project.pbxproj
create mode 100644 Example/Pods/Target Support Files/FirstViewController/FirstViewController-dummy.m
create mode 100644 Example/Pods/Target Support Files/FirstViewController/FirstViewController-prefix.pch
create mode 100644 Example/Pods/Target Support Files/FirstViewController/FirstViewController-umbrella.h
create mode 100644 Example/Pods/Target Support Files/FirstViewController/FirstViewController.modulemap
create mode 100644 Example/Pods/Target Support Files/FirstViewController/FirstViewController.xcconfig
create mode 100644 Example/Pods/Target Support Files/FirstViewController/Info.plist
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Info.plist
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests-acknowledgements.markdown
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests-acknowledgements.plist
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests-dummy.m
create mode 100755 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests-frameworks.sh
create mode 100755 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests-resources.sh
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests-umbrella.h
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests.debug.xcconfig
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests.modulemap
create mode 100644 Example/Pods/Target Support Files/Pods-FirstViewController_Tests/Pods-FirstViewController_Tests.release.xcconfig
create mode 100644 FirstViewController/Classes/FirstViewController.h
create mode 100644 FirstViewController/Classes/FirstViewController.m
delete mode 100644 FirstViewController/Classes/ReplaceMe.m
Lemons-MacBookPro:FirstViewController lemon$ git push origin master
Counting objects: 62, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (55/55), done.
Writing objects: 100% (62/62), 23.04 KiB | 2.56 MiB/s, done.
Total 62 (delta 10), reused 0 (delta 0)
remote: Resolving deltas: 100% (10/10), done.
To https://github.com/codemonkeybulucck/FirstViewController.git
* [new branch] master -> master
3、 创建远程索引库和本地索引库,同样在github创建一个新的仓库,仓库的名字叫做LMSpec,这个仓库是pod的索引库,也就是后面如果要引用组件pod的话只要引入这个LMSpec就能从里面找到对应的组件。
创建完远程仓库之后我们创建一个本地索引库,并且将本地索引库和远程仓库连接起来。
pod repo add LMSpec https://github.com/codemonkeybulucck/LMSpec.git
执行完这条命令之后,去到 ~/.cocoapods/repo
路径下就能看到有一个master和LMSpec,master是公有cocoapod的索引库,LMSpec就是我们自己新建的索引库。到此我们已经创建好代码库以及索引库了。
4、本地测试podspec文件是否可用 本地测试podspec文件是否可用。
Lemons-MacBookPro:FirstViewController lemon$ pod lib lint
-> FirstViewController (1.0.0)
- WARN | summary: The summary is not meaningful.
[!] FirstViewController did not pass validation, due to 1 warning (but you can use `--allow-warnings` to ignore it).
You can use the `--no-clean` option to inspect any issue.
上述验证表明我们本地验证已经没有错误了,但是有一个警告,我们可以使用
pod lib lint --allow-warnings
来忽略警告。如果我们使用pod spec lint
来验证的话,记得要先本地代码库打tag然后将tag推动到远程仓库才能通过验证,因为该命令是同时验证本地和远程仓库,因为我们还没有打tag推送到远程仓库,所以我们先用pod lib lint
来验证。
5、 向索引库Spec Repo中提交podspec
在第四步中我们已经验证我们的podspec文件没有问题了,但是我们现在还不能推送到索引库,因为我们还没有打tag,这个tag应该是与podspec文件里面的version一致,不一致的话远程验证的时候是通不过验证的。
Lemons-MacBookPro:FirstViewController lemon$ git tag -a 1.0.0 -m "第一个版本pod"
Lemons-MacBookPro:FirstViewController lemon$ git push origin master 1.0.0
Counting objects: 1, done.
Writing objects: 100% (1/1), 183 bytes | 183.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/codemonkeybulucck/FirstViewController.git
* [new tag] 1.0.0 -> 1.0.0
完成上述步骤后我们需要将podspec提交到索引库中。
Lemons-MacBookPro:FirstViewController lemon$ pod repo push LMSpec FirstViewController.podspec --allow-warnings
Validating spec
-> FirstViewController (1.0.0)
- WARN | summary: The summary is not meaningful.
Updating the `LMSpec' repo
Already up to date.
Adding the spec to the `LMSpec' repo
- [Add] FirstViewController (1.0.0)
Pushing the `LMSpec' repo
至此为止我们已经将podspec文件推送到本地LMSpec和远程LMSpec里面了,可以到 ~/.cocoapods/repo/LMSpec
文件夹下看有没有对应FirstViewControll文件夹。该文件夹下会有一个1.0.0的文件夹,也就是我们刚刚打的tag的数值。后续如果修改代码需要重新打tag,然后到时这里也会出现新的版本的代码。
注 如果该私有库里面引用了其他的私有库,也就是podspec文件中s.dependency引用了其他私有库的信息,需要指定私有库的位置,那么推送命令将变为
pod repo push LMSpec FirstViewController.podspec --allow-warnings --sources=https://github.com/codemonkeybulucck/LMSpec,master
6、 测试Spec Repo中的的 podspec 是否可用
创建一个ModuleTest的工程,进入到工程里面先执行 pod init
,然后编辑podfile文件
source 'https://github.com/codemonkeybulucck/LMSpec'
source 'https://github.com/CocoaPods/Specs.git'
target 'moduleTest' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
pod 'FirstViewController'
# Pods for moduleTest
end
执行pod install
如果没出错就代表私有库已经添加成功。