内容简介:最近想了解一些组件化的知识,去看了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会重新创建搜索索引。
这只是一些可能的原因,具体的问题需要具体针对解决。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 组件化之路—集成组件SDK
- Android组件化入门:一步步搭建组件化架构
- Android快速开发框架,基础库,样式库,组件化,组件集成
- Android组件化方案及组件消息总线modular-event实战
- 组件化架构漫谈
- 前端面试之组件化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
REST in Practice
Jim Webber、Savas Parastatidis、Ian Robinson / O'Reilly Media / 2010-9-24 / USD 44.99
Why don't typical enterprise projects go as smoothly as projects you develop for the Web? Does the REST architectural style really present a viable alternative for building distributed systems and ent......一起来看看 《REST in Practice》 这本书的介绍吧!