组件化实践

栏目: IOS · 发布时间: 5年前

内容简介:最近想了解一些组件化的知识,去看了Casa写的大神们讨论具体的实施方案,是对理论的描述,在架构层面来分析利弊,我看过之后感觉还是有点晦涩,具体的方案异同之处我们先不说,今天我们先从当然了,我们选择使用的方案是Casa的

最近想了解一些组件化的知识,去看了Casa写的 iOS应用架构谈 组件化方案 这篇文章,Casa在文中针对蘑菇街的组件化方案提出了一些不同的观点,陈述了自己的组件化方案。

大神们讨论具体的实施方案,是对理论的描述,在架构层面来分析利弊,我看过之后感觉还是有点晦涩,具体的方案异同之处我们先不说,今天我们先从 应用 着手,在自己当前的工程实施组件化。

当然了,我们选择使用的方案是Casa的 CTMediator

准备

首先我们得先了解组件化这个概念,其实通俗的讲,就是把我们的项目拆解成一个一个的小组件分别管理。我们平时使用cocoapods继承的三方的库,可以理解成是一个公有的组件。我们项目中,也可以把一些模块拆解出来,使用cocoapods来集成。这样拆解成一个个的组件的好处有很多,比如说业务模块之间解耦,复用模块,节省编译时间等等。

所以我们要先学会创建cocoapods私有库。

这里多说一句,Casa的组件化方案在实施的时候,每独立出来一个组件,就会相应的创建一个Category工程,作为中间的调度,所以说,我们每做一个组件,就要创建两个私有的pod工程。

我们结合Casa这篇 在现有工程中实施基于CTMediator的组件化方案 ,来做一下补充或者说是注解吧,本文中的流程取自于上文。

创建私有Pod工程

1. 先去开一个repo,这个repo就是我们私有Pod源仓库
2. pod repo add [私有Pod源仓库名字] [私有Pod源的repo地址]
3. 创立一个文件夹,例如Project。把我们的主工程文件夹放到Project下:~/Project/MainProject
4. 在~/Project下clone快速配置私有源的脚本repo:git clone git@github.com:casatwy/ConfigPrivatePod.git
5. 将ConfigPrivatePod的template文件夹下Podfile中source 'https://github.com/ModulizationDemo/PrivatePods.git'改成第一步里面你自己的私有Pod源仓库的repo地址
6. 将ConfigPrivatePod的template文件夹下upload.sh中PrivatePods改成第二步里面你自己的私有Pod源仓库的名字

首先我们先创建一个名为Project的文件,然后把我们项目的主程序,我们叫做MainProject放到Project路径下,然后在Project路径下clone出我们需要的脚本(Casa提供)

在~/Project下clone快速配置私有源的脚本:
git clone git@github.com:casatwy/ConfigPrivatePod.git

现在我们的文件目录结构是这样的。

Project
├── ConfigPrivatePod(脚本文件)
└── MainProject

在Project路径下创建我们的组件工程(一个普通的iOS工程),我们把这个工程名字叫PayComponents (模拟抽取项目中的支付模块)。

当前目录结构

Project
├── ConfigPrivatePod
├── MainProject
└── PayComponents

有了本地的工程之后,我们现在需要创建一个repo,作为我们的私有pod源仓库。也就是在github,或者gitee(码云)上面创建一个项目,放我们的项目代码,命名PayComponents。

然后呢,我们还需要创建一个东西,就是私有Pod源仓库名字。

pod repo add [私有Pod源仓库名字] [私有Pod源的repo地址]

落实到我们这个项目中,我们应该这样写。

pod repo add PayComponents https://gitee.com/LittleBin/PayComponents.git

那这到底代表着我们创建了什么?

我们打开finder->前往->前往文件夹,然后输入 ~/.cocoapods/repos

可以看到目录是这样子的

组件化实践

repos路径下面有一个master,一个payComponents。这两个文件夹我们可以粗略的认为他和pod search还有install有关。

打个比方就拿search来说,我们查询一个库的时候会用下面这个命令

pod search AFNetworking

然后会从master路径下找到AFNetworking,然后列出来他有哪些版本什么的。我们有的时候会发现一个库其实已经跟新到2.x.x版本,但是我们search出来只有1.x.x,这也可能是我们的cocoapods没有更新,我们的master路径下没有新的版本。

