脚本组件化

2018-07-03  本文已影响614人  莪的世界木有如果

第一步:创建一个主工程MainProject,然后在主工程里面有几个模块后者说是业务线;如下图中的A B ,主工程点击进去到A界面,A界面点击进入到B界面

第二步:开一个repo的私有源仓库,终端输入

pod repo add [私有仓库名][私有仓库git地址]

第三步:创建一个文件夹,比如叫projects,将主工程MainProject放到projects中,然后在projects文件夹下面,终端输入:

git clone git@github.com:wode0weiyi/ConfigPrivatePod.git 

clone完成后,将ConfigPrivatePod的template文件夹下Podfile中的第一个sources改为自己的私有仓库地址;

文件目录是这样的:

Project

├── ConfigPrivatePod

└── MainProject

第四步:创建私有的Pod工程和category工程

MainProject是一个非常简单的应用,一共就三个页面。首页push了AViewController,AViewController里又push了BViewController。我们可以理解成这个工程由三个业务组成:首页、A业务、B业务。

我们这一次组件化的实施目标就是把A业务组件化出来,首页和B业务都还放在主工程。

既然要把A业务抽出来作为组件,那么我们需要为此做两个私有Pod:A业务Pod(以后简称A Pod)、方便其他人调用A业务的CTMediator category的Pod(以后简称A_Category Pod)。这里多解释一句:A_Category Pod本质上只是一个方便方法,它对A Pod不存在任何依赖。

我们先创建A Pod

1.新建一个工程,命名为A,放在projects文件夹下面;在github或者其他第三方托管网站上面创建A的repo,新建好之后,网页不要关掉

Project

├── ConfigPrivatePod

├── MainProject

└── A

然后cd到ConfigPrivatePod下,执行./config.sh脚本来配置A这个私有Pod。脚本会问你要一些信息,Project Name就是A,要跟你的A工程的目录名一致。HTTPS Repo、SSH Repo网页上都有,Home Page URL就填你A Repo网页的URL就好了。

A

├── A

|   ├── A

|   │   ├── AViewController.h

|   │   └── AViewController.m

|   ├── AppDelegate.h

|   ├── AppDelegate.m

|   ├── ViewController.h

|   ├── ViewController.m

|   └── main.m

└── A.xcodeproj

我们再创建A_Category工程Pod

步骤和创建A工程pod是一个流程。然后去A_Category下,在Podfile中添加一行pod "CTMediator",在podspec文件的后面添加s.dependency "CTMediator",然后执行pod install

接下来打开A_Category.xcworkspace,把脚本生成的名为A_Category的空目录拖放到Xcode对应的位置下,然后在这里新建基于CTMediator的Category:CTMediator+A。最后你的A_Category工程应该是这样的:

A_Category

├── A_Category

|   ├── A_Category

|   │   ├── CTMediator+A.h

|   │   └── CTMediator+A.m

|   ├── AppDelegate.h

|   ├── AppDelegate.m

|   ├── ViewController.h

|   └── ViewController.m

└── A_Category.xcodeproj

主工程中引入A_Category,并让主工程编译通过

去主工程的Podfile下添加pod "A_Category", :path => "../A_Category"来本地引用A_Category。

然后编译一下,说找不到AViewController的头文件。此时我们把头文件引用改成#import 。

然后继续编译,说找不到AViewController这个类型。看一下这里是使用了AViewController的地方,于是我们在Development Pods下找到CTMediator+A.h,在里面添加一个方法:

- (UIViewController *)A_aViewController;

再去CTMediator+A.m中,补上这个方法的实现,把主工程中调用的语句作为注释放进去,将来写Target-Action要用:

-(UIViewController*)A_aViewController

{

 /*

        AViewController *viewController = [[AViewController alloc] init];

     */

 return[selfperformTarget:@"A"action:@"viewController"params:nilshouldCacheTarget:NO];

}