这个PayComponents文件夹,就代表我们本地有一个私有的pod库。我们search的时候,也会查这些本地的私有库。

下面把远程的这个repo和我们本地创建的项目关联到一起,这个工作Casa给我们提供的脚本就可以完成,顺便还会帮我们生成.podspec的文件,具体这个文件的作用我们后面再说,还会初始化podfile。

我们进到ConfigPrivatePod文件中,执行config.sh脚本,然后在终端根据提示输入就行了。

[localhost:ConfigPrivatePod sunxiaobin$ ./config.sh 


Enter Project Name: PayComponents
Enter HTTPS Repo URL: https://gitee.com/LittleBin/PayComponents.git
Enter SSH Repo URL: git@gitee.com:LittleBin/PayComponents.git
Enter Home Page URL: https://gitee.com/LittleBin/PayComponents

================================================
  Project Name  :  PayComponents
  HTTPS Repo    :  https://gitee.com/LittleBin/PayComponents.git
  SSH Repo      :  git@gitee.com:LittleBin/PayComponents.git
  Home Page URL :  https://gitee.com/LittleBin/PayComponents
================================================

confirm? (y/n):y
copy to ../PayComponents/FILE_LICENSE
copy to ../PayComponents/.gitignore
copy to ../PayComponents/PayComponents.podspec
copy to ../PayComponents/readme.md
copy to ../PayComponents/upload.sh
copy to ../PayComponents/Podfile
editing...
edit finished
cleaning...
Initialized empty Git repository in /Users/fmb/Documents/LEARN/Project_test/PayComponents/.git/
clean finished
finished
localhost:ConfigPrivatePod sunxiaobin$

Enter Project Name:的时候,后面的名字一定要跟我们创建的PayComponents工程一样,要不然脚本找不到文件,就配置不了。

脚本跑完之后PayComponents里面变成下面这样子。

组件化实践

我们要修改一下Podfile文件和upload.sh。下面是生成的Podfile文件里面的内容

# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

source 'https://github.com/ModulizationDemo/PrivatePods.git'
source 'https://github.com/CocoaPods/Specs.git'

use_frameworks!

target 'PayComponents' do
 
end

因为脚本都是照着模板来生成的这些文件,上面是podfile文件里面的内容,我们要把第一个source后面的 'https://github.com/ModulizationDemo/PrivatePods.git' 改成我们这个库的地址, https://gitee.com/LittleBin/PayComponents.git

然后在upload.sh中,最后一行

pod repo push PrivatePods PayComponents.podspec --verbose --allow-warnings --use-libraries --use-modular-headers

把PrivatePods替换为我们上面的私有pod库名称。

也就是我们之前执行的下面这个命令中的PayComponents。

//不用重复执行
pod repo add PayComponents https://gitee.com/LittleBin/PayComponents.git

我们在看一下PayComponents项目文件的结构,脚本给我们生成了一个空的PayComponents文件。

组件化实践

我们需要把这个文件拖拽到我们的项目中

组件化实践

然后我们这个PayComponents组件的文件就全部放到这个路径下。我们的私有库暂时就先写到这里。下面创建我们的Category工程

创建Category工程

因为篇幅原因,这里我把创建Category工程略过一下,不一一展示了。

其实按道理说在实际项目中,这个Category工程也要做成私有库的,就像我们上面说的步骤,先创建本地工程,创建远程的repo,然后创建本地私有库(pod repo add ...),在用脚本关联本地和远程的库,然后修改Podfile和upload.sh等等这一整套步骤。

最终Category项目的结构是下面这样的。(包含为CTMediator添加的分类)

组件化实践

我们调用PayComponents组件里面的vc都是通过这个category来调用的。所以说我们的这个Pay_category工程应该在Podfile文件中加上 pod 'CTMediator' ,然后执行 pod install

我们之前有遇到过这种情况,我们在使用A库的时候,pod install之后,会自动帮我们导入A库依赖的B库,回到我们的项目也就是说当我们在主工程里面集成Pay_Category这一组件的时候,应该默认帮我们把CTMediator库和PayComponents组件也集成进工程。这就要修改Pay_Category.podspec文件。

在文件的最底部,end之前加上下面两句

s.dependency "CTMediator"
s.dependency "PayComponents"

说回我们新建的这个CTMediator+pay文件,我们要在主工程MainProject跳转到PayComponents里面的VC,所以CTMediator+pay应该提供一个返回vc的方法,如下:

- (UIViewController *)PayViewController {
  
    return [self performTarget:@"PayManager" action:@"pay" params:nil shouldCacheTarget:NO];
}

我们想不去管return后面的代码是什么意思,只要他是返回了vc给我们就可以。

然后在MainProject里面的跳转代码就如下:

// 导入CTMediator+pay头文件
UIViewController * viewController = [[CTMediator sharedInstance] PayViewController];
[self.navigationController pushViewController:viewController animated:YES];

下面我们再来说 return [self performTarget:@"PayManager" action:@"pay" params:nil shouldCacheTarget:NO]; 是什么意思。

我们可以从CTMediator的源码中,看一下 - (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget 这个方法。

那这里我就不绕圈子里,直接说结论,其实在上述的方法中是找到了一个叫Target_PayManager的类,调用了它里面的Action_pay方法,这个前缀Target_和Action_是在方法内部拼接的,所以说我们可以得出,CTMediator是通过反射拿到类名和方法名,然后调用,得到目标vc的。所以说在PayComponents工程中,我们还得创建Taregt文件来做间接的调用。

组件化实践

这里的Target_PayManager文件的文件名后半部分PayManager要跟 - (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget 里面的targetName对应起来,然后类里面的方法名字也得对应。(PayViewController就是我们的目标文件)

- (UIViewController *)Action_pay:(NSDictionary *)param {
    
    PayViewController *viewController = [[PayViewController alloc] init];
    viewController.param = param;
    return viewController;

}

最后我们在MainProject的Podfile文件中引入Pay_Category库就行了。这个时候我们的私有库可能还没有完全创建成,所以我们可以用这种导入本地的方法

pod "Pay_Category", :path => "../Pay_Category"

当然如果私有库做好了,就只需要 pod "Pay_Category" 就行了。

完善私有库

在Casa的博客中说到,可以使用他的upload.sh脚本来更新私有库代码,我用过它的脚本,总是有错无,而且库的版本号也是依次+1的形式,版本号我喜欢x.x.x这种,所以我选择自己提交代码,更新私有库。

针对于每个工程来说,首先是一些基本的提交代码操作,

git add .

git commit -m “新版本号“

git tag 新版本号

git push origin master —tags

要更新私有库,我们拿PayComponents这个项目来说,执行下面的指令

//私有库升级
pod repo push PayComponents  PayComponents.podspec

这个PayComponents就是我们pod repo add时候起得名字,后面是.podspec文件,这操作等于把我们的私有库更新推到我们本地的库里面。 注意.podspec里面的版本号要记得更新,与tag一致。

那这种私有库我们项目的其他成员,还是拿PayComponents这个来说,首先在代码管理库上面得给他们下载代码的权限,然后执行下面:

//待核实~ 
pod repo add PayComponents https://gitee.com/LittleBin/PayComponents.git

公有库

补充一点,那如果想做成公有库,让大家都可以使用要怎么搞?

执行下面操作:

pod trunk push PayComponents.podspec

就可以把组件推到Cocoapods主仓库。别人就可以通过pod search来查找你的库了。

pod trunk push 可能失败,因为首次使用trunk需要注册自己的电脑。

pod trunk register [E-mail] [User Name]

执行完成之后,会受到一封验证邮件,按邮件提示完成验证即可。

全部都完成了之后pod search也可能会搜不到自己的库,这时候可以尝试把缓存删掉

使用命令:rm ~/Library/Caches/CocoaPods/search_index.json

清除后,再重新搜索,此时CocoaPod会重新创建搜索索引。

这只是一些可能的原因,具体的问题需要具体针对解决。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

群体智能

群体智能

James Kennedy、Russell C Eberhart、Yuhui Shi / 人民邮电出版社 / 2009-2-1 / 75.00元

群体智能是近年来发展迅速的人工智能学科领域.通过研究分散,自组织的动物群体和人类社会的智能行为, 学者们提出了许多迥异于传统思路的智能算法, 很好地解决了不少原来非常棘手的复杂工程问题.与蚁群算法齐名的粒子群优化(particle swarm optimization, 简称PSO)算法就是其中最受瞩目,应用最为广泛的成果之一. 本书由粒子群优化算法之父撰写,是该领域毋庸置疑的经典著作.作者......一起来看看 《群体智能》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具