补充说明一下,performTarget:@"A"中给到的@"A"其实是Target对象的名字。一般来说,一个业务Pod只需要有一个Target就够了,但一个Target下可以有很多个Action。Action的名字也是可以随意命名的,只要到时候Target对象中能够给到对应的Action就可以了。

关于Target-Action我们会在第三步中去实现,现在不实现Target-Action是不影响主工程编译的。

category里面这么写就已经结束了,后面的实施过程中就不会再改动到它了。

然后我们把主工程调用AViewController的地方改为基于CTMediator Category的实现:

UIViewController*viewController=[[CTMediatorsharedInstance]A_aViewController];

 [self.navigationControllerpushViewController:viewControlleranimated:YES];

再编译一下,编译通过。

到此为止主工程就改完了,现在跑主工程点击这个按钮跳不到A页面是正常的,因为我们还没有在A工程中实现Target-Action。

而且此时主工程中关于A业务的改动就全部结束了,后面的组件化实施过程中,就不会再有针对A业务线对主工程的改动了。

添加Target_Action,并让A工程编译通过

我们在A工程中创建一个文件夹:Targets,然后看到A_Category里面有performTarget:@"A",所以我们新建一个对象,叫做Target_A。A工程目录是这个样的

然后又看到对应的Action是viewController,于是在Target_A中新建一个方法:Action_viewController。这个Target对象是这样的:

这里写实现文件的时候,对照着之前在A_Category里面的注释去写就可以了。

因为Target对象处于A的命名域中,所以Target对象中可以随意import A业务线中的任何头文件。

另外补充一点,Target对象的Action设计出来也不是仅仅用于返回ViewController实例的,它可以用来执行各种属于业务线本身的任务。例如上传文件,转码等等各种任务其实都可以作为一个Action来给外部调用,Action完成这些任务的时候,业务逻辑是可以写在Action方法里面的。

换个角度说就是:Action具备调度业务线提供的任何对象和方法来完成自己的任务的能力。它的本质就是对外业务的一层服务化封装。

现在我们这个Action要完成的任务只是实例化一个ViewController并返回出去而已,根据上面的描述,Action可以完成的任务其实可以更加复杂。

然后我们再继续编译A工程,发现找不到BViewController。由于我们这次组件化实施的目的仅仅是将A业务线抽出来,BViewController是属于B业务线的,所以我们没必要把B业务也从主工程里面抽出来。但为了能够让A工程编译通过,我们需要提供一个B_Category来使得A工程可以调度到B,同时也能够编译通过。

B_Category的创建步骤跟A_Category是一样的,不外乎就是这几步:新建Xcode工程、网页新建Repo、跑脚本配置Repo、添加Category代码。

B_Category添加好后,我们同样在A工程的Podfile中本地指过去,然后跟在主工程的时候一样。

后续操作和在主工程引入A_Category时候一样,修改代码,创建B业务的target_Action

最后:

我们创建了三个pod,分别为A 、A_Category、B_Category

接下来就是给这个三个pod发版。

终端cd到各个工程的项目下,然后执行./upload.sh脚本文件,就可以了!如果提示错误,不知道怎么去解决的时候,下面给出分布的发布指令:

git add . 

git commit -m '版本号'  //说明:这个版本号必须和你podSpec文件里面的version一致,脚本生成让输入的versionNum也是一样的

git tag 版本号

git push origin master --tags

pod lib lint 项目名称.podspec --use-libraries//说明:这个是验证podspec文件的正确性


如果是用上述方法创建的pod和执行./config.sh脚本就不需要执行:

cd ~/.cocoapods/repos/[你的私有仓库名字]

git pull origin master//这里经常会提示already up to date,如果是先创建pod的,就可以不用理会

cd -

pod repo push [你的私有源名称] [podspec文件名].podspec --verbose --allow-warnings --use-libraries 


最后提示build success就说明成功了。

这个时候在主工程的Podfile文件中,先引入两个sources

source '你的私有仓库git地址'

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

然后将之前引入的本地的path去掉,最后就是

pod 'A'

pod 'A_Category'

上一篇下一篇

猜你喜欢

热点阅